如果用户按下该键,则会触发多个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()会多次触发。即使用户按住键,我也希望它只触发一次。
答案 0 :(得分:39)
使用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;
});
答案 1 :(得分:7)
对允许多键情况的接受答案的另一个简单调整:
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 :(得分:3)
所以,如果现有的解决方案看起来很可疑(它不考虑同时按下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 );
}
答案 3 :(得分:0)
(从另一个问题复制而来,这个问题与此问题重复。)
dmaurolizer的KeyPress library可以很好地控制所有键盘事件。您为事件提供回调函数。 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;
}
}
]);