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

lem*_*dge 2 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)); 
 }
Run Code Online (Sandbox Code Playgroud)

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

感谢您的帮助.

Sam*_*age 5

使用临时范围.你正在调用一个异步函数setTimeout ...

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

当超时事件发生时,所有超时事件都被调度,j的值等于numberoOfButtons ...

现在javascript中使用的另一个概念开始行动了.这个概念被称为"范围".函数的范围可以定义为函数可以访问的变量(不是非常准确的定义).在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); 
 }
Run Code Online (Sandbox Code Playgroud)