2013-05-13 67 views
1

我想在HTML/JS中編寫遊戲Simon,它的全部工作,除了遊戲閃爍序列的部分,所以你知道新序列是什麼。基本上我有什麼是:for循環中的多setTimeout調用

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"; 
    } 
} 

什麼它似乎做的是經歷了整個的循環,並啓動所有的計時器,然後再所有定時器這麼快就熄滅了,甚至顏色看起來都不閃爍。

任何想法?所有的幫助非常感謝。


現在它是正確閃爍,關閉工作正常,但在同一時間閃爍的所有顏色。然而,我試圖將封閉件放入另一個setTimeout,這隻會產生其他問題。


解決感謝您的幫助球員。

+0

你真的需要了解switch語句。 – epascarello 2013-05-13 17:34:21

+0

首先解決這裏答案中指出的問題。然後,當你發現修復這個問題的下一個問題會暴露,看看這個:http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – 2013-05-13 17:36:10

回答

7

你需要一個函數傳遞給setTimeout

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

現在,你立即調用colorON(obj)並將其輸出傳遞到setTimeout,這使得它看起來像setTimeout被立即解僱。

obj也是按引用傳遞,這樣的時候所有的功能將運行,obj將參照最後元素在你的循環。爲了解決這個問題,你必須通過obj的陰影值:

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

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

你會碰到*「在循環中創建函數」*問題。 OP應該保持相同的代碼,並使函數返回一個函數。 – 2013-05-13 17:33:57

+1

這是真的,但修復它會導致另一個問題。在循環中調用'setTimeout','obj'值將始終是最後一次迭代的最終值。 – 2013-05-13 17:34:40

+1

@squint:我寧願隻影「obj」。 'colorON'返回一個函數是違反直覺的。 – Blender 2013-05-13 17:39:40

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/

+0

你會擊中*「在循環中創建函數」*問題。 OP應該保持相同的代碼,並使函數返回一個函數。 – 2013-05-13 17:34:25