【问题标题】:setInterval and setTimeout speed changessetInterval 和 setTimeout 速度变化
【发布时间】:2012-12-08 12:54:05
【问题描述】:

我的问题出在一些 JavaScript 中:

            var mijnfunctie = function(){

    //balk 1 2 3

    setTimeout(function(){
        $("#balk1").animate({"margin-left": "0px"}, 400);
        $("#balk2").animate({"margin-left": "0px"}, 400);
        $("#balk3").animate({"margin-left": "0px"}, 400);
    });
    setTimeout(function(){
        $("#balk1").animate({"margin-left": "-2000px"}, 400);
        $("#balk2").animate({"margin-left": "4000px"}, 400);
        $("#balk3").animate({"margin-left": "-5000px"}, 400);
    }, 2000);

    //balk 4 5 6

    setTimeout(function(){
        $("#balk4").animate({"margin-left": "0"}, 400);
        $("#balk5").animate({"margin-left": "0"}, 400);
        $("#balk6").animate({"margin-left": "0"}, 400);
    }, 3000);

    setTimeout(function(){
        $("#balk4").animate({"margin-left": "2000px"}, 400);
        $("#balk5").animate({"margin-left": "-4000px"}, 400);
        $("#balk6").animate({"margin-left": "5000px"}, 400);
    }, 5000);


    setInterval(mijnfunctie, 6000);
};

mijnfunctie();

这是为滑块制作的,效果很好。六次,第六次之后就开始混了。所以在某个地方时间不对,但是在哪里呢?

【问题讨论】:

  • 第一个缺少时间参数。
  • 您能否说明您的更多工作代码,以便任何人都可以了解流程的进展情况?
  • @JanDvorak - 如果我们不提供参数,代码仍然可以正常工作,但是这部分函数将立即执行,而不是基于时间

标签: javascript function slider settimeout setinterval


【解决方案1】:

setIntervalrepeated 函数排入队列。由于您在排队的函数结束时执行此操作,因此十二秒后,它将运行两次。每再过六秒,它们的数量就会翻倍。慢慢地,这将使浏览器屈服。您将在一分钟内设置 500 个计时器,第二分钟设置 500 000 个计时器...

要么将 setInterval 移到要重复的函数之外,要么(更好地)将其更改为 setTimeout(这将只排队一次调用)。

function mijnfunctie(){
   ...
   setTimeout(mijnfunctie, 6000);
}

其次,您对setTimeout 的第一次调用缺少其参数。无论默认值是什么,您都应该始终指定它。


第三,如果任何动画延迟几秒钟,那么后续动画将立即运行。为了防止这种情况,您可能希望链接动画而不是依赖正确的时间。在这种情况下,为了防止金字塔效应(极端缩进),我建议这种形式:

function phase1(){
  $(...).animate(..., phase2);
}

function phase2(){
  ...

...

function phaseN(){
  $(...).animate(..., phase1);
}

【讨论】:

  • 感谢您所做的一切。当我简单地将我的 setInterval 更改为 setTimeout 时,它工作得很好!我从你们那里得到了一些很好的反馈。再次感谢!
  • @GerritMulder 您可能希望接受这个答案。请注意答案旁边的空复选标记。
【解决方案2】:

您不能依赖setTimeout 中的延迟,该值仅表示函数的最小延迟。相反,您应该链接这些函数。

var mijnfunctie = function(){
    setTimeout(function(){
        $("#balk1").animate({"margin-left": "0px"}, 400);
        $("#balk2").animate({"margin-left": "0px"}, 400);
        $("#balk3").animate({"margin-left": "0px"}, 400, function () {
            setTimeout(function () {
                $("#balk1").animate({"margin-left": "-2000px"}, 400);
                $("#balk2").animate({"margin-left": "4000px"}, 400);
                $("#balk3").animate({"margin-left": "-5000px"}, 400, function () {
                    setTimeout(function () {
                        $("#balk4").animate({"margin-left": "0"}, 400);
                        $("#balk5").animate({"margin-left": "0"}, 400);
                        $("#balk6").animate({"margin-left": "0"}, 400, function () {
                            setTimeout(function () {
                                $("#balk4").animate({"margin-left": "2000px"}, 400);
                                $("#balk5").animate({"margin-left": "-4000px"}, 400);
                                $("#balk6").animate({"margin-left": "5000px"}, 400, function () {
                                    setTimeout(mijnfunctie, 600);
                                });
                            }, 1600);
                        });
                    }, 600);
                });
            }, 1600);
        });
    }, 0);
};
mijnfunctie();

无论如何我宁愿建议这样的东西:)

(function () {
    var objects = new Array(6),
        index = 0,
        steps = [
            [[0,'0px'],[1, '0px'],[2, '0px']],
            1600,
            [[0,'-2000px'],[1,'4000px'],[2,'-5000px']],
            600,
            [[3,'0px'],[4,'0px'],[5,'0px']],
            1600,
            [[3,'2000px', '-400px', '5000px']],
            600
        ],
        i = 6,
        crawler;

    while(i--) { objects[i] = $('#balk'+(i + 1)); };

    crawler = function () {
        var step, k;
        if (index >= steps.length) index = 0;
        step = steps[index];
        ++index;
        if (typeof(step) == 'number') {
            setTimeout(step, crawler);
        } else {
            k = step.length - 1;
            while(k--) {
                objects[k[0]].animate({'margin-left': step[k[1]]}, 400, (k ? null : crawler)});
            }
        }
    };
    crawler();
}());

或更通用和可重用的东西

【讨论】:

  • 它可以写得更好,我只是改变了OP写的内容。我也没有注意到你做了什么 - setIterval。
  • 考虑我的金字塔效应替代方案。你怎么看?
  • 我宁愿将所有更改打包到某个数组中并生成将爬过该数组的函数(因为所有函数都是相同的)
  • 代码应该被重写成通用形式以适应任意数量的障碍,这样你就不会有回调金字塔了。
  • @lupatus 我实际上(在这个问题之前)正在考虑以do(f1).then(f2).then(f3) ... .end() 的形式编写一个框架,其中 f1...fn 将采用selfnext 作为它们的参数。跨度>
【解决方案3】:

Gerrit 您在同一个函数中使用 setInterval(mijnfunctie, 6000); 函数,这就是它循环自身并多次调用 setInterval(mijnfunctie, 6000); 函数的原因..

因此建议只调用一次setInterval(mijnfunctie, 6000); 函数(调用第一次的地方)。

享受..!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    相关资源
    最近更新 更多