我有这个脚本:
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,而不把函数写成字符串?
当前回答
我也遇到过同样的问题这就是我解决的方法。
假设我想要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
其他回答
你可以使用bind方法
for (var i = 1, j = 1; i <= 3; i++, j++) {
setTimeout(function() {
alert(this);
}.bind(i), j * 100);
}
这是因为!
超时函数 回调在循环完成后都运行良好。事实上, 作为计时器,即使它是setTimeout(.., 0),所有 这些函数回调在完成后仍然严格运行 这就是为什么有3个被反射了! 这两个函数都有定义 在每个循环迭代中,分别在相同的共享全局上关闭 范围,实际上只有一个I在里面。
解决方案通过使用执行的自我函数(匿名或更好的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);
}
真正的解决方案在这里,但是您需要熟悉PHP编程语言。 你必须混合使用PHP和JAVASCRIPT才能达到你的目的。
请注意:
<?php
for($i=1;$i<=3;$i++){
echo "<script language='javascript' >
setTimeout(function(){alert('".$i."');},3000);
</script>";
}
?>
它完全是你想要的,但要小心如何使之间的关系 PHP变量和JAVASCRIPT变量。
答案?
我用它来做一个添加物品到购物车的动画——当点击产品“添加”按钮时,一个购物车图标浮动到购物车区域:
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)
希望这能有所帮助!