【问题标题】:Why is this closure not working as I expect it to?为什么这个关闭没有像我预期的那样工作?
【发布时间】:2014-11-18 16:31:43
【问题描述】:

我有以下 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 中的一个或另一个上运行 cycle(..) 时,一切正常(通过将最后一个元素移动到不透明过渡后的容器)。但是,当我如上所述在两者上运行循环时,容器-a 中的元素无法正确转换。

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

【问题讨论】:

  • 您应该在闭包内的变量声明之前使用“var”,这样可以保持它们的私密性

标签: javascript jquery closures


【解决方案1】:

您的任何变量声明都没有使用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)?

【讨论】:

    【解决方案2】:

    $next 是一个全局变量。在此行的开头添加“var”:

    $next = $active.prev();
    

    【讨论】:

      猜你喜欢
      • 2021-09-07
      • 1970-01-01
      • 2023-04-10
      • 2017-04-17
      • 1970-01-01
      • 2011-07-04
      • 2015-09-16
      • 1970-01-01
      • 2016-06-19
      相关资源
      最近更新 更多