如何避免JavaScript中自动重复的按键事件?

How can I avoid autorepeated keydown events in JavaScript?

本文关键字:事件 JavaScript 何避免      更新时间:2023-09-26

如果用户按住该键,则触发多个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 = {};
});

它很简单

$(document).keydown(function(e) {
    if (e.repeat) return;
    // ...
});

所以,如果现有的解决方案看起来可疑(它不考虑同时按下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 );
    }

(抄自另一个问题,结果发现是这个问题的复制品)

dmaurolizer的KeyPress库提供了对所有键盘事件的精细控制。为事件提供回调函数。keydown事件发送一个可选的isRepeat参数,因此您可以忽略自动重复。以下是在电子游戏中使用推力控制功能的示例:

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