簡體   English   中英

如何避免 JavaScript 中自動重復的 keydown 事件?

[英]How can I avoid autorepeated keydown events in JavaScript?

如果用戶按住鍵,則會觸發多個 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 );
    }

這很簡單

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

(從另一個問題復制,結果證明是這個問題的副本。)

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM