开发者

Iterating over a JavaScript object to bind keys

开发者 https://www.devze.com 2023-04-07 04:26 出处:网络
Considering the following code: controls = { \'w\': \'up\', \'s\': \'down\', \'a\': \'left\', \'d\': \'right\'

Considering the following code:

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

Only the right direction gets bound, and it is bound to all four keys. This is obviously not intended, but what am I missing about JavaScript that prevents all the properties from being bound appropriately?

EDIT:

For clarification, I'm using jQuery.hotkeys to handle key names. And this is a snippet; you can assume all variables have been declared. Also, c开发者_如何学JAVAode is in a safety function wrapper.

SOLUTION:

I solved it with this modification:

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

That's an odd JavaScript quirk.


Seems to me like it's probably the basic "closure in for loop" issue that many people trip up on with JS.

An explanation and solution is easy to find via google, here's one for example: http://www.mennovanslooten.nl/blog/post/62


This is how I would do it:

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

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


You didn't declare the direction variable (using var), so it will be in global scope. This means the for-loop will run and then direction will be set to right.

All keys are bound, but all call

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

Also I recommend to read Jani's post (and the related article) as you could have walked into that issue as well.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号