为什么这个关闭不能像我期望的那样工作?

时间:2014-11-18 16:31:44

标签: javascript jquery closures

我有以下html和javascript(jQuery):

<div class="container-a">
    <div class="element">...</div>
    <div class="element">...</div>
    ...
</div>
<div class="container-b">
    <div class="element">...</div>
    <div class="element">...</div>
    ...
</div>

<script>
    function cycle($container) {
        setInterval(function() {
            $active = $container.find(':last-child')
            $next = $active.prev();
            $next.css({opacity:0});
            $next.insertAfter($active);
            $next.animate({opacity: 1}, 500, function() {
                $active.insertBefore($container.find(':first-child'));
            });
        }, 3500);
    }

    $(function() {
         cycle($('.container-a'));
         cycle($('.container-b'));
    })
</script>

当我在.container-a或.container-b中的一个或另一个上运行循环(..)时,一切正常(通过将最后一个元素移动到下一个元素的开头,元素在一个接一个地逐渐淡化不透明度过渡后的容器)。但是,当我按上述方式运行循环时,容器-a中的元素不能正常转换。

我知道这是因为一个闭包问题,因为当我单步执行代码时,有时会运行动画完成函数,而$ container是.container-a但$ active.parent()和$ next.parent ()是.container-b。我无法弄清楚为什么会出现这种情况以及如何解决它。

2 个答案:

答案 0 :(得分:2)

您没有对任何变量声明使用var,因此它们都是隐式全局变量。您没有使用闭包的变量范围行为,因为您的所有函数都没有局部变量。

相反,您必须使用var

var $active = $container.find(':last-child')
var $next = $active.prev();

严格模式不允许隐式全局变量。如果您将"use strict";添加到setInterval回调的顶部(或整个文件的顶部),您会看到$active未定义的错误。

另见What is the purpose of the var keyword and when to use it (or omit it)?

答案 1 :(得分:1)

$ next是一个全局变量。添加&#34; var&#34;到这一行的开头:

$next = $active.prev();