循环执行setTimeout

5

我目前正在努力理解一些JavaScript。

我想要的是在屏幕上打印出一段文本,然后按照给定的数字进行计数,如下所示:

"测试"

[1秒暂停]

"1"

[1秒暂停]

"2"

[1秒暂停]

"3"

这是我的JS代码:

$(document).ready(function() {

    var initMessage = "Test";
    var numberCount = 4;    

function count(){

    writeNumber = $("#target");

    setTimeout(function(){
        writeNumber.html(initMessage);
    },1000);

        for (var i=1; i < numberCount; i++) {

    setTimeout(function(){
        writeNumber.html(i.toString());
    },1000+1000*i)};

};

 count();

});

这是我的标记语言:
<span id="target"></span>

当我渲染页面时,我只得到了“Test”后面跟着“4”的内容。我不是JavaScript的专家,所以解决方案可能相当简单。非常感谢您提供有关问题所在的任何提示。您可以在此处尝试我的示例:http://jsfiddle.net/JSe3H/1/
3个回答

6
您遇到了变量作用域问题。循环内的计数器(i)只在count函数中定义。循环执行完毕时,i的值为4。这会影响每个setTimeout函数,这就是为什么您只看到“4”的原因。
我会这样重写它:
function createTimer(number, writeNumber) {
    setTimeout(function() {
        writeNumber.html(number.toString());
    }, 1000 + 1000 * number)
}

function count(initMessage, numberCount) {
    var writeNumber = $("#target");

    setTimeout(function() {
        writeNumber.html(initMessage);
    }, 1000);

    for (var i = 1; i < numberCount; i++) {
        createTimer(i, writeNumber);
    }
}

$(document).ready(function() {

    var initMessage = "Test";
    var numberCount = 4;


    count(initMessage, numberCount);

});
createTimer函数确保循环内的变量被"捕获"到createTimer提供的新作用域中。 更新后的示例:http://jsfiddle.net/3wZEG/ 还请查看以下相关问题:

1
也许你想将 writeNumber 声明为一个隐式全局变量,因为它目前是隐式全局的。 - pimvdb

3
在你的例子中,你说:“分别在2、3、4和5秒后写入 i 的值”。在第一次两秒钟之前,你的for循环已经完成了所有迭代,并将 i 的值设为4。
你需要创建一个闭包来保存你尝试写入的值。像这样:
for(var i = 1; i < numberCount; i++) {
    setTimeout((function(x) {
        return function() {
            writeNumber.html(x.toString());
        }
    })(i),1000+1000*i)};
}

完全不同的另一种方法可能是这样的:
var i = 0;
var numberCount = 4;

// repeat this every 1000 ms
var counter = window.setInterval(function() {

   writeNumber.html( (++i).toString() );

   // when i = 4, stop repeating
   if(i == numberCount)
       window.clearInterval(counter);

}, 1000);

1
希望这可以帮到你:
var c=0;
var t;
var timer_is_on=0;
function timedCount() { document.getElementById('target').value=c; c=c+1; t=setTimeout("timedCount()",1000); }
function doTimer() { if (!timer_is_on) { timer_is_on=1; timedCount(); } }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接