如何在JavaScript中避免自动重复的keydown事件?

如果用户按下该键,则会触发多个keydown事件。 出于可用性原因,我需要使用keydown,而不是keyup,但我想避免这种情况。 我的相关代码如下:

$(document).keydown(function(e) { var key = 0; if (e == null) { key = event.keyCode;} else { key = e.which;} switch(key) { case config.keys.left: goLeft(); break; case config.keys.up: goUp(); break; case config.keys.right: goRight(); break; case config.keys.down: goDown(); break; case config.keys.action: select(); break; } }); 

因此,当用户按下向下键时,goDown()会被多次触发。 即使用户按住键,我也希望它只触发一次。

使用event.repeat检测事件是否重复。 然后,您可以在允许处理程序第二次执行之前等待“keyup”。

 var allowed = true; $(document).keydown(function(event) { if (event.repeat != undefined) { allowed = !event.repeat; } if (!allowed) return; allowed = false; //... }); $(document).keyup(function(e) { allowed = true; }); $(document).focus(function(e) { allowed = true; }); 

对允许多键情况的接受答案的另一个简单调整:

 var keyAllowed = {}; $(document).keydown(function(e) { if (keyAllowed [e.which] === false) return; keyAllowed [e.which] = false; // code to be executed goes here }); $(document).keyup(function(e) { keyAllowed [e.which] = true; }); $(document).focus(function(e) { keyAllowed = {}; }); 

因此,如果现有的解决方案看起来很可疑(它不考虑同时按下2个或更多按钮的情况),我建议另一个解决方案将其考虑在内。

_prevKeyDown对象用于存储当前按下的键。

  _prevKeyDown = {} function _downKey( event ) { var wh = event.which; var kC = event.keyCode; if( _prevKeyDown[ wh ] == null ) { _prevKeyDown[ wh ] = {}; } _prevKeyDown[ wh ][ kC ] = true; }; function _upKey( event ) { var wh = event.which; var kC = event.keyCode; if( _prevKeyDown[ wh ] != null ) { _prevKeyDown[ wh ][ kC ] = null; } }; function _isKeyDown( event ) { var wh = event.which; var kC = event.keyCode; var result = false; if( this._prevKeyDown[ wh ] != null ) { if( this._prevKeyDown[ wh ][ kC ] == true ) { result = true; } } return result; } // now your keydown/keyup handlers function keydown( event ) { if( !_isKeyDown( event ) ) { // your once-keydown handler here _downKey( event ); } } function keyup( event ) { _upKey( event ); } 

(复制自另一个问题,结果certificate是这个问题的副本。)

dmaurolizer的KeyPress库可以精确控制所有键盘事件。 您为事件提供回调函数。 keydown事件发送一个可选的isRepeat参数,因此您可以忽略自动重复。 以下是使用该function进行video游戏中推力控制的示例:

 var my_combos = listener.register_many([ { "keys" : "up", "on_keydown" : function(e, num, isRepeat) { if (isRepeat) return ; thrust = 0.1; }, "on_keyup" : function() { thrust = 0; } } ]);