Search code examples
javascripteventsdom-eventskeypress

How to get info on what key was pressed on for how long?


Imagine this code:

if (navigator.appName == "Opera")
    document.onkeypress = function (e) { console.log(e.keyCode); };
else 
    document.onkeydown = function (e) { console.log(e.keyCode); };

What it does is pretty obvious, I guess. The problem is, if you hold the key for a long period of time, it will be registered a lot of times. In my app, this is a problem because it makes my app do a lot of unnecessary computing. Is it possible to somehow only get a keypress once, but with info on how long the key was held?


Solution

  • Here you go:

    var pressed = {};
    
    window.onkeydown = function(e) {
        if ( pressed[e.which] ) return;
        pressed[e.which] = e.timeStamp;
    };
    
    window.onkeyup = function(e) {
        if ( !pressed[e.which] ) return;
        var duration = ( e.timeStamp - pressed[e.which] ) / 1000;
        // Key "e.which" was pressed for "duration" seconds
        pressed[e.which] = 0;
    };
    

    Live demo: http://jsfiddle.net/EeXVX/1/show/

    (remove the "show/" part of the URL to view the code for the demo)

    So you have the pressed object which monitors which keys are currently being pressed and at what point (in time) they have been pressed.

    Inside the keyup handler, you determine if the key was being pressed, and if so, calculate the duration by subtracting the time-stamps of the keyup/keydown events.