2011-09-25 88 views
2

考慮下面的代碼:遍歷JavaScript對象綁定密鑰

controls = { 
    'w': 'up', 
    's': 'down', 
    'a': 'left', 
    'd': 'right' 
}; 

keysPressed = []; 

for (control in controls) { 
    direction = controls[control]; 
    $(document).bind('keydown', control, function() { 
    keysPressed.push(direction); 
    }); 
} 

只有right方向被約束,並且它被綁定到所有四個鍵。這顯然不是有意的,但是我錯過了關於JavaScript的所有屬性被禁止適當綁定的內容?

編輯:

爲了澄清,我使用jQuery.hotkeys處理的鍵名。這是一個片段;你可以假設所有的變量已經被聲明。此外,代碼在安全function包裝。

SOLUTION:

我這個修改解決了它:

controls = { 
    'w': 'up', 
    's': 'down', 
    'a': 'left', 
    'd': 'right' 
}; 

keysPressed = []; 

addToKeyPressArray = function(value) { 
    return function() { 
    keysPressed.push(value); 
    }; 
}; 

removeFromKeyPressArray = function(value) { 
    return function() { 
    keysPressed = keysPressed.filter(value); 
    }; 
}; 

for (control in controls) { 
    direction = controls[control]; 
    $(document).bind('keydown', control, addToKeyPressArray(direction)); 
    $(document).bind('keyup', control, removeFromKeyPressArray(direction)); 
} 

這是一個奇怪的JavaScript怪癖。

+0

所有這些變量都是在上面的某個地方聲明的,對吧? –

+0

是的。這是一個片段。 – mybuddymichael

+0

「bind()」的第二個參數應該是一個對象(表示事件數據),而不是一個字符串。 –

回答

2

在我看來,這很可能是基本的「封閉式循環」問題,很多人都用JS來解決這個問題。

的解釋和解決方案很容易通過谷歌找到,這裏有一個例子:http://www.mennovanslooten.nl/blog/post/62

+0

是的,這是做到了。一個有趣的JavaScript怪癖的好解釋。謝謝! – mybuddymichael

1

這是我會怎麼做:

$(document).keypress(function (e) { 
    var char = String.fromCharCode(e.keyCode); 

    if (controls[ char ]) { 
     keysPressed.push(controls[ char ]); 
    } 
}); 
0

你沒有申報的direction變量(使用var),所以它會在全球範圍內。這意味着for循環將運行,然後direction將設置爲right

所有按鍵綁定,但所有的呼叫

keysPressed.push(direction); 
// and that is: 
keysPressed.push("right"); 

此外,我建議閱讀賈尼的帖子(和相關文章),你可能已經走進了這個問題爲好。