【问题标题】:Change nested setTimeout functions to efficient loop将嵌套的 setTimeout 函数更改为高效循环
【发布时间】:2013-10-15 00:13:47
【问题描述】:

我有一个学生列表 - 每个学生都是具有特定班级和 ID 的 DIV。

我还有一组学生 ID,我已经随机化了。

我想做的是:

  1. 随机选择一个学生
  2. 用紫色突出显示相关的 DIV(pulse 类)
  3. 短暂的停顿(如 0.2 秒)
  4. 随机选择另一个学生
  5. 冲洗并重复 1-3 共 10 次
  6. 以不同的颜色突出显示所选学生(selected 班级)

下面的代码可以正常工作...

                setTimeout(function() {
                    $("#" + arr[1]).addClass('pulse');
                    setTimeout(function() {
                        $("#" + arr[1]).removeClass('pulse');

                        setTimeout(function() {
                            $("#" + arr[2]).addClass('pulse');
                            setTimeout(function() {
                                $("#" + arr[2]).removeClass('pulse');

                                    setTimeout(function() {
                                        $("#" + arr[3]).addClass('pulse');
                                        setTimeout(function() {
                                            $("#" + arr[3]).removeClass('pulse');

                                            setTimeout(function() {
                                                $("#" + arr[4]).addClass('pulse');
                                                setTimeout(function() {
                                                    $("#" + arr[4]).removeClass('pulse');

                                                    setTimeout(function() {
                                                        $("#" + arr[5]).addClass('pulse');
                                                        setTimeout(function() {
                                                            $("#" + arr[5]).removeClass('pulse');

                                                            setTimeout(function() {
                                                                $("#" + arr[6]).addClass('pulse');
                                                                setTimeout(function() {
                                                                    $("#" + arr[6]).removeClass('pulse');

                                                                    setTimeout(function() {
                                                                        $("#" + arr[7]).addClass('pulse');
                                                                        setTimeout(function() {
                                                                            $("#" + arr[7]).removeClass('pulse');

                                                                            setTimeout(function() {
                                                                                $("#" + arr[8]).addClass('pulse');
                                                                                setTimeout(function() {
                                                                                    $("#" + arr[8]).removeClass('pulse');

                                                                                    setTimeout(function() {
                                                                                        $("#" + arr[9]).addClass('pulse');
                                                                                        setTimeout(function() {
                                                                                            $("#" + arr[9]).removeClass('pulse');

                                                                                            setTimeout(function() {
                                                                                                $("#" + arr[10]).addClass('pulse');
                                                                                                setTimeout(function() {
                                                                                                    $("#" + arr[10]).removeClass('pulse');
                                                                                                    $("#" + arr[0]).addClass('activeClass');
                                                                                                    Dojo.disableButtons(false);
                                                                                                }, 250);
                                                                                            }, 250);

                                                                                        }, 250);
                                                                                    }, 250);

                                                                                }, 250);
                                                                            }, 250);

                                                                        }, 250);
                                                                    }, 250);

                                                                }, 250);
                                                            }, 250);

                                                        }, 250);
                                                    }, 250);

                                                }, 250);
                                            }, 250);

                                        }, 250);
                                    }, 250);

                            }, 250);
                        }, 250);

                    }, 250);
                }, 250);

但是实在是太丑了。

有没有更有效的方法使用 for 循环来做到这一点?

提前致谢,

【问题讨论】:

  • 是否可以选择使用 jQuery?
  • @YuriyGalanter 他已经在使用 jQuery!
  • 是的,我们需要使用 jQuery。
  • @JamesBall 你可以尝试使用.toggleClass().delay() 之类的东西来使过渡更简洁吗?

标签: javascript jquery


【解决方案1】:

您可以使用一个函数(显然,将其重命名为更有意义的名称):

function lessMessy(index) {
    $("#" + arr[index]).addClass('pulse');
    if (index === 10) {
        $("#" + arr[0]).addClass('activeClass');
        Dojo.disableButtons(false);
    } else {
        setTimeout(function() {
            $("#" + arr[index]).removeClass('pulse');
            lessMessy(index + 1)
        }, 250)
    }
}

lessMessy(1)

编辑:请注意,这比setInterval 更好,因为它会总是等待四分之一秒。如果里面的代码花费的时间超过 1/4 秒,那么setInterval 将跳过该迭代。这将导致页面损坏,因为 pulse 类不会从前一个元素中删除。

【讨论】:

  • 这很接近,但它从未将类添加到任何元素。
  • 将此行添加到代码块的末尾将使其等效:setTimeout(function() {lessMessy(1);}, 250);
  • @devnull69 我以为这很明显,但没关系
【解决方案2】:

我认为setInterval 功能是您所需要的。
这将执行另一个函数,直到您调用 clearInterval
[编辑]
这是一个想法:

var arr = YOUR ARRAY HERE;
var index = 0;
var t = setInterval(function(){
    if (index > 0){
       $('#' + arr[index - 1]).removeClass('pulse'); //remove class from previous
    }
    if (index < 10){
       $('#' + arr[index]).addClass('pulse'); //add class to current element
    }
    else { 
      clearInterval(t);//stop everything
    }
    index ++;
}, 250)

这可能行不通。这是我的头上,但它应该给你和想法。

【讨论】:

  • 嗨@Marius 我认为这是正确的。你有任何可行的例子吗?
  • 谢谢@Marius。完美运行。在最后一行的第 4 行只有 1 个错字。 clearInderval.
  • @JamesBall。哈!..很高兴听到它。我修正了错字。
  • @JamesBall 请注意,如果内部代码花费的时间过长,此解决方案将破坏您的页面。 (有关更多信息,请参阅我对答案的编辑)
【解决方案3】:

带有回调的稍微冗长/通用的方法:

var pulseStudent = function( student, callback ){
  student = $('#' + student);
  student.addClass('pulse');
  setTimeout(function(){student.removeClass('pulse');}, 250);
  setTimeout(callback, 500);
};

var pulseStudents = function( students, callback ){
  var student = students.pop();
  if ( student ) {
    pulseStudent( student, function(){
      pulseStudents( students, callback );
    });
  }
  else {
    callback();
  }
};

pulseStudents( arr.slice(0), function(){
  $("#" + arr[0]).addClass('activeClass');
  Dojo.disableButtons(false);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2017-08-22
    • 2021-10-23
    • 2021-09-16
    相关资源
    最近更新 更多