jQuery - 使用嵌套的setTimeout暂停循环

时间:2014-11-09 13:45:07

标签: javascript jquery for-loop settimeout

我正在尝试使用Timeout暂停一个for循环,这将为一些元素设置动画。我想让一些按钮一个接一个地展开。

目前我有两个问题。第一个是方程(j)似乎有一个比它应该更大的元素索引1。另一个是跳到最后一个动画。

 for (j = 0; j<=numberOfButtons; j++){
    setTimeout(function() { 
         $buttons.eq(j).animate({
            height: buttonBig,
            width: buttonBig
        },150, 'linear');
    }, 3000 * (j + 1)); 
 }

这是我第一次使用stackoverflow,所以如果我正确地发布这个问题,请告诉我。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

使用临时范围。您正在调用异步函数setTimeout ...

在您的代码中,您使用settimeOut()函数调度事件。当代码运行时,一次迭代在调用settimeOut()函数后不会等待。它只是为j = 0到j&lt; = numberOfButtons调度所有setTimeout事件。然后js继续执行循环下面的其余代码,直到发生超时事件......

发生超时事件时,会调度所有超时事件,并且j的值等于numberoOfButtons ......

现在javascript中使用的另一个概念开始行动了。这个概念被称为&#34;范围&#34;。函数的范围可以定义为函数可以访问的变量(不是非常准确的定义)。在javascript中,函数的范围也包括它的父函数的变量(不仅是父母,祖父母的变量等等)......

在您的代码中,当发生超时事件时,将调用回调函数。执行回调时,每个回调引用的j的值不是您所想的那样。 j的值等于父函数中的numberOfButtons。因此,所有回调都会在执行回调时引用该值,从而导致意外行为。

我做的是我添加了另一个输入参数为j的函数,并调用它。在循环的每次迭代中调用此函数,将j设置为新值。现在,当执行回调时,父函数不是具有for循环的函数。父函数是我添加的匿名函数。匿名函数的j值对于每个函数是本地的并且是不同的。因此,当执行回调时,它们引用它们应该引用的j值。这就是它给出预期行为的原因。

for (j = 0; j<=numberOfButtons; j++){
    (function(j){
       setTimeout(function() { 
         $buttons.eq(j).animate({
            height: buttonBig,
            width: buttonBig
        },150, 'linear');
      }, 3000 * (j + 1)); 
   })(j); 
 }