If the user holds down the key, multiple keydown events are fired. For usability reasons I need to use keydown, not keyup, but I want to avoid this situation. My relevant co
So, if the existing solution seems dubious (it doesn't consider the case when 2 or more buttons is pressed simultaneously), I suggest another solution that takes it into account.
The _prevKeyDown object is to store keys that are currently pressed.
_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 );
}
(Copied from another question which turned out to be a duplicate of this one.)
dmaurolizer's KeyPress library gives fine control over all keyboard events. You provide callback functions for events. The keydown
event sends an optional isRepeat
param so you can ignore auto-repeats. Here's a sample using that functionality for the thrust control in a video game:
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;
}
}
]);
Use event.repeat
to detect whether or not the event is repeating. You could then wait for "keyup" before allowing the handler to execute a second time.
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;
});
Another simple adjustment to the accepted answer to allow for the multiple keys scenario:
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 = {};
});