You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We should use two handlers: `document.onkeydown` and `document.onkeyup`.
3
3
4
-
The set `pressed` should keep currently pressed keys.
4
+
Let's create a set `pressed = new Set()` to keep currently pressed keys.
5
5
6
6
The first handler adds to it, while the second one removes from it. Every time on `keydown` we check if we have enough keys pressed, and run the function if it is so.
Copy file name to clipboardExpand all lines: 2-ui/3-event-details/5-keyboard-events/article.md
+21-18Lines changed: 21 additions & 18 deletions
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
Before we get to keyboard, please note that on modern devices there are other ways to "input something". For instance, people use speech recognition (especially on mobile devices) or copy/paste with the mouse.
4
4
5
-
So if we want to track any input into an `<input>` field, then keyboard events are not enough. There's another event named `input` to handle changes of an `<input>` field, by any means. And it may be a better choice for such task. We'll cover it later in the chapter <info:events-change-input>.
5
+
So if we want to track any input into an `<input>` field, then keyboard events are not enough. There's another event named `input` to track changes of an `<input>` field, by any means. And it may be a better choice for such task. We'll cover it later in the chapter <info:events-change-input>.
6
6
7
7
Keyboard events should be used when we want to handle keyboard actions (virtual keyboard also counts). For instance, to react on arrow keys `key:Up` and `key:Down` or hotkeys (including combinations of keys).
8
8
@@ -30,7 +30,7 @@ The `keydown` events happens when a key is pressed down, and then `keyup` -- whe
30
30
31
31
The `key` property of the event object allows to get the character, while the `code` property of the event object allows to get the "physical key code".
32
32
33
-
For instance, the same key `key:Z` can be pressed with or without `Shift`. That gives us two different characters: lowercase `z` and uppercase `Z`.
33
+
For instance, the same key `key:Z` can be pressed with or without `key:Shift`. That gives us two different characters: lowercase `z` and uppercase `Z`.
34
34
35
35
The `event.key` is exactly the character, and it will be different. But `event.code` is the same:
36
36
@@ -52,7 +52,7 @@ For instance:
52
52
53
53
There are several widespread keyboard layouts, and the specification gives key codes for each of them.
54
54
55
-
See [alphanumeric section of the spec](https://www.w3.org/TR/uievents-code/#key-alphanumeric-section) for more codes, or just try the [teststand](#keyboard-test-stand) above.
55
+
Read the [alphanumeric section of the spec](https://www.w3.org/TR/uievents-code/#key-alphanumeric-section) for more codes, or just press a key in the [teststand](#keyboard-test-stand) above.
56
56
```
57
57
58
58
```warn header="Case matters: `\"KeyZ\"`, not `\"keyZ\"`"
@@ -61,9 +61,7 @@ Seems obvious, but people still make mistakes.
61
61
Please evade mistypes: it's `KeyZ`, not `keyZ`. The check like `event.code=="keyZ"` won't work: the first letter of `"Key"` must be uppercase.
62
62
```
63
63
64
-
65
-
What if a key does not give any character? For instance, `key:Shift` or `key:F1` or others. For those keys `event.key` is approximately the same as `event.code`:
66
-
64
+
What if a key does not give any character? For instance, `key:Shift` or `key:F1` or others. For those keys, `event.key` is approximately the same as `event.code`:
67
65
68
66
| Key | `event.key` | `event.code` |
69
67
|--------------|-------------|--------------|
@@ -73,11 +71,11 @@ What if a key does not give any character? For instance, `key:Shift` or `key:F1`
73
71
74
72
Please note that `event.code` specifies exactly which key is pressed. For instance, most keyboards have two `key:Shift` keys: on the left and on the right side. The `event.code` tells us exactly which one was pressed, and `event.key` is responsible for the "meaning" of the key: what it is (a "Shift").
75
73
76
-
Let's say, we want to handle a hotkey: `key:Ctrl+Z` (or `key:Cmd+Z` for Mac). Most text editors hook the "Undo" action on it. We can set a listener on `keydown` and check which key is pressed -- to detect when we have the hotkey.
74
+
Let's say, we want to handle a hotkey: `key:Ctrl+Z` (or `key:Cmd+Z` for Mac). Most text editors hook the "Undo" action on it. We can set a listener on `keydown` and check which key is pressed.
77
75
78
76
There's a dilemma here: in such a listener, should we check the value of `event.key` or `event.code`?
79
77
80
-
On one hand, the value of `event.key` changes depending on the language. If the visitor has several languages in OS and switches between them, the same key gives different characters. So it makes sense to check `event.code`, it's always the same.
78
+
On one hand, the value of `event.key` is a character, it changes depending on the language. If the visitor has several languages in OS and switches between them, the same key gives different characters. So it makes sense to check `event.code`, it's always the same.
On the other hand, there's a problem with `event.code`. For different keyboard layouts, the same key may have different labels (letters).
90
+
On the other hand, there's a problem with `event.code`. For different keyboard layouts, the same key may have different characters.
93
91
94
-
For example, here are US layout ("QWERTY") and German layout ("QWERTZ") under it (courtesy of Wikipedia):
92
+
For example, here are US layout ("QWERTY") and German layout ("QWERTZ") under it (from Wikipedia):
95
93
96
94

97
95
98
96

99
97
100
98
For the same key, US layout has "Z", while German layout has "Y" (letters are swapped).
101
99
102
-
So, `event.code` will equal `KeyZ` for people with German layout when they press "Y".
100
+
Literally, `event.code` will equal `KeyZ` for people with German layout when they press `key:Y`.
101
+
102
+
If we check `event.code == 'KeyZ'` in our code, then for people with German layout such test will pass when they press `key:Y`.
103
+
104
+
That sounds really odd, but so it is. The [specification](https://www.w3.org/TR/uievents-code/#table-key-code-alphanumeric-writing-system) explicitly mentions such behavior.
103
105
104
-
That sounds odd, but so it is. The [specification](https://www.w3.org/TR/uievents-code/#table-key-code-alphanumeric-writing-system) explicitly mentions such behavior.
106
+
So, `event.code` may match a wrong character for unexpected layout. Same letters in different layouts may map to different physical keys, leading to different codes. Luckily, that happens only with several codes, e.g. `keyA`, `keyQ`, `keyZ` (as we've seen), and doesn't happen with special keys such as `Shift`. You can find the list in the [specification](https://www.w3.org/TR/uievents-code/#table-key-code-alphanumeric-writing-system).
105
107
106
-
-`event.code` has the benefit of staying always the same, bound to the physical key location, even if the visitor changes languages. So hotkeys that rely on it work well even in case of a language switch.
107
-
-`event.code` may match a wrong character for unexpected layout. Same letters in different layouts may map to different physical keys, leading to different codes. Luckily, that happens only with several codes, e.g. `keyA`, `keyQ`, `keyZ` (as we've seen), and doesn't happen with special keys such as `Shift`. You can find the list in the [specification](https://www.w3.org/TR/uievents-code/#table-key-code-alphanumeric-writing-system).
108
+
To reliably track layout-dependent characters, `event.key` may be a better way.
108
109
109
-
So, to reliably track layout-dependent characters, `event.key` may be a better way.
110
+
On the other hand, `event.code` has the benefit of staying always the same, bound to the physical key location, even if the visitor changes languages. So hotkeys that rely on it work well even in case of a language switch.
111
+
112
+
Do we want to handle layout-dependant keys? Then `event.key` is the way to go.
113
+
114
+
Or we want a hotkey to work even after a language switch? Then `event.code` may be better.
Please note that special keys like `key:Backspace`, `key:Left`, `key:Right`, `key:Ctrl+V` do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`.
148
+
Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, `key:Ctrl+V`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`.
144
149
145
150
Let's relax it a little bit:
146
151
@@ -165,8 +170,6 @@ In the past, there was a `keypress` event, and also `keyCode`, `charCode`, `whic
165
170
166
171
There were so many browser incompatibilities while working with them, that developers of the specification had no way, other than deprecating all of them and creating new, modern events (described above in this chapter). The old code still works, as browsers keep supporting them, but there's totally no need to use those any more.
167
172
168
-
There was a time when this chapter included their detailed description. But, as of now, browsers support modern events, so it was removed and replaced with more details about the modern event handling.
169
-
170
173
## Summary
171
174
172
175
Pressing a key always generates a keyboard event, be it symbol keys or special keys like `key:Shift` or `key:Ctrl` and so on. The only exception is `key:Fn` key that sometimes presents on a laptop keyboard. There's no keyboard event for it, because it's often implemented on lower level than OS.
0 commit comments