Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force keydown event to fire only once per keyCode

Situation: I have a keydown handler with a switch for what key is pressed, fairly standard stuff, but when any key is held down the keydown event fires repeatedly (rather than just once when the key is actually pressed).

Why it's a problem: I want to keep the keydown listener active, i.e. be able to detect more than one key being pressed at once, but only have the event fire once per keydown. I will want to do something on the keyup for that keyCode based on the time between down and up, but that timing is getting screwed up because of the multiple firings.

What I've tried: I am currently keeping a list of keyCodes that are down, and checking against those in my keydown handler to keep the default behaviour from happening if the keyCode is in my list. However, the event is still firing very often and I'm concerned about the efficiency/elegance of this solution.

The actual question: Is there a good way to limit firing of the keydown event to just when the key is physically pushed down, or to only listen for specific keyCodes?

like image 355
Piers Mana Avatar asked May 05 '12 23:05

Piers Mana


1 Answers

In the keydown handler, check whether the key is the same as the last key handled. If it was, exit early. On keyup, forget the last key handled.

For example:

var lastEvent;
var heldKeys = {};

window.onkeydown = function(event) {
    if (lastEvent && lastEvent.keyCode == event.keyCode) {
        return;
    }
    lastEvent = event;
    heldKeys[event.keyCode] = true;
};

window.onkeyup = function(event) {
    lastEvent = null;
    delete heldKeys[event.keyCode];
};​

Demo here (click on the "Result" panel and hit keys).

like image 171
Dagg Nabbit Avatar answered Sep 20 '22 04:09

Dagg Nabbit