20

So I've seen some forums posts about different browsers reporting differenct keyCodes, but everyone seems so avoid the "why?".

I was trying to capture the colon (:) keyCode and realized that Firefox reports back e.keyCode 56. While Chrome reports back 186 (I think that's what it was).

Is there a univeral way of getting the right keyCode across all browsers?

And why are they different if they are the same keys?

I would be more curious as to whether there is a international way of getting the same key press.

Thanks.

Pointy
  • 405,095
  • 59
  • 585
  • 614
Senica Gonzalez
  • 7,996
  • 16
  • 66
  • 108
  • http://www.quirksmode.org/js/keys.html – gblazex Oct 07 '10 at 16:17
  • 1
    @galambalazs, this chart does not account for colon and semi-colon. Which suprises me. PPK is usually on top of that sort of thing. – Senica Gonzalez Oct 07 '10 at 17:02
  • http://unixpapa.com/js/key.html has the colon and semi-colon, and seems pretty exhaustive. – ruffin Jan 04 '13 at 14:02
  • 1
    KeyEvent (and hence keyCodes) is [basically deprecated and being replaced with KeyboardEvent](http://stackoverflow.com/a/33860580/1836776). This is not an answer as to why different browsers report different keyCodes but hopefully a pointer to what will potentially be a good solution in the future. Potentially. – Marc Durdin Nov 24 '15 at 08:10

7 Answers7

18

It depends whether you're interested in which physical key the user has pressed or which character the user has typed. If it's the character you're after, you can get that reliably in all major browsers (using the keypress event's which property in most browsers or keyCode in IE <= 8), but only in the keypress event. If you're after the key, use the keydown or keyup event and examine the keyCode property, although the exact key-code mappings do differ somewhat between browsers.

An excellent explanation of and reference for all JavaScript key-related events can be found at http://unixpapa.com/js/key.html.

To detect the user typing a colon character reliably in all the major browsers, you could do the following:

document.onkeypress = function(e) {
    e = e || window.event;
    var charCode = (typeof e.which == "number") ? e.which : e.keyCode;
    if (charCode && String.fromCharCode(charCode) == ":") {
        alert("Colon!");
    }
};
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • charCode != keyCode, except for /[A-Z 0-9]/ – Nathan Bubna Feb 05 '14 at 16:32
  • @NathanBubna: I know. However, in old IE's `keypress` event, `keyCode` confusingly *is* the character code, not a key code, and all other mainstream browsers support `which`, so `keyCode` is only used in old IE. Read all about it at http://unixpapa.com/js/key.html (as linked to in my answer). – Tim Down Feb 05 '14 at 17:40
  • Ick. Old IE strikes again. Thanks for the explanation! – Nathan Bubna Feb 05 '14 at 20:40
13

See http://unixpapa.com/js/key.html for an explanation why they have different keys. I do not know of an international way to match keys.

Plaudit Design
  • 1,156
  • 8
  • 16
3

This is an old question. The modern way to do this is use event.key. See MDN Key

kidconcept
  • 509
  • 6
  • 13
  • 1
    This is still the current way, considering Key is still in draft and not supported on most mobile browsers http://caniuse.com/#feat=keyboardevent-key – Nicu Surdu Mar 01 '17 at 16:34
  • suit your self, it's not very far off. It's worth noting that the far and away most popular mobile browser, Chrome for android has full support. The biggest gotchas are iOS and Safari, though Safaris' support is coming in the next version. I would recommend using one of the many available polyfills. – kidconcept Mar 01 '17 at 18:53
  • Actually you can use it. It's supported for most used browsers. (http://caniuse.com/#feat=keyboardevent-key) If the property is undefined you can still use a small fallback function. – CodeBrauer Jun 08 '17 at 14:52
  • Note that there are differences, however, in some modern browsers. For example, pressing the dot key (`.`/`Del`) on a Num Pad with the Num Lock on reports the event.key as "Del" in Edge, but reports it as "." in Chrome. People keep suggesting that Safari is the new Internet Explorer. Lately I wonder if Edge is actually the new Internet Explorer. Oh, wait. – Dale Harris May 04 '18 at 20:40
1

2022 - event.key gives the "logical" key, event.code gives the "physical" key

Some examples tested on MacOS Firefox, Windows Edge & Windows Chrome:

event.key event.code
"Enter" "Enter"
"Enter" "NumpadEnter"
"8" "Digit8"
"8" "Numpad8"
"/" "Slash"
"/" "NumpadDivide"

edge cases

  • Windows Chrome/Edge, when pressing ctrl+Enter the event.key is "\n"
wraiford
  • 181
  • 1
  • 5
0

I think you should make JavaScript to get the keycode of the ':' character, so the script will know what is it in a certain environment. Similar question had been asked here, in stackoverflow.

Community
  • 1
  • 1
ifroz
  • 103
  • 3
  • 6
0

Have also a look at this GitHub file: https://github.com/bpeacock/key-to-charCode/blob/master/jQuery.getChar.js on how you can use keyDown instead of keyPress events.

I used this for a barcode scanner with a keyboard wedge, on a mobile device, that had a bug on returning (keyPress) data for scanning a hyphen. Works pretty good. Except when I tested the app in a browser with a regular keyboard, I noticed that the hyphen works on Chrome, but not on Firefox. Strange but true. Fixed by adding code 173 in the above JS file, in addition to code 189.

This makes me wonder what the keyboard is actually sending. The keydown code of 173 or 189 for pressing the hyphen key (- _) is apparently not sent by the keyboard itself, but created by the browser that sends the keyDown event to my javascript application.

Roland
  • 4,619
  • 7
  • 49
  • 81
0

2023 here, I've been using a different solution to this for a long time.

It involves using a hidden textarea to get the typed character. It is a bit of a hack, but it works flawlessly in all major browsers and saves the headache of working with e.key or e.keyCode etc.

I'll just post the code here. It's fairly self-explanatory. If you're wanting this to work in ALL mobile browsers including opera mini etc then you'll have to change the fixed positioning to absolute positioning and make sure the textarea is always positioned around the middle of the visible part of the page to avoid scrolling whenever a character is typed.

Basically, create a hidden textarea, add a keydown event to the window object that focuses the textarea, get the value of the textarea, clear the textarea, focus the previously focused element again...and optionally then generate the typed character in the previously focused element.

    /*create a hidden textarea*/
    var keyGrabber = document.createElement('textarea');
    keyGrabber.style.border = '0';
    keyGrabber.style.margin = '0';
    keyGrabber.style.padding = '0';
    keyGrabber.style.outline = 'none';
    keyGrabber.style.position = 'fixed';
    keyGrabber.style.top = '0';
    keyGrabber.tabIndex = '-1';
            
    document.body.appendChild(keyGrabber);
    
    /*Avoid confusion for screen readers*/
    keyGrabber.setAttribute('aria-hidden','true');
    
    /*Init the variables here so they are global and easy to access*/
    var oldActiveElement = document.activeElement;
    var oldStart = 0;
    var oldEnd = 0;
    
    /*Catch the keydown event and store the active elements selection start and end in case you still want the character to be typed*/
    window.addEventListener('keydown',function(e){
        oldActiveElement = document.activeElement;
        oldStart = oldActiveElement.selectionStart;
        oldEnd = oldActiveElement.selectionEnd;
        keyGrabber.focus();
        /*If you need to capture keys that don't generate written characters, you'll have to do that here using e.key || e.keyCode */
    });
    
    keyGrabber.addEventListener('input',function(){
        var character = keyGrabber.value;
        if(character == ':'){
            alert('You typed a colon!');
            /*replace alert with whatever code you want to execute when a colon is typed*/
        }
        keyGrabber.value = '';
        oldActiveElement.focus();
        /*This part is optional, in case you want to still have the typed character generate in an input and also fire the event. You would then also replace "window.addEventListener..." with "yourInput.addEventListener..."*/
        var part1 = oldActiveElement.value.slice(0,oldStart);
        var part2 = oldActiveElement.value.slice(oldEnd,oldActiveElement.value.length);
        oldActiveElement.value = part1 + character + part2;
        oldActiveElement.selectionStart = oldStart + 1;
        oldActiveElement.selectionEnd = oldActiveElement.selectionStart;
    });

Please don't copy/paste this code and expect it to work flawlessly. I'm typing this from memory and not copying it from a working file. I can't remember if setting the tabIndex to -1 stops the .focus() from working. I think it's fine but please double check this.