我有一个页面中的项目列表,必须按顺序隐藏,但在上一个项目完全隐藏之后。
我制作了以下代码,我创建了一个大字符串,在前面的回调中插入回调,然后使用eval执行效果,但尽管代码工作正常,但我完全相信这不是最好的这样做的方法。
// get items to hide
var itemsToHide = jQuery(".hide");
// function responsible to hide the item
var hideItem = function (item, callback) {
jQuery(item).hide(100, callback)
};
// declare an empty function, to be the first to be called
var buff = function(){};
for (var i = 0; i < itemsToHide.length; i++) {
// put the previous value of buff in the callback and assign this to buff
buff = "function(){hideItem(itemsToHide[" + i + "], " + buff + ");}";
}
// execute the effects
eval("(" + buff + ")()");
关于如何使用递归实现此效果的任何建议,没有“邪恶”评估?
答案 0 :(得分:7)
在这种情况下,您知道效果的持续时间,因此您可以按照其他人的建议进行操作。
但是,您可能仍然想知道如何使用更加实用的样式,使用简单的递归来实现相同的效果。
所以我在这里告诉你一种方法。
<script src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script type="text/javascript">
$(function() {
var items = jQuery(".to-hide");
(function hideRec() {
if (items.length == 0) {
window.alert("The end.");
return;
}
var toHide = jQuery(items[0]);
items = items.slice(1);
toHide.hide("100", hideRec);
})();
});
<script>
<ul>
<li class="to-hide">...</li>
<li class="to-hide">...</li>
<li class="to-hide">...</li>
<li class="to-hide">...</li>
<li class="to-hide">...</li>
<ul>
我们首先从jQuery获取一个包含我们想要的对象to-hide
的数组。
然后我们创建一个名为anonymous function 的,它将在定义后立即执行 - 它是(function() { ... })();
模式。即使它是一个匿名函数,我们也给它一个名字,以便我们能够轻松地递归调用它。
请注意,您可以在不给匿名函数命名的情况下实现相同的功能 - 如果您不了解JavaScript如何处理范围,这可能听起来有点奇怪 - 使用更加模糊的版本:
(function() { // Anonymous function without a name
if (items.length == 0) {
window.alert("The end.");
return;
}
var toHide = jQuery(items[0]);
items = items.slice(1);
toHide.hide("100", arguments.callee); // Recursive call to anonymous function
})();
这次我们使用arguments.callee
表示函数本身的事实 - 所以不需要给匿名函数命名。
整个魔法都在这个递归匿名函数中 - 这是一个闭包。
hideRec
匿名函数捕获items
数组。在检查内部还有内容之后,它将删除第一个元素并将其存储在本地toHide
变量中(使用jQuery正确包装)。
最后,它使用jQuery隐藏元素,并将此匿名函数作为回调传递 - 一旦完成效果,jQuery将再次调用它。
我希望这很清楚。
祝你好运!答案 1 :(得分:3)
由于您知道每个隐藏的毫秒数,因此您根本不需要使用回调:
jQuery(".hide").each(function(i)
{
var obj = $(this);
setTimeout(function() { obj.hide(100); }, i * 100);
}