7

This is probably intended behaviour or atleast not a jQuery / js issue but I'd like some clarification if there's any to be had.

Take the following:

$(document).bind('keypress', function(e){
    switch(e.keyCode)
    {
        case 37:
            console.log('left cursor keydown, will fire on hold');
            break;
        case 39:
            console.log('right cursor keydown, will fire on hold');
            break;
        case 80:
            console.log('p will only fire once per press!');
            break;
    }
});

You can also play with the example at jQuery's docs: http://api.jquery.com/keypress/

When a left or right cursor is pressed (or many other keys such as A,E,[, etc), the event fires and you get a nice log message in the console. All fine & as intended. However, now try holding the key down - after a brief pause you will see that the keydown event fires multiple times when you hold the key, however if you try hitting a p (or, for instance, a j), it will only fire once.

I'm testing this using FF 9.0.1 and mac OSX 10.7.1 and jQuery 1.7.1.

Is this by design, is it a browser-dependant feature, or is it to do with the OS, or even the keyboard itself? Also has anyone got a list of keys that will repeat and keys that will not?

As far as the use case goes, there isn't one really - this just cropped up when I was binding an animation to a cursor press and started seeing wierd behaviour when the key was pressed. My workaround was to use the keyup() event instead, and preventDefault() on the keydown() event for the keys I was insterested in, to stop the cursors scrolling the screen.

UPDATE: Seems that on the keypress event, keyCode is always 0 for most letters, which might have something to do with why I thought the handler only fired once. After some more testing I see the repeated log entries like for cursors. If you check the jQuery API page though, and use the demo on that, it exhibits the behaviour I was describing: http://api.jquery.com/keypress/

Still can't explain that myself :/

totallyNotLizards
  • 8,489
  • 9
  • 51
  • 85
  • All keys repeat. You need to add `break`'s at the end of each switch case, unless you left them out intentionally. Either your keyboard is malfunctioning, or your code simply needs some `break`'s. – Nahydrin Feb 01 '12 at 15:11
  • Not for me - "p" repeats just fine. I think it's a function of your keyboard's hardware/firmware. – Pointy Feb 01 '12 at 15:11
  • @BrianGraham just spotted that, thanks :) after testing this again on jsfiddle I'm seeing a repeat on all keys too - however the keyCode attr is 0 on most keys for the keypress event, which would explain some of the odd behaviour I was seeing – totallyNotLizards Feb 01 '12 at 15:15

3 Answers3

5

Behaviour varies between browsers and operating systems. The following page covers the topic of auto-repeated key events in detail in section 2.2:

http://unixpapa.com/js/key.html

Tim Down
  • 318,141
  • 75
  • 454
  • 536
1

This problem has been around for ages, but i think i have discovered a fix just now. This seems to work fine

$("#search_query").keyup(function(event) {

    //this will void fake keypresses
    if(event.charCode == 0 && event.keyCode == 0) {
        return false;
    }

    //place the rest of you code here
});
totallyNotLizards
  • 8,489
  • 9
  • 51
  • 85
centralhubb.com
  • 2,705
  • 19
  • 17
0

Also - for the benefit of all people who view this post: try the "keydown" method

Keypress will get fired multiple times... keydown won't

http://jquerymobile.com/demos/1.0a2/experiments/api-viewer/docs/keypress/index.html

Rebecca
  • 577
  • 4
  • 11
  • 6
    `Keydown` actually does repeat (in latest Google Chrome at least). Try it right here: `$(document).on('keydown', function(ev) { console.log(ev) })` – Juribiyan Jan 20 '14 at 08:29