为什么这个关闭没有像我预期的那样工作

Why is this closure not working as I expect it to?

本文关键字:工作 为什么      更新时间:2023-09-26

我有以下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用于任何变量声明,因此它们都是隐式全局变量。您没有使用闭包的变量范围行为,因为您的函数都没有局部变量。

相反,您必须使用 var

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

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

参见 var 关键字的目的是什么以及何时使用它(或省略它)?

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

$next = $active.prev();