我有这个脚本:
for (var i = 1; i <= 2; i++) {
setTimeout(function() { alert(i) }, 100);
}
但是两次警报都会弹出3
,而不是先弹出1
然后再弹出2
。
有没有一种方法可以传递i
,而不必将函数编写为字符串?
我有这个脚本:
for (var i = 1; i <= 2; i++) {
setTimeout(function() { alert(i) }, 100);
}
但是两次警报都会弹出3
,而不是先弹出1
然后再弹出2
。
有没有一种方法可以传递i
,而不必将函数编写为字符串?
function doSetTimeout(i) {
setTimeout(function() {
alert(i);
}, 100);
}
for (var i = 1; i <= 2; ++i)
doSetTimeout(i);
If what you need is for the handlers to be called at intervals, you can either use
setInterval()
, which is called exactly likesetTimeout()
but which will fire more than once after repeated delays of the requested amount, or instead you can establish the timeouts and multiply the time value by your iteration counter. That is, to modify my example code:
function doScaledTimeout(i) { setTimeout(function() { alert(I); }, i * 5000); }
(With a
100
millisecond timeout, the effect won't be very obvious, so I bumped the number up to 5000.) The value ofi
is multiplied by the base delay value, so calling that 5 times in a loop will result in delays of 5 seconds, 10 seconds, 15 seconds, 20 seconds, and 25 seconds.
更新
在2018年,有一个更简单的替代方案。通过在比函数更小的作用域中声明变量的新能力,如果进行如下修改,则原始代码将继续工作:
for (let i = 1; i <= 2; i++) {
setTimeout(function() {
alert(i)
}, 100);
}
let
声明与 var
不同,它会为循环的每次迭代创建一个独立的 i
。
for
循环完成后超时才会触发。即使超时为零秒,setTimeout()
调用也总是推迟函数的执行。 - Pointy你可以使用立即执行函数表达式 (IIFE) 来创建一个setTimeout
的闭包:
for (var i = 1; i <= 3; i++) {
(function(index) {
setTimeout(function() { alert(index); }, i * 1000);
})(i);
}
let
而不是var
。 - hien这是因为的原因!
解决方案是通过使用一个自执行函数(匿名或更好的IIFE)为每次迭代声明一个单独的作用域,并在其中拥有i的副本,像这样:
for (var i = 1; i <= 2; i++) {
(function(){
var j = i;
setTimeout(function() { console.log(j) }, 100);
})();
}
更加清洁的那一个
for (var i = 1; i <= 2; i++) {
(function(i){
setTimeout(function() { console.log(i) }, 100);
})(i);
}
在每次迭代中使用一个IIFE(自执行函数)创建了一个新的作用域,使得我们的超时函数回调有机会为每次迭代关闭一个新的作用域,其中包含了一个变量,该变量具有适当的每次迭代值,可以供我们访问。
setTimeout
的函数参数正在捕获循环变量。在第一次超时之前,循环已经完成并显示了当前值i
,即3
。
由于JavaScript变量只有函数作用域,解决方法是将循环变量传递给设置超时的函数。您可以像这样声明和调用这样的函数:
for (var i = 1; i <= 2; i++) {
(function (x) {
setTimeout(function () { alert(x); }, 100);
})(i);
}
i * 1000
。 - Pushp Singhfor (var i = 1; i <= 2; i++) {
setTimeout(function(j) { alert(j) }, 100, i);
}
答案?
我正在使用它来制作添加物品到购物车的动画-当点击产品的“添加”按钮时,购物车图标从页面上飘到购物车区域:
function addCartItem(opts) {
for (var i=0; i<opts.qty; i++) {
setTimeout(function() {
console.log('ADDED ONE!');
}, 1000*i);
}
};
注意,持续时间以单位n的时间为基准。
因此,从单击时刻开始,每个动画的起始时间(epoc)是每秒单位乘以项目数量的乘积。
epoc: https://en.wikipedia.org/wiki/Epoch_(reference_date)
希望这能帮到您!
bind
方法。for (var i = 1, j = 1; i <= 3; i++, j++) {
setTimeout(function() {
alert(this);
}.bind(i), j * 100);
}
this
的设置。但我明白了。类似于这个,您也可以使用setTimeout(console.log.bind(console,i), 1000);
。 - Muhammad Umer好的,基于Cody的答案,另一个可行的解决方案是这样的:
但更加通用的方法可能是这样的:
function timedAlert(msg, timing){
setTimeout(function(){
alert(msg);
}, timing);
}
function yourFunction(time, counter){
for (var i = 1; i <= counter; i++) {
var msg = i, timing = i * time * 1000; //this is in seconds
timedAlert (msg, timing);
};
}
yourFunction(timeInSeconds, counter); // well here are the values of your choice.
我曾经遇到过同样的问题,以下是我的解决方法。
假设我想要12个2秒的延迟
function animate(i){
myVar=setTimeout(function(){
alert(i);
if(i==12){
clearTimeout(myVar);
return;
}
animate(i+1)
},2000)
}
var i=1; //i is the start point 1 to 12 that is
animate(i); //1,2,3,4..12 will be alerted with 2 sec delay
animate(i);
- 如果你调用 animate(1)
,这个方法才能按照描述正常工作,因为 i
是未定义的。使用其他值将无法正确运行。该参数在最好的情况下是毫无意义的。 - nathanchere真正的解决方案在这里,但你需要熟悉PHP编程语言。你必须混合使用PHP和JAVASCRIPT命令才能达到你的目的。
请注意:
<?php
for($i=1;$i<=3;$i++){
echo "<script language='javascript' >
setTimeout(function(){alert('".$i."');},3000);
</script>";
}
?>
它正好做你想要的事情,但要小心PHP变量和JAVASCRIPT变量之间的关系如何建立。
let
而不是var
。这将解决你的问题。 - Mari Selvan