.keyCode vs. .which

.keyCode vs. .which

I thought this would be answered somewhere on Stack Overflow, but I can’t find it.
If I’m listening for a keypress event, should I be using .keyCode or .which to determine if the Enter key was pressed?
I’ve always done something like the following:
$(“#someid”).keypress(function(e) {
if (e.keyCode === 13) {
e.preventDefault();
// do something
}
});

But I’m seeing examples that use .which instead of .keyCode. What’s the difference? Is one more cross-browser friendly than the other?

Solutions/Answers:

Solution 1:

Some browsers use keyCode, others use which. If you’re using jQuery, you can reliably use which as jQuery standardizes things. More here.


If you’re not using jQuery, you can do this:

var key = 'which' in e ? e.which : e.keyCode;

Or alternately:

var key = e.which || e.keyCode || 0;

…which handles the possibility that e.which might be (by restoring that at the end, using JavaScript’s curiously-powerful || operator).

Solution 2:

jQuery normalises event.which depending on whether event.which, event.keyCode or event.charCode is supported by the browser:

// Add which for key events
if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
   event.which = event.charCode != null ? event.charCode : event.keyCode;
}

An added benefit of .which is that jQuery does it for mouse clicks too:

// Add which for click: 1 === left; 2 === middle; 3 === right
// Note: button is not normalized, so don't use it
if ( !event.which && event.button !== undefined ) {
    event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
}

Solution 3:

If you are staying in vanilla Javascript, please note keyCode is now deprecated and will be dropped:

This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Avoid using it and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any tim

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

Related:  How to know if two arrays have the same values

Instead use either: .key or .code depending on what behavior you want:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

Both are implemented on modern browsers.

Solution 4:

look at this: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

In a keypress event, the Unicode value of the key pressed is stored in either the keyCode or charCode property, never both. If the key pressed generates a character (e.g. ‘a’), charCode is set to the code of that character, respecting the letter case. (i.e. charCode takes into account whether the shift key is held down). Otherwise, the code of the pressed key is stored in keyCode.
keyCode is always set in the keydown and keyup events. In these cases, charCode is never set.
To get the code of the key regardless of whether it was stored in keyCode or charCode, query the which property.
Characters entered through an IME do not register through keyCode or charCode.

Solution 5:

A robust Javascript library for capturing keyboard input and key combinations entered. It has no dependencies.

Related:  Javascript, Time and Date: Getting the current minute, hour, day, week, month, year of a given millisecond time

http://jaywcjlove.github.io/hotkeys/

hotkeys('ctrl+a,ctrl+b,r,f', function(event,handler){
    switch(handler.key){
        case "ctrl+a":alert('you pressed ctrl+a!');break;
        case "ctrl+b":alert('you pressed ctrl+b!');break;
        case "r":alert('you pressed r!');break;
        case "f":alert('you pressed f!');break;
    }
});

hotkeys understands the following modifiers: , shift, option, , alt, ctrl, control, command, and .

The following special keys can be used for shortcuts: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, delete and f1 through f19.

Solution 6:

I’d recommend event.key currently. MDN docs: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCode and event.which both have nasty deprecated warnings at the top of their MDN pages:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which

For alphanumeric keys, event.key appears to be implemented identically across all browsers. For control keys (tab, enter, escape, etc), event.key has the same value across Chrome/FF/Safari/Opera but a different value in IE10/11/Edge (IEs apparently use an older version of the spec but match each other as of Jan 14 2018).

For alphanumeric keys a check would look something like:

event.key === 'a'

For control characters you’d need to do something like:

event.key === 'Esc' || event.key === 'Escape'

I used the example here to test on multiple browsers (I had to open in codepen and edit to get it to work with IE10): https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code

Related:  WebRTC remote video is shown as black

event.code is mentioned in a different answer as a possibility, but IE10/11/Edge don’t implement it, so it’s out if you want IE support.