简体   繁体   English

jQuery如何在一系列延迟之后循环一个函数

[英]jQuery how to loop a function after a series of delay

I have a function which has a series of several delayed functions: 我有一个函数,其中包含一系列延迟函数:

function greet(t) {
    $("div").delay(t*2).queue(function(n) {
         $(this).html("Bonjour");
        n();
    });

    $("div").delay(t*3).queue(function(n) {
         $(this).html("Hola");
        n();
    });

    $("div").delay(t*4).queue(function(n) {
         $(this).html("Hallo");
        n();
    });

    $("div").delay(t*5).queue(function(n) {
        $(this).html("Hello"); // back to original
        n();
    });
}

greet(500);

With a simple <div>Hello</div> in HTML. 用HTML中的简单<div>Hello</div> This way, the greeting changes language every 500ms. 这样,问候语每500毫秒更改一次语言。

After the function completes (which takes about 2 seconds; 2000ms) I want to start the function over and have loop it infinitely. 函数完成后(大约需要2秒钟; 2000毫秒),我想重新启动函数并无限循环。 So, I tried the usual: 因此,我尝试了通常的方法:

    setTimeout(function() {
       greet(500);
    }, 2500); // after 2500ms, repeat the function

If you notice, once it loops through twice, it stops at "Hello". 如果您注意到,一旦循环两次,它将在“ Hello”停止。 Why is this? 为什么是这样? Here is a fiddle displaying my problem http://jsfiddle.net/rgX6B/2/ 这是显示我的问题的小提琴http://jsfiddle.net/rgX6B/2/

Any help would be much appreciated! 任何帮助将非常感激!

Edit: 编辑:

I actually simplified my problem for the sake of asking a question. 我实际上是为了提出问题而简化了我的问题。 I didn't want to post a big wall of code (the changing of the inner html are actually complex functions that involve changing the positioning of CSS shapes.) My problem was ultimately solved by putting the setTimeout inside the function. 我不想张贴大量的代码(更改内部html实际上是涉及更改CSS形状位置的复杂函数。)我的问题最终通过将setTimeout 放入函数中得以解决。 Thank you all for your answers! 谢谢大家的答案!

You just have to use it in your function 您只需要在功能中使用它

http://jsfiddle.net/kelunik/rgX6B/4/ http://jsfiddle.net/kelunik/rgX6B/4/

function greet(t) {
    $("div").delay(t*1).queue(function(n) {
         $(this).html("Bonjour");
        n();
    });

    $("div").delay(t*2).queue(function(n) {
         $(this).html("Hola");
        n();
    });

    $("div").delay(t*3).queue(function(n) {
         $(this).html("Hallo");
        n();
    });

    $("div").delay(t*4).queue(function(n) {
        $(this).html("Hello"); // back to original
        n();
    });

    setTimeout(function() {
       greet(500);
    }, 500);
}

greet(500);

another solution would be to use setInterval(function() { greet(..) }, 3000); 另一个解决方案是使用setInterval(function() { greet(..) }, 3000);

Your algorithm seems a bit messy, and violates DRY, making it more difficult to maintain. 您的算法似乎有些混乱,并且违反了DRY,因此难以维护。 Here's an alternative: 这是一个替代方案:

http://jsfiddle.net/LLQXj/ http://jsfiddle.net/LLQXj/

var greetings = [
    "Hello",
    "Bonjour",
    "Hola",
    "Hallo"
];

function greet(idx) {
    $('div').html(greetings[idx]);
    var next = (idx + 1) > (greetings.length - 1) ? 0 : idx + 1;
    setTimeout(function() { greet(next); }, 1000);
}

greet(0);

"If you notice, once it loops through twice, it stops at "Hello". Why is this?" “如果您注意到,一旦循环两次,它将在“ Hello”处停止。为什么会这样?”

The setTimeout() method queues up a function to be executed once after a given delay, so you would need to call it from inside your function if you want it to keep repeating - or use setInterval() instead. setTimeout()方法将一个函数排队等待给定延迟后执行一次 ,因此,如果您希望函数继续重复,则需要从函数内部调用它-或使用setInterval()代替。

However, you are misusing the .delay() method, which is really intended to be used with other jQuery animation methods . 但是,您滥用了.delay()方法,该方法实际上打算与其他jQuery动画方法一起使用 setTimeout() is what you should be using for all of the delays in your function. setTimeout()是您应使用的所有函数延迟。 I'd probably implement your function more like this: 我可能会更像这样实现您的功能:

function greet(delay, messages, nextMessage) {
    if (nextMessage === undefined) nextMessage = 0;
    $("div").html(messages[nextMessage]);
    setTimeout(function() {
        greet(delay, messages, (nextMessage + 1) % messages.length);
    }, delay);
}

greet(500, ["Hello","Hola","Hallo"]);

Demo: http://jsfiddle.net/rgX6B/5/ 演示: http//jsfiddle.net/rgX6B/5/

You could perhaps add another parameter to indicate which element(s) to set the .html() for, rather than hardcoding that in the function... 您也许可以添加另一个参数来指示要设置.html()元素,而不是在函数中对其进行硬编码...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM