使用递归而不是EVAL

时间:2009-11-17 16:43:52

标签: javascript jquery recursion eval

我有一个页面中的项目列表,必须按顺序隐藏,但在上一个项目完全隐藏之后。

我制作了以下代码,我创建了一个大字符串,在前面的回调中插入回调,然后使用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 + ")()");

关于如何使用递归实现此效果的任何建议,没有“邪恶”评估?

2 个答案:

答案 0 :(得分:7)

隐藏递归 - 功能样式

在这种情况下,您知道效果的持续时间,因此您可以按照其他人的建议进行操作。

但是,您可能仍然想知道如何使用更加实用的样式,使用简单的递归来实现相同的效果。

所以我在这里告诉你一种方法。

1。代码

<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>

2。它是如何工作的?

我们首先从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);
}