0

我有一个具有一系列延迟功能的功能:

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);

用一个简单<div>Hello</div>的HTML。这样,问候语每 500 毫秒更改一次语言。

函数完成后(大约需要 2 秒;2000 毫秒)我想重新启动函数并无限循环它。所以,我尝试了通常的方法:

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

如果您注意到,一旦它循环两次,它就会在“Hello”处停止。为什么是这样?这是一个显示我的问题的小提琴http://jsfiddle.net/rgX6B/2/

任何帮助将非常感激!

编辑:

为了提出问题,我实际上简化了我的问题。我不想贴一大堵代码(内部html的更改实际上是涉及更改CSS形状位置的复杂函数。)我的问题最终通过将函数放在setTimeout 内部解决了。谢谢大家的答案!

4

3 回答 3

2

“如果你注意到,一旦它循环了两次,它就会在“Hello”处停止。这是为什么?

setTimeout()方法将一个函数排队等待在给定的延迟后执行一次,因此如果您希望它继续重复,则需要从函数内部调用它 - 或改用它setInterval()

但是,您误用了该.delay()方法,该方法实际上旨在与其他 jQuery 动画方法一起使用。setTimeout()是您应该使用的功能中的所有延迟。我可能会更像这样实现你的功能:

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"]);

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

您也许可以添加另一个参数来指示要设置的元素.html(),而不是在函数中硬编码...

于 2013-10-28T21:12:41.973 回答
2

你只需要在你的函数中使用它

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);

另一种解决方案是使用setInterval(function() { greet(..) }, 3000);

于 2013-10-28T21:07:24.050 回答
2

你的算法看起来有点乱,而且违反了 DRY,使它更难维护。这是一个替代方案:

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);
于 2013-10-28T21:09:44.540 回答