2011-09-25 60 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"); 

此外,我建议阅读贾尼的帖子(和相关文章),你可能已经走进了这个问题为好。