4

我有这个 Javascript 代码,它按预期工作:

<div class="test"></div>

<script>
setTimeout(function(){$(".test").append("test1")},1000);
setTimeout(function(){$(".test").append("test2")},2000);
</script>
<script src="js/jquery.min.js"></script>

它首先显示“test1”,然后在一秒钟后显示“test2”,例如:“test1test2”,这就是我想要的。

当我尝试在 FOR 循环中执行此操作时,如下所示:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++ ) {
    setTimeout(function(){$(".test").append("test" + i)},timeInterval);
    timeInterval += 1000;
}

然后我先得到“test2”,然后一秒钟后得到“test2”,例如:“test2test2”,这不是我想要的。

事实上,如果 l = 3,那么我得到“test3test3test3”而不是“test1test2test3”。有谁知道如何解决这个问题?

4

5 回答 5

5

vari在执行函数时递增到 2 setTimeout,因此它只是将i值打印为 2,从而导致test2test2.

您应该使用闭包来使用iprint的实例test1test

演示:http: //jsfiddle.net/mBBJn/1/

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++) {
    (function(i) {
        setTimeout(function() {
            $(".test").append("test" + (i+1))
        }, timeInterval);
        timeInterval += 1000;
    })(i);
}

编辑:使用函数参数。

于 2012-10-25T21:52:02.957 回答
3

for 循环不会创建新范围,您可以使用另一个函数来执行此操作:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++) {
    setTimeout((function(i) {
        return function() {
            $(".test").append("test" + i);
        }
    })(i), timeInterval);
    timeInterval += 1000;
}
于 2012-10-25T21:50:47.903 回答
2

在这种情况下,变量i将始终引用的当前值i(而不是i调用时的值)。

这就是作用域在 JavaScript 中的工作方式。

请参阅@Esailija 的答案以获取解决方案。

于 2012-10-25T21:51:01.447 回答
0

这是因为您没有i从 for 循环中捕获 的值。您可以将代码调整为此以使其工作:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++ ) {
    (function(i2, timeInterval2) {
        setTimeout(function() {
            $(".test").append("test" + i2);
        }, timeInterval2);
    })(i, timeInterval);
    timeInterval += 1000;
}
于 2012-10-25T21:51:54.800 回答
0

保持范围最明显的方法i是在其他答案中解决,但是由于您使用的是 jQuery,因此您还有其他选择。

  1. 使用$.each而不是for循环,这样您就i可以在该范围内的任何地方访问变量。

  2. 使用delay而不是setTimeout. 为此,您需要先触发队列:$(".test").show(0).delay(timeInterval).append("test" + i)

于 2012-10-25T22:14:14.860 回答