The KeyboardEvent
interface's key
read-only property returns the value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
The KeyboardEvent
interface's key
read-only property returns the value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
A string.
Its value is determined as follows:
KeyboardEvent
represents the press of a dead key, the key value must be "Dead
".WM_APPCOMMAND
events. These events get mapped to DOM keyboard events, and are listed among the "Virtual key codes" for Windows, even though they aren't actually key codes.Unidentified
.Every KeyboardEvent
is fired in a pre-determined sequence. For a given key press, the sequence of KeyboardEvent
s fired is as follows assuming that Event.preventDefault
is not called:
keydown
event is first fired. If the key is held down further and the key produces a character key, then the event continues to be emitted in a platform implementation dependent interval and the KeyboardEvent.repeat
read only property is set to true
.<input>
, <textarea>
or an element with HTMLElement.contentEditable
set to true, the beforeinput
and input
event types are fired in that order. Note that some other implementations may fire keypress
event if supported. The events will be fired repeatedly while the key is held down.keyup
event is fired once the key is released. This completes the process.In sequence 1 & 3, the KeyboardEvent.key
attribute is defined and is set appropriately to a value according to the rules defined earlier.
Consider the event sequence generated when we interact with the Shift and the 2 key using a U.S keyboard layout as compared to when we do so using a UK keyboard layout.
Try experimenting using the following two test cases:
html
<div class="fx"> <div> <textarea rows="5" name="test-target" id="test-target"></textarea> <button type="button" name="btn-reset" id="btn-reset">Reset</button> </div> <div class="flex"> <pre id="console-log"></pre> </div> </div>
css
.fx { -webkit-display: flex; display: flex; margin-left: -20px; margin-right: -20px; } .fx > div { padding-left: 20px; padding-right: 20px; } .fx > div:first-child { width: 30%; } .flex { -webkit-flex: 1; flex: 1; } #test-target { display: block; width: 100%; margin-bottom: 10px; }
js
let textarea = document.getElementById("test-target"), consoleLog = document.getElementById("console-log"), btnReset = document.getElementById("btn-reset"); function logMessage(message) { consoleLog.innerHTML += `${message}<br>`; } textarea.addEventListener("keydown", (e) => { if (!e.repeat) { logMessage(`Key "${e.key}" pressed [event: keydown]`); } else { logMessage(`Key "${e.key}" repeating [event: keydown]`); } }); textarea.addEventListener("beforeinput", (e) => { logMessage(`Key "${e.data}" about to be input [event: beforeinput]`); }); textarea.addEventListener("input", (e) => { logMessage(`Key "${e.data}" input [event: input]`); }); textarea.addEventListener("keyup", (e) => { logMessage(`Key "${e.key}" released [event: keyup]`); }); btnReset.addEventListener("click", (e) => { let child = consoleLog.firstChild; while (child) { consoleLog.removeChild(child); child = consoleLog.firstChild; } textarea.value = ""; });
Note: On browsers that don't fully implement the InputEvent
interface which is used for the beforeinput
and input
events, you may get incorrect output on those lines of the log output.
When the shift key is pressed, a keydown
event is first fired, and the key
property value is set to the string Shift
. As we keep holding this key, the keydown
event does not continue to fire repeatedly because it does not produce a character key.
When key 2
is pressed, another keydown
event is fired for this new key press, and the key
property value for the event is set to the string @
for the U.S keyboard type and "
for the UK keyboard type, because of the active modifier shift
key. The beforeinput
and input
events are fired next because a character key has been produced.
As we release the key 2
, a keyup
event is fired and the key
property will maintain the string values @
and "
for the different keyboard layouts respectively.
As we finally release the shift
key, another keyup
event is fired for it, and the key attribute value remains Shift
.
When the shift key is pressed, a keydown
event is first fired, and the key
property value is set to be the string Shift
. As we keep holding this key, the keydown event does not continue to fire repeatedly because it produced no character key.
When key 2
is pressed, another keydown
event is fired for this new key press, and the key
property value for the event is set to be the string @
for the U.S keyboard type and "
for the UK keyboard type, because of the active modifier shift
key. The beforeinput
and input
events are fired next because a character key has been produced. As we keep holding the key, the keydown
event continues to fire repeatedly and the KeyboardEvent.repeat
property is set to true
. The beforeinput
and input
events are fired repeatedly as well.
As we release the shift
key, a keyup
event is fired for it, and the key attribute value remains Shift
. At this point, notice that the key
property value for the repeating keydown event of the key 2
key press is now "2" because the modifier shift
key is no longer active. The same goes for the InputEvent.data
property of the beforeinput
and input
events.
As we finally release the key 2
, a keyup
event is fired but the key
property will be set to the string value 2
for both keyboard layouts because the modifier shift
key is no longer active.
This example uses EventTarget.addEventListener()
to listen for keydown
events. When they occur, the key's value is checked to see if it's one of the keys the code is interested in, and if it is, it gets processed in some way (possibly by steering a spacecraft, perhaps by changing the selected cell in a spreadsheet).
js
window.addEventListener( "keydown", (event) => { if (event.defaultPrevented) { return; // Do nothing if the event was already processed } switch (event.key) { case "ArrowDown": // Do something for "down arrow" key press. break; case "ArrowUp": // Do something for "up arrow" key press. break; case "ArrowLeft": // Do something for "left arrow" key press. break; case "ArrowRight": // Do something for "right arrow" key press. break; case "Enter": // Do something for "enter" or "return" key press. break; case "Escape": // Do something for "esc" key press. break; default: return; // Quit when this doesn't handle the key event. } // Cancel the default action to avoid it being handled twice event.preventDefault(); }, true, );
Specification |
---|
UI Events # dom-keyboardevent-key |
Desktop | Mobile | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | |
key |
51 | 12 | 23 | 9IE's implementation does not completely match the current spec because it is based on an older version of the spec. |
38 | 10.1 | 51 | 51 | 23 | 41 | 10.3 | 5.0 |
dead_key |
51 | ≤79 | 37 | No | 38 | 10.1 | 51 | 51 | 37 | 41 | 10.3 | 5.0 |
non_printable_keys |
51 | 12 | 23 | 9IE's implementation does not completely match the current spec because it is based on an older version of the spec. |
38 | 10.1 | 51 | 51 | 23 | 41 | 10.3 | 5.0 |
printable_key |
51 | 12 | 29 | 9IE's implementation does not completely match the current spec because it is based on an older version of the spec. |
38 | 10.1 | 51 | 51 | 29 | 41 | 10.3 | 5.0 |
© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key