Debugging Javascript KeyboardEvent Properites
Stumble across this bug when try to move some old code from jQuery to vanilla JS.
To response "Done" button in text input:
1 | document.querySelector('#queryInput').addEventListener('keydown', e => { |
Old code with e.which == 13
works fine, as e.which
property is depreciated, I tried to use e.code
. This works everywhere except Android Chrome.
KeyboardEvent
To identify a keypress with KeyboardEvent, we have:
- keyCode
- which
- code
- key
keyCode
and which
are all depreciated and the later isn't even on the document page. So officially we have only code
and key
. And the code
property is a tricky one.
which
and keyCode
return a numeric value, and they're always the same in my limited test. code
and key
returns different string value and code
give some more "precise" result.
Things get interesting with mobile device and IME.
Here is the document for code
If the input device isn't a physical keyboard, but is instead a virtual keyboard or accessibility device, the returned value will be set by the browser to match as closely as possible to what would happen with a physical keyboard, to maximize compatibility between physical and virtual input devices.
Or in other words, on soft keyboard , don't expect anything for code
.
Test Result
PC(Windows 10) Chrome | keyCode/which | code | key |
---|---|---|---|
A(upper case,holding shift or caps lock on) | 65 | keyA | A |
a(lower case) | 65 | keyA | a |
Left Shift | 16 | ShiftLeft | Shift |
Enter | 13 | Enter | Enter |
Numberpad Enter | 13 | NumberpadEnter | Enter |
A with IME* | 229 | KeyA | Process |
PC with onscreen keyboard | |||
Same result as hardware keyboard | |||
Android 11 Chrome w/GBoard | |||
A | 229 | ""(empty string) | Unidentified |
a | 229 | ""(empty string) | Unidentified |
Done | 13 | ""(empty string) | Enter |
A with Pinyin IME* | N/A | N/A | N/A |
iOS 17 Safari default IME | |||
A | 65 | KeyA | A |
a | 65 | KeyA | a |
Shift | 16 | ShiftLeft | Shift |
Done | 13 | Enter | Enter |
A with Pinyin IME* | 229 | KeyA | A |
Note:
- PC and iOS get all key events with IME. on PC, even word selection is logged(as "229/Space" or "229/Digit1" etc.). Nothing on Android during composing at all, and a generic
229/""/Unidentified
is sent after word selection.
Also worth noting, while keycode 229 is a special char for composing, Android did a poor job handling it comparing to PC and iOS.
And that's why e.code == 'Enter'
fails. I don't know if it's addressed in latest Android but e.code
is definitely not a reliable way to get the key pressed. Use either keyCode
or key
.