我正在建造一个西蒙游戏。每轮比赛结束后,球员应该看到他必须在下一轮比赛中发挥的动作。所以我创建了一个函数showMoves,它闪烁了他必须播放的方块。问题是该功能没有显示任何内容。谁能告诉我我错过了什么?
// the effect
function flasher(index) {
$(moves[index]).fadeIn(50).fadeOut(50).fadeIn(50).fadeOut(50).fadeIn(100);
}
var interval2;
// show the moves that supposed to be played
function showMoves() {
for (var i = 0; i < moves; i++) {
if (i === 0) {
interval2 = setTimeout(flasher(i), 1000);
} else {
interval2 = setTimeout(flasher(i), (i+1) * 1000);
}
}
}
答案 0 :(得分:1)
setTimeout
接受函数作为第一个参数。我假设通过致电flasher
您试图避免this situation。在你的情况下,这应该这样做:
function showMoves() {
for (var i = 0; i < moves; i++) {
if (i === 0) {
interval2 = setTimeout(function(i) {return function() {flasher(i)}}(i), 1000);
} else {
interval2 = setTimeout(function(i) {return function() {flasher(i)}}(i), (i+1) * 1000);
}
}
}
答案 1 :(得分:0)
setTimeout和setInterval与我们想到的有点不同。 它们会在特定时间保存一些事件,这些事件将在其时间内触发。因此,他们遇到了循环问题:
for(i=0;i<3;i++)
{
setTimeout(function(){alert(i)}, i*1000);
}
结束循环后,浏览器有3个工作要做:
alert(i) after 1 second
alert(i) after 2 seconds
alert(i) after 3 seconds
但是&#39; i&#39;的价值是什么?如果你在结束循环之后进行c#编程,那么我就会#c;编程。将被处理,我们没有。 但javascript没有处理&#39;我&#39;我们还有它。因此浏览器将i的当前值设置为3.因为当&#39; i&#39;达到3循环结束。为此您的浏览器执行此操作:
alert(3) after 1 second
alert(3) after 2 seconds
alert(3) after 3 seconds
这不是我们想要的。但是如果将上面的代码更改为:
for(i=0;i<3;i++){
(function (index)
{
setTimeout(function () { alert(index); }, i * 1000);
})(i);
}
我们将:
alert(0) after 1 second
alert(1) after 2 seconds
alert(2) after 3 seconds
因此,Maximus说你使用浏览器获取i当前循环的值。这样:
setTimeout(function(i) {return function() {flasher(i)}}(i), (i+1) * 1000);
我不会遗漏直到循环结束,并且必须立即获得价值。
答案 2 :(得分:0)
我可以从你的代码中得到的是moves
是一个数组,但是你正在使用它,好像它是for循环中的一个整数。这就是为什么没有任何事情发生的原因。
替换:
for (var i = 0; i < moves; i++) {
使用:
for (var i = 0; i < moves.length; i++) {
你应该看到事情正在发生。
但是你会注意到flasher
被立即调用,没有超时。这是因为flasher
的结果设置为调用,而不是flasher
本身
这里的其他答案建议使用包装函数,但这需要解决方法才能正确地将索引传递给setTimeout
调用的函数。
因此,假设它不必在IE8及更低版本中运行,以下是最简洁的解决方案:
setTimeout(flasher.bind(null, i), (i+1) * 1000)
完整的工作示例:
var moves = [1, 2, 3, 4];
function flasher(index) {
console.log('move', moves[index]);
}
var interval2;
// show the moves that supposed to be played
function showMoves() {
for (var i = 0; i < moves.length; i++) {
interval2 = setTimeout(flasher.bind(null, i), (i+1) * 1000);
}
}
showMoves()