for循环中的多个setTimeout调用

时间:2013-05-13 17:29:26

标签: javascript for-loop settimeout

我正在尝试使用HTML / JS对游戏Simon进行编码,除了游戏闪烁序列的部分以外你知道新序列是什么之外,它都可以正常工作。基本上我所拥有的是:

for(var i in thePattern){
    var obj = document.getElementById(thePattern[i]);
    window.setTimeout(colorON(obj),500);
    window.setTimeout(colorOFF(obj),1000);
}

其中colorON和colorOFF是:

function colorON(obj){
    if(obj.id == "red"){
        obj.style.backgroundColor="#ff5555";
    }else if(obj.id == "blue"){
    obj.style.backgroundColor="#5555ff";
    }else if(obj.id == "green"){
    obj.style.backgroundColor="#88ff88";
    }else{
    obj.style.backgroundColor="#ffffaa";
    }
}
function colorOFF(obj){
    if(obj.id == "red"){
        obj.style.backgroundColor="#ff0000";
    }else if(obj.id == "blue"){
        obj.style.backgroundColor="#0000ff";
    }else if(obj.id == "green"){
        obj.style.backgroundColor="#22ff22";
    }else{
        obj.style.backgroundColor="#ffff00";
    }
}

它似乎正在做的是经历整个for循环并启动所有计时器,然后所有计时器都快速消失,颜色甚至看起来都不闪烁。

有什么想法吗?非常感谢所有帮助。


现在它正确闪烁并且关闭工作正常,但它同时闪烁所有颜色。我已经尝试将闭包放在另一个setTimeout中,但这只会产生其他问题。


已解决感谢您的帮助。

2 个答案:

答案 0 :(得分:7)

您需要将函数传递给setTimeout

window.setTimeout(function() {
    colorON(obj);
},500);

现在,您立即调用colorON(obj)并将其输出传递给setTimeout,这使setTimeout似乎立即触发。

obj也会通过引用传递,因此当您的所有函数运行时,obj将引用循环中的 last 元素。要解决这个问题,你必须通过遮蔽它来传递obj

(function(obj) {
    window.setTimeout(function() {
        colorON(obj);
    }, 500);

    window.setTimeout(function() {
        colorOFF(obj);
    }, 1000);
})(obj);

答案 1 :(得分:2)

您正在调用该函数,而不是为其分配引用!因此,代码立即运行,并使用函数返回的任何内容设置setTimeout。

更改

window.setTimeout(colorON(obj),500);
window.setTimeout(colorOFF(obj),1000);

for(var i in thePattern){
    var obj = document.getElementById(thePattern[i]);
    (function(obj) {
        window.setTimeout(function(){colorON(obj);},500);
        window.setTimeout(function(){colorOFF(obj);},1000);
    })(obj);
}

和代码显示如何使用开关或对象来摆脱if / else逻辑

function colorON(obj) {
    var color = "";
    switch (obj.id) {
        case "red":
            color = "#ff5555"
            break;
        case "blue":
            color = "#5555ff"
            break;
        case "green":
            color = "#88ff88"
            break;
        default:
            color = "#ffffaa"
    }
    obj.style.background = color;
}

var colorsOff = {
    "red": "#ff0000",
        "blue": "#0000ff",
        "green": "#22ff22",
        "default": "#ffff00"
}



    function colorOFF(obj) {
        var color = colorsOff[obj.id] || colors["default"];
        obj.style.backgroundColor = color;
    }


var thePattern = {
    "one": "red",
        "two": "blue",
        "three": "green"
}


for (var i in thePattern) {
    var obj = document.getElementById(thePattern[i]);
    (function (obj) {
        window.setTimeout(function () {
            colorON(obj);
        }, 500);
        window.setTimeout(function () {
            colorOFF(obj);
        }, 1000);
    })(obj);
}

示例:http://jsfiddle.net/brjgc/