KeyboardEvent: keyCode property - Web APIs

KeyboardEvent: keyCode property
===============================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. 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 time.

The deprecated **`KeyboardEvent.keyCode`** read-only property represents a system and implementation dependent numerical code identifying the unmodified value of the pressed key.

This is usually the decimal ASCII (RFC 20) or Windows 1252 code corresponding to the key. If the key can't be identified, this value is `0`.

You should avoid using this if possible; it's been deprecated for some time. Instead, you should use `KeyboardEvent.code`, if it's implemented. Unfortunately, some browsers still don't have it, so you'll have to be careful to make sure you use one which is supported on all target browsers.

**Note:** Web developers shouldn't use the `keyCode` attribute for printable characters when handling `keydown` and `keyup` events. As described above, the `keyCode` attribute is not useful for printable characters, especially those input with the `Shift` or `Alt` key pressed. When implementing a shortcut key handler, the `keypress` event is usually better (at least when Gecko is the runtime in use).

Examples
--------

```js
window.addEventListener(
  "keydown",
  (event) => {
    if (event.defaultPrevented) {
      return; // Should do nothing if the default action has been cancelled
    }

    let handled = false;
    if (event.key !== undefined) {
      // Handle the event with KeyboardEvent.key
      handled = true;
    } else if (event.keyCode !== undefined) {
      // Handle the event with KeyboardEvent.keyCode
      handled = true;
    }

    if (handled) {
      // Suppress "double action" if event handled
      event.preventDefault();
    }
  },
  true,
);
```

Specifications
--------------

| Specification |
| --- |
| UI Events # dom-keyboardevent-keycode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Value of keyCode
----------------

### Printable keys in standard position

The value of key events which are caused by pressing or releasing printable keys in standard position is not compatible between browsers.

IE just exposes the native virtual keycode value as `KeyboardEvent.keyCode`.

Google Chrome, Chromium and Safari must decide the value from the input character. If the inputting character can be inputted with the US keyboard layout, they use the `keyCode` value on the US keyboard layout.

Firefox gets `keyCode` values from ASCII characters inputtable by the key — even with shift modifiers or an ASCII capable keyboard layout. See the following rules for details:

1. If the system is Windows and the native keycode of the pressed key indicates that the key is a-z or 0-9, use a keycode for it.
2. If the system is Mac and the native keycode of the pressed key indicates that the key is 0-9, use a keycode for it.
3. If the pressed key inputs an ASCII alphabetic or numeric character with no modifier key, use a keycode for it.
4. If the pressed key inputs an ASCII alphabetic or numeric character with a Shift key modifier, use a keycode for it.
5. If the pressed key inputs a different ASCII character with no modifier key, use a keycode for it.
6. If the pressed key inputs a different ASCII character with a Shift key modifier, use a keycode for it.
7. Otherwise, i.e., pressed key inputs a unicode character:
    1. If the keyboard layout is ASCII-capable (i.e., can input ASCII alphabets), use 0 or compute with the following additional rules.
    2. Otherwise, i.e., the keyboard layout isn't ASCII capable, use the ASCII capable keyboard layout installed on the environment with the highest priority:
        1. If the pressed key on the alternative keyboard layout inputs an ASCII alphabetic or numeric character, use a keycode for it.
        2. Otherwise, use 0 or compute with the following additional rules.

Gecko sets `keyCode` values of punctuation keys as far as possible (when points 7.1 or 7.2 in the above list are reached) with the following rules:

**Warning:** The purpose of these new additional rules is for making users whose keyboard layouts map unicode characters to punctuation keys in a US keyboard layout can use web applications which support Firefox only with ASCII-capable keyboard layouts or just with a US keyboard layout. Otherwise, the newly mapped `keyCode` values may be conflict with other keys. For example, if the active keyboard layout is Russian, the `keyCode` value of **both** the `"Period"` key and `"Slash"` key are `190` (`KeyEvent.DOM_VK_PERIOD`). If you need to distinguish those keys but you don't want to support all keyboard layouts in the world by yourself, you should probably use `KeyboardEvent.code`.

1. If running macOS or Linux:
    1. If the active keyboard layout is not ASCII-capable and an alternative ASCII-capable keyboard layout is available.
        1. If the alternative ASCII-capable keyboard layout produces an ASCII character via just the unmodified key, use a `keyCode` for the character.
        2. If the alternative ASCII-capable keyboard layout produces an ASCII character with a Shift key modifier, use a `keyCode` for the shifted character.
        3. Otherwise, use a `keyCode` for an ASCII character produced by the key when the US keyboard layout is active.
    2. Otherwise, use a `keyCode` for an ASCII character produced by the key when the US keyboard layout is active.
2. If running on Windows:
    1. Use a `keyCode` value for an ASCII character produced by a key which is mapped to the same virtual keycode of Windows when the US keyboard layout is active.

 keyCode values of each browser's keydown event caused by printable keys in
 standard position
 | `KeyboardEvent.code` | IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |
| --- | --- | --- | --- | --- | --- |
|  | Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
|  | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek |
| `"Digit1"` | `0x31 (49)` | `0x31 (49)` | `0x31 (49)` | `0x31 (49)` | `0x31 (49)` | `0x31 (49)` | `0x31 (49)` | `0x31 (49)` |
| `"Digit2"` | `0x32 (50)` | `0x32 (50)` | `0x32 (50)` | `0x32 (50)` | `0x32 (50)` | `0x32 (50)` | `0x32 (50)` | `0x32 (50)` |
| `"Digit3"` | `0x33 (51)` | `0x33 (51)` | `0x33 (51)` | `0x33 (51)` | `0x33 (51)` | `0x33 (51)` | `0x33 (51)` | `0x33 (51)` |
| `"Digit4"` | `0x34 (52)` | `0x34 (52)` | `0x34 (52)` | `0x34 (52)` | `0x34 (52)` | `0x34 (52)` | `0x34 (52)` | `0x34 (52)` |
| `"Digit5"` | `0x35 (53)` | `0x35 (53)` | `0x35 (53)` | `0x35 (53)` | `0x35 (53)` | `0x35 (53)` | `0x35 (53)` | `0x35 (53)` |
| `"Digit6"` | `0x36 (54)` | `0x36 (54)` | `0x36 (54)` | `0x36 (54)` | `0x36 (54)` | `0x36 (54)` | `0x36 (54)` | `0x36 (54)` |
| `"Digit7"` | `0x37 (55)` | `0x37 (55)` | `0x37 (55)` | `0x37 (55)` | `0x37 (55)` | `0x37 (55)` | `0x37 (55)` | `0x37 (55)` |
| `"Digit8"` | `0x38 (56)` | `0x38 (56)` | `0x38 (56)` | `0x38 (56)` | `0x38 (56)` | `0x38 (56)` | `0x38 (56)` | `0x38 (56)` |
| `"Digit9"` | `0x39 (57)` | `0x39 (57)` | `0x39 (57)` | `0x39 (57)` | `0x39 (57)` | `0x39 (57)` | `0x39 (57)` | `0x39 (57)` |
| `"Digit0"` | `0x30 (48)` | `0x30 (48)` | `0x30 (48)` | `0x30 (48)` | `0x30 (48)` | `0x30 (48)` | `0x30 (48)` | `0x30 (48)` |
| `"KeyA"` | `0x41 (65)` | `0x41 (65)` | `0x41 (65)` | `0x41 (65)` | `0x41 (65)` | `0x41 (65)` | `0x41 (65)` | `0x41 (65)` |
| `"KeyB"` | `0x42 (66)` | `0x42 (66)` | `0x42 (66)` | `0x42 (66)` | `0x42 (66)` | `0x42 (66)` | `0x42 (66)` | `0x42 (66)` |
| `"KeyC"` | `0x43 (67)` | `0x43 (67)` | `0x43 (67)` | `0x43 (67)` | `0x43 (67)` | `0x43 (67)` | `0x43 (67)` | `0x43 (67)` |
| `"KeyD"` | `0x44 (68)` | `0x44 (68)` | `0x44 (68)` | `0x44 (68)` | `0x44 (68)` | `0x44 (68)` | `0x44 (68)` | `0x44 (68)` |
| `"KeyE"` | `0x45 (69)` | `0x45 (69)` | `0x45 (69)` | `0x45 (69)` | `0x45 (69)` | `0x45 (69)` | `0x45 (69)` | `0x45 (69)` |
| `"KeyF"` | `0x46 (70)` | `0x46 (70)` | `0x46 (70)` | `0x46 (70)` | `0x46 (70)` | `0x46 (70)` | `0x46 (70)` | `0x46 (70)` |
| `"KeyG"` | `0x47 (71)` | `0x47 (71)` | `0x47 (71)` | `0x47 (71)` | `0x47 (71)` | `0x47 (71)` | `0x47 (71)` | `0x47 (71)` |
| `"KeyH"` | `0x48 (72)` | `0x48 (72)` | `0x48 (72)` | `0x48 (72)` | `0x48 (72)` | `0x48 (72)` | `0x48 (72)` | `0x48 (72)` |
| `"KeyI"` | `0x49 (73)` | `0x49 (73)` | `0x49 (73)` | `0x49 (73)` | `0x49 (73)` | `0x49 (73)` | `0x49 (73)` | `0x49 (73)` |
| `"KeyJ"` | `0x4A (74)` | `0x4A (74)` | `0x4A (74)` | `0x4A (74)` | `0x4A (74)` | `0x4A (74)` | `0x4A (74)` | `0x4A (74)` |
| `"KeyK"` | `0x4B (75)` | `0x4B (75)` | `0x4B (75)` | `0x4B (75)` | `0x4B (75)` | `0x4B (75)` | `0x4B (75)` | `0x4B (75)` |
| `"KeyL"` | `0x4C (76)` | `0x4C (76)` | `0x4C (76)` | `0x4C (76)` | `0x4C (76)` | `0x4C (76)` | `0x4C (76)` | `0x4C (76)` |
| `"KeyM"` | `0x4D (77)` | `0x4D (77)` | `0x4D (77)` | `0x4D (77)` | `0x4D (77)` | `0x4D (77)` | `0x4D (77)` | `0x4D (77)` |
| `"KeyN"` | `0x4E (78)` | `0x4E (78)` | `0x4E (78)` | `0x4E (78)` | `0x4E (78)` | `0x4E (78)` | `0x4E (78)` | `0x4E (78)` |
| `"KeyO"` | `0x4F (79)` | `0x4F (79)` | `0x4F (79)` | `0x4F (79)` | `0x4F (79)` | `0x4F (79)` | `0x4F (79)` | `0x4F (79)` |
| `"KeyP"` | `0x50 (80)` | `0x50 (80)` | `0x50 (80)` | `0x50 (80)` | `0x50 (80)` | `0x50 (80)` | `0x50 (80)` | `0x50 (80)` |
| `"KeyQ"` | `0x51 (81)` | `0x51 (81)` | `0x51 (81)` | `0x51 (81)` | `0xBA (186)⚠` | `0x51 (81)` | `0x51 (81)` | `0xBA (186)⚠` | `0x51 (81)` | `0x51 (81)` | `0xBA (186)⚠` | `0x51 (81)` | `0x51 (81)` | `0x51 (81)` | `0xBA (186)⚠` | `0x51 (81)` |
| `"KeyR"` | `0x52 (82)` | `0x52 (82)` | `0x52 (82)` | `0x52 (82)` | `0x52 (82)` | `0x52 (82)` | `0x52 (82)` | `0x52 (82)` |
| `"KeyS"` | `0x53 (83)` | `0x53 (83)` | `0x53 (83)` | `0x53 (83)` | `0x53 (83)` | `0x53 (83)` | `0x53 (83)` | `0x53 (83)` |
| `"KeyT"` | `0x54 (84)` | `0x54 (84)` | `0x54 (84)` | `0x54 (84)` | `0x54 (84)` | `0x54 (84)` | `0x54 (84)` | `0x54 (84)` |
| `"KeyU"` | `0x55 (85)` | `0x55 (85)` | `0x55 (85)` | `0x55 (85)` | `0x55 (85)` | `0x55 (85)` | `0x55 (85)` | `0x55 (85)` |
| `"KeyV"` | `0x56 (86)` | `0x56 (86)` | `0x56 (86)` | `0x56 (86)` | `0x56 (86)` | `0x56 (86)` | `0x56 (86)` | `0x56 (86)` |
| `"KeyW"` | `0x57 (87)` | `0x57 (87)` | `0x57 (87)` | `0x57 (87)` | `0x57 (87)` | `0x57 (87)` | `0x57 (87)` | `0x57 (87)` |
| `"KeyX"` | `0x58 (88)` | `0x58 (88)` | `0x58 (88)` | `0x58 (88)` | `0x58 (88)` | `0x58 (88)` | `0x58 (88)` | `0x58 (88)` |
| `"KeyY"` | `0x59 (89)` | `0x59 (89)` | `0x59 (89)` | `0x59 (89)` | `0x59 (89)` | `0x59 (89)` | `0x59 (89)` | `0x59 (89)` |
| `"KeyZ"` | `0x5A (90)` | `0x5A (90)` | `0x5A (90)` | `0x5A (90)` | `0x5A (90)` | `0x5A (90)` | `0x5A (90)` | `0x5A (90)` |
| `KeyboardEvent.code` | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| Internet Explorer 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |

 keyCode values of each browser's keydown event caused by printable keys in
 standard position (punctuations in US layout):
 | `KeyboardEvent.code` | IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |
| --- | --- | --- | --- | --- | --- |
|  | Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows (10.9) | Mac (10.9) | Linux (Ubuntu 14.04) |
|  | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek |
| `"Comma"` | `0xBC (188)` | `0xBC (188)` | `0xBC (188)` | `0xBC (188)` | `0xBC (188)` | `0xBC (188)` | `0xBC (188)` | `0xBC (188)` |
| `"Comma"` with `Shift` |
| `"Period"` | `0xBE (190)` | `0xBE (190)` | `0xBE (190)` | `0xBE (190)` | `0xBE (190)` | `0xBE (190)` | `0xBE (190)` | `0xBE (190)` |
| `"Period"` with `Shift` |
| `"Semicolon"` | `0xBA (186)` | `0xBB (187)`⚠ | `0xBA (186)` | `0xBA (186)` | `0xBB (187)`⚠ | `0xBA (186)` | `0xBA (186)` | `0xBA (186)` [1] | `0xE5 (229)`⚠ [2] | `0xBA (186)` | `0xBA (186)` | `0xE5 (229)`⚠ [3] | `0xBA (186)` | `0xBA (186)` [1] | `0xE5 (229)`⚠ [2] | `0x3B (59)` | `0x3B (59)` | `0x00 (0)`⚠ | `0x3B (59)` | `0x3B (59)` [1] | `0x00 (0)`⚠ | `0x3B (59)` | `0x3B (59)` | `0x00 (0)`⚠ |
| `"Semicolon"` with `Shift` | `0xBB (187)`⚠ [1] | `0xBB (187)`⚠ | `0xBB (187)`⚠ [1] |
| `"Quote"` | `0xDE (222)` | `0xBA (186)`⚠ | `0xDE (222)` | `0xDE (222)` | `0xBA (186)`⚠ | `0xDE (222)` | `0xDE (222)` | `0xBA (186)`⚠ [1] | `0xDE (222)` | `0xDE (222)` | `0xBA (186)`⚠ | `0xDE (222)` | `0xDE (222)` | `0xBA (186)`⚠ [1] | `0xDE (222)` | `0xDE (222)` | `0x3A (58)`⚠ | `0xDE (222)` | `0xDE (222)` | `0x3A (58)`⚠ [1] | `0xDE (222)` | `0xDE (222)` | `0x3A (58)`⚠ | `0xDE (222)` |
| `"Quote"` with Shift | `0xDE (222)`⚠ [1] | `0x38 (56)`⚠ | `0xDE (222)`⚠ [1] |
| `"BracketLeft"` | `0xDB (219)` | `0xC0(192)`⚠ | `0xDB (219)` | `0xDB (219)` | `0xC0(192)`⚠ | `0xDB (219)` | `0xDB (219)` | `0xDB (219)` [1] | `0xDB (219)` | `0xDB (219)` | `0x32 (50)`⚠ | `0xDB (219)` | `0xDB (219)` | `0xDB (219)` [1] | `0xDB (219)` | `0xDB (219)` | `0x40 (64)`⚠ | `0xDB (219)` | `0xDB (219)` | `0x40 (64)`⚠ [1] | `0xDB (219)` | `0xDB (219)` | `0x40 (64)`⚠ | `0xDB (219)` |
| `"BracketLeft"` with `Shift` | `0xC0 (192)`⚠ [1] | `0xC0 (192)`⚠ | `0xC0 (192)`⚠ [1] |
| `"BracketRight"` | `0xDD (221)` | `0xDB (219)`⚠ | `0xDD (221)` | `0xDD (221)` | `0xDB (219)`⚠ | `0xDD (221)` | `0xDD (221)` | `0xDB (219)`⚠ [1] | `0xDD (221)` | `0xDD (221)` | `0xDB (219)`⚠ | `0xDD (221)` | `0xDD (221)` | `0xDB (219)`⚠ [1] | `0xDD (221)` | `0xDD (221)` | `0xDB (219)`⚠ | `0xDD (221)` | `0xDD (221)` | `0xDB (219)`⚠ [1] | `0xDD (221)` | `0xDD (221)` | `0xDB (219)`⚠ | `0xDD (221)` |
| `"BracketRight"` with `Shift` |
| `"Backquote"` | `0xC0 (192)` | `❌ N/A` | `0xC0 (192)` | `0xC0 (192)` | `❌ N/A` | `0xC0 (192)` | `0xC0 (192)` | `0xC0 (192)` | `0xF4 (244)`⚠ | `0xC0 (192)` | `0xC0 (192)` | `0xC0 (192)` | `❌ N/A` | `0xC0 (192)` | `0xC0 (192)` | `0xC0 (192)` | `0x00 (0)` | `0xC0 (192)` |
| `"Backquote"` with `Shift` |
| `"Backslash"` | `0xDC (220)` | `0xDD (221)`⚠ | `0xDC (220)` | `0xDC (220)` | `0xDD (221)`⚠ | `0xDC (220)` | `0xDC (220)` | `0xDC (220)` | `0xDD (221)`⚠ | `0xDC (220)` | `0xDC (220)` | `0xDC (220)` | `0xDD (221)`⚠ | `0xDC (220)` | `0xDC (220)` | `0xDC (220)` | `0xDD (221)`⚠ | `0xDC (220)` |
| `"Backslash"` with `Shift` |
| `"Minus"` | `0xBD (189)` | `0xBD (189)` | `0xBD (189)` | `0xBD (189)` [1] | `0xBD (189)` | `0xBD (189)` | `0xBD (189)` | `0xBD (189)` | `0xBD (189)` | `0xBD (189)` [1] | `0xBD (189)` | `0xAD (173)` | `0xAD (173)` | `0xAD (173)`[1] | `0xAD (173)` | `0xAD (173)` |
| `"Minus"` with `Shift` | `0xBB (187)`⚠ [1] | `0xBB (187)`⚠ | `0xBD (189)` | `0xBB (187)`⚠ [1] | `0xBD (189)` |
| `"Equal"` | `0xBB (187)` | `0xDE (222)`⚠ | `0xBB (187)` | `0xBB (187)` | `0xDE (222)`⚠ | `0xBB (187)` | `0xBB (187)` | `0xBB (187)` [1] | `0xBB (187)` | `0xBB (187)` | `0x36 (54)`⚠ | `0xBB (187)` | `0xBB (187)` | `0xBB (187)`[1] | `0xBB (187)` | `0x3D (61)` | `0xA0 (160)`⚠ | `0x3D (61)` | `0x3D (61)` | `0xA0 (160)`⚠ [1] | `0x3D (61)` | `0x3D (61)` | `0xA0 (160)`⚠ | `0x3D (61)` |
| `"Equal"` with `Shift` | `0xC0 (192)`⚠ [1] | `0xC0 (192)`⚠ | `0xBB (187)` | `0xC0 (192)`⚠ [1] | `0xBB (187)` |
| `"IntlRo"` | `0xC1 (193)` | `0xE2 (226)`⚠ | `0xC1 (193)` | `0xC1 (193)` | `0xE2 (226)`⚠ | `0xC1 (193)` | `0xBD (189)` | `0xBD (189)` | `0x00 (0)`⚠ | [4] | `0xDC (220)`⚠ | [4] | `0xBD (189)` | `0xBD (189)` | `0xE5 (229)`⚠ [5] | `0x00 (0)` | `0xDC (220)`⚠ | `0x00 (0)` | `0xA7 (167)` | `0xA7 (167)` | `0x00 (0)` | `0x00 (0)` | `0xDC (220)`⚠ | `0x00 (0)` |
| `"IntlRo"` with `Shift` |
| `"IntlYen"` | `0xFF (255)` | `0xDC (220)`⚠ | `0xFF (255)` | `0xFF (255)` | `0xDC (220)`⚠ | `0xFF (255)` | `0x00 (0)`⚠ | `0x00 (0)`⚠ | `0x00 (0)`⚠ | [4] | `0xDC (220)`⚠ | [4] | `0x00 (0)`⚠ | `0x00 (0)`⚠ | `0xE5 (229)`⚠ [5] | `0x00 (0)`⚠ | `0xDC (220)`⚠ | `0x00 (0)`⚠ | `0xDC` (220) | `0xDC` (220) | `0x00 (0)`⚠ | `0x00 (0)`⚠ | `0xDC (220)`⚠ | `0x00 (0)`⚠ |
| `"IntlYen"` with `Shift` | `0xDC (220)` | `0xDC (220)` | `0xBD (189)`⚠ | `0xDC (220)` | `0xDC (220)` |
| `KeyboardEvent.code` | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek | US | Japanese | Greek |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| Internet Explorer 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |

[1] The value is input from JIS keyboard. When you use ANSI keyboard, the keyCode value and inputted character are what you select from the US keyboard layout.

[2] The key is a dead key. The value of `keyup` event is `0xBA (186)`.

[3] The key is a dead key. The value of `keyup` event is `0x10 (16)`.

[4] No key events are fired.

[5] The key isn't available with Greek keyboard layout (does not input any character). The value of `keyup` event is `0x00 (0)`.

### Non-printable keys (function keys)

keyCode values of each browser's keydown event caused by modifier keys:| `KeyboardEvent.code` | IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |
| --- | --- | --- | --- | --- | --- |
| Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| `"AltLeft"` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` |
| `"AltRight"` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` | `0x12 (18)` |
| `"AltRight"` when it's `"AltGraph"` key | [1] | [1] | ❌N/A | `0xE1 (225)`⚠ | ❌ N/A | [1] | ❌ N/A | `0xE1 (225)`⚠ |
| `"CapsLock"` | `0x14 (20)` [2] | `0x14 (20)` [2] | `0x14 (20)` | `0x14 (20)` | `0x14 (20)` | `0x14 (20)` [2] | `0x14 (20)` | `0x14 (20)` [3] |
| `"ControlLeft"` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` |
| `"ControlRight"` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` | `0x11 (17)` |
| `"MetaLeft"` | `0x5B (91)` | `0x5B (91)` | `0x5B (91)` | `0x5B (91)` | `0x5B (91)` | `0x5B (91)` | `0xE0 (224)`⚠ | `0x5B (91)` |
| `"MetaRight"` | `0x5C (92)` | `0x5C (92)` | `0x5D (93)`⚠ | `0x5C (92)` | `0x5D (93)`⚠ | `0x5B (91)`⚠ | `0xE0 (224)`⚠ | `0x5B (91)`⚠ |
| `"ShiftLeft"` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` |
| `"ShiftRight"` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` | `0x10 (16)` |
| `KeyboardEvent.code` | Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |

[1] On Windows, pressing the `AltGraph` key raises both the `"ControlLeft"` and the `"AltRight"` key events.

[2] When the Japanese keyboard layout is active, pressing the `CapsLock` key without pressing `Shift` raises `0xF0 (240)`. The key works as the `Alphanumeric` key whose label is `"英数"`.

[3] When the Japanese keyboard layout is active, pressing the `"CapsLock"` key without pressing `Shift` raises `0x00 (0)`. The key works as the `"Alphanumeric"` key whose label is `"英数"`.

keyCode values of each browser's keydown event caused by non-printable keys:| `KeyboardEvent.code` | IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |
| --- | --- | --- | --- | --- | --- |
| Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| `"ContextMenu"` | `0x5D (93)` | `0x5D (93)` | `0x00 (0)`⚠ [1] | `0x5D (93)` | `0x00 (0)`⚠ [1] | `0x5D (93)` | `0x5D (93)` | `0x5D (93)` |
| `"Enter"` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` |
| `"Space"` | `0x20 (32)` | `0x20 (32)` | `0x20 (32)` | `0x20 (32)` | `0x20 (32)` | `0x20 (32)` | `0x20 (32)` | `0x20 (32)` |
| `"Tab"` | `0x09 (9)` | `0x09 (9)` | `0x09 (9)` | `0x09 (9)` | `0x09 (9)` | `0x09 (9)` | `0x09 (9)` | `0x09 (9)` |
| `"Delete"` | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` |
| `"End"` | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` |
| `"Help"` | ❌ N/A | ❌ N/A | `0x2D (45)`⚠ [2] | `0x2F (47)`⚠ [3] | `0x2D (45)`⚠ [2] | ❌ N/A | `0x2D (45)`⚠ [2] | `0x06 (6)`⚠ [3] |
| `"Home"` | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` |
| `"Insert"` | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` |
| `"PageDown"` | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` |
| `"PageUp"` | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` |
| `"ArrowDown"` | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` |
| `"ArrowLeft"` | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` |
| `"ArrowRight"` | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` |
| `"ArrowUp"` | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` |
| `"Escape"` | `0x1B (27)` | `0x1B (27)` | `0x1B (27)` | `0x1B (27)` | `0x1B (27)` | `0x1B (27)` | `0x1B (27)` | `0x1B (27)` |
| `"PrintScreen"` | `0x2C (44)` [4] | `0x2C (44)` [4] | `0x7C (124)`⚠ [5] | `0x2A (42)`⚠ | `0x7C (124)`⚠ [5] | `0x2C (44)` [4] | `0x2C (44)` | `0x2A (42)`⚠ |
| `"ScrollLock"` | `0x91 (145)` | `0x91 (145)` | `0x7D (125)`⚠ [5] | `0x91 (145)` | `0x7D (125)`⚠ [5] | `0x91 (145)` | `0x91 (145)` | `0x91 (145)` |
| `"Pause"` | `0x13 (19)` [6] | `0x13 (19)` [6] | `0x7E (126)`⚠ [5] | `0x13 (19)` | `0x7E (126)`⚠ [5] | `0x13 (19)` [6] | `0x13 (19)` | `0x13 (19)` |
| `KeyboardEvent.code` | Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |

[1] A `keypress` event is fired and its `keyCode` and `charCode` are `0x10 (16)` but the text isn't actually entered into the editor.

[2] On Mac, the `Help` key is mapped to the `Insert` key of PC keyboards. These `keyCode` values are the same as the `Insert` key's `keyCode` values.

[3] Tested on Fedora 20.

[4] Only a `keyup` event is fired.

[5] PC's `PrintScreen`, `ScrollLock` and `Pause` are mapped to Mac's `F13`, `F14` and `F15`, respectively. Chrome and Safari map them to the same `keyCode` values as Mac's keys.

[6] `Pause` key with `Control` generates `0x03 (3)`.

keyCode values of each browser's keydown event caused by function keys:| `KeyboardEvent.code` | IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |
| --- | --- | --- | --- | --- | --- |
| Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| `"F1"` | `0x70 (112)` | `0x70 (112)` | `0x70 (112)` | `0x70 (112)` | `0x70 (112)` | `0x70 (112)` | `0x70 (112)` | `0x70 (112)` |
| `"F2"` | `0x71 (113)` | `0x71 (113)` | `0x71 (113)` | `0x71 (113)` | `0x71 (113)` | `0x71 (113)` | `0x71 (113)` | `0x71 (113)` |
| `"F3"` | `0x72 (114)` | `0x72 (114)` | `0x72 (114)` | `0x72 (114)` | `0x72 (114)` | `0x72 (114)` | `0x72 (114)` | `0x72 (114)` |
| `"F4"` | `0x73 (115)` | `0x73 (115)` | `0x73 (115)` | `0x73 (115)` | `0x73 (115)` | `0x73 (115)` | `0x73 (115)` | `0x73 (115)` |
| `"F5"` | `0x74 (116)` | `0x74 (116)` | `0x74 (116)` | `0x74 (116)` | `0x74 (116)` | `0x74 (116)` | `0x74 (116)` | `0x74 (116)` |
| `"F6"` | `0x75 (117)` | `0x75 (117)` | `0x75 (117)` | `0x75 (117)` | `0x75 (117)` | `0x75 (117)` | `0x75 (117)` | `0x75 (117)` |
| `"F7"` | `0x76 (118)` | `0x76 (118)` | `0x76 (118)` | `0x76 (118)` | `0x76 (118)` | `0x76 (118)` | `0x76 (118)` | `0x76 (118)` |
| `"F8"` | `0x77 (119)` | `0x77 (119)` | `0x77 (119)` | `0x77 (119)` | `0x77 (119)` | `0x77 (119)` | `0x77 (119)` | `0x77 (119)` |
| `"F9"` | `0x78 (120)` | `0x78 (120)` | `0x78 (120)` | `0x78 (120)` | `0x78 (120)` | `0x78 (120)` | `0x78 (120)` | `0x78 (120)` |
| `"F10"` | `0x79 (121)` | `0x79 (121)` | `0x79 (121)` | `0x79 (121)` | `0x79 (121)` | `0x79 (121)` | `0x79 (121)` | `0x79 (121)` |
| `"F11"` | `0x7A (122)` | `0x7A (122)` | `0x7A (122)` | `0x7A (122)` | `0x7A (122)` | `0x7A (122)` | `0x7A (122)` | `0x7A (122)` |
| `"F12"` | `0x7B (123)` | `0x7B (123)` | `0x7B (123)` | `0x7B (123)` | `0x7B (123)` | `0x7B (123)` | `0x7B (123)` | `0x7B (123)` |
| `"F13"` | `0x7C (124)` | `0x7C (124)` | `0x7C (124)` | `0x7C (124)` [1] | `0x7C (124)` | `0x7C (124)` | `0x2C (44)` ⚠ [2] | `0x00 (0)`⚠ [3] |
| `"F14"` | `0x7D (125)` | `0x7D (125)` | `0x7D (125)` | `0x7D (125)` [1] | `0x7D (125)` | `0x7D (125)` | `0x91 (145)` ⚠ [2] | `0x00 (0)`⚠ [3] |
| `"F15"` | `0x7E (126)` | `0x7E (126)` | `0x7E (126)` | `0x7E (126)` [1] | `0x7E (126)` | `0x7E (126)` | `0x13 (19)` ⚠ [2] | `0x00 (0)`⚠ [3] |
| `"F16"` | `0x7F (127)` | `0x7F (127)` | `0x7F (127)` | `0x7F (127)` [1] | `0x7F (127)` | `0x7F (127)` | `0x7F (127)` | `0x00 (0)`⚠ [3] |
| `"F17"` | `0x80 (128)` | `0x80 (128)` | `0x80 (128)` | `0x80 (128)` [1] | `0x80 (128)` | `0x80 (128)` | `0x80 (128)` | `0x00 (0)`⚠ [3] |
| `"F18"` | `0x81 (129)` | `0x81 (129)` | `0x81 (129)` | `0x81 (129)` [1] | `0x81 (129)` | `0x81 (129)` | `0x81 (129)` | `0x00 (0)`⚠ [3] |
| `"F19"` | `0x82 (130)` | `0x82 (130)` | `0x82 (130)` | ❌ `N/A` [4] | `0x82 (130)` | `0x82 (130)` | `0x82 (130)` | `0x00 (0)`⚠ [3] |
| `"F20"` | `0x83 (131)` | `0x83 (131)` | `0x83 (131)` | ❌ `N/A` [4] | `0xE5 (229)`⚠ [5] | `0x83 (131)` | `0x00 (0)`⚠ | ❌ `N/A` [6] |
| `"F21"` | `0x84 (132)` | `0x84 (132)` | `0x00 (0)`⚠ [7] | ❌ `N/A` [4] | `0x00 (0)`⚠ [7] | `0x84 (132)` | ❌ `N/A` [8] | ❌ `N/A` [6] |
| `"F22"` | `0x85 (133)` | `0x85 (133)` | `0x00 (0)`⚠ [7] | ❌ `N/A` [4] | `0x00 (0)`⚠ [7] | `0x85 (133)` | ❌ `N/A` [8] | ❌ `N/A` [6] |
| `"F23"` | `0x86 (134)` | `0x86 (134)` | `0x00 (0)`⚠ [7] | ❌ `N/A` [4] | `0x00 (0)`⚠ [7] | `0x86 (134)` | ❌ `N/A` [8] | ❌ `N/A` [6] |
| `"F24"` | `0x87 (135)` | `0x87 (135)` | `0x00 (0)`⚠ [7] | ❌ `N/A` [4] | `0x00 (0)`⚠ [7] | `0x87 (135)` | ❌ `N/A` [8] | `0x00 (0)`⚠ [3] |
| `KeyboardEvent.code` | Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |

[1] Tested on Fedora 20.

[2] On PCs, `PrintScreen`, `ScrollLock` and `Pause` are mapped to the Mac's `F13`, `F14` and `F15`, respectively. Firefox sets for them the same `keyCode` values as the PC's keys.

[3] Tested on Fedora 20. The keys don't cause `GDK_Fxx` keysyms. If the keys cause proper keysyms, these values must be same as IE.

[4] Tested on Fedora 20. The keys don't cause DOM key events on Chromium.

[5] The `keyCode` value of a `keyUp` event is `0x83 (131)`.

[6] Tested on Fedora 20. The keys don't cause DOM key events on Firefox.

[7] Only the `keydown` event is fired.

[8] No DOM key events are fired on Firefox.

### Numpad keys

 keyCode values of each browser's keydown event caused by keys in numpad in
 NumLock state
 | `KeyboardEvent.code` | IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |
| --- | --- | --- | --- | --- | --- |
| Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| `"NumLock"` | `0x90 (144)` | `0x90 (144)` | `0x0C (12)`⚠ [1] | `0x90 (144)` | `0x0C (12)`⚠ [1] | `0x90 (144)` | `0x0C (12)`⚠ [1] | `0x90 (144)` |
| `"Numpad0"` | `0x60 (96)` | `0x60 (96)` | `0x60 (96)` | `0x60 (96)` | `0x60 (96)` | `0x60 (96)` | `0x60 (96)` | `0x60 (96)` |
| `"Numpad1"` | `0x61 (97)` | `0x61 (97)` | `0x61 (97)` | `0x61 (97)` | `0x61 (97)` | `0x61 (97)` | `0x61 (97)` | `0x61 (97)` |
| `"Numpad2"` | `0x62 (98)` | `0x62 (98)` | `0x62 (98)` | `0x62 (98)` | `0x62 (98)` | `0x62 (98)` | `0x62 (98)` | `0x62 (98)` |
| `"Numpad3"` | `0x63 (99)` | `0x63 (99)` | `0x63 (99)` | `0x63 (99)` | `0x63 (99)` | `0x63 (99)` | `0x63 (99)` | `0x63 (99)` |
| `"Numpad4"` | `0x64 (100)` | `0x64 (100)` | `0x64 (100)` | `0x64 (100)` | `0x64 (100)` | `0x64 (100)` | `0x64 (100)` | `0x64 (100)` |
| `"Numpad5"` | `0x65 (101)` | `0x65 (101)` | `0x65 (101)` | `0x65 (101)` | `0x65 (101)` | `0x65 (101)` | `0x65 (101)` | `0x65 (101)` |
| `"Numpad6"` | `0x66 (102)` | `0x66 (102)` | `0x66 (102)` | `0x66 (102)` | `0x66 (102)` | `0x66 (102)` | `0x66 (102)` | `0x66 (102)` |
| `"Numpad7"` | `0x67 (103)` | `0x67 (103)` | `0x67 (103)` | `0x67 (103)` | `0x67 (103)` | `0x67 (103)` | `0x67 (103)` | `0x67 (103)` |
| `"Numpad8"` | `0x68 (104)` | `0x68 (104)` | `0x68 (104)` | `0x68 (104)` | `0x68 (104)` | `0x68 (104)` | `0x68 (104)` | `0x68 (104)` |
| `"Numpad9"` | `0x69 (105)` | `0x69 (105)` | `0x69 (105)` | `0x69 (105)` | `0x69 (105)` | `0x69 (105)` | `0x69 (105)` | `0x69 (105)` |
| `"NumpadAdd"` | `0x6B (107)` | `0x6B (107)` | `0x6B (107)` | `0x6B (107)` | `0x6B (107)` | `0x6B (107)` | `0x6B (107)` | `0x6B (107)` |
| `"NumpadComma"` inputting `","` | `0xC2 (194)` | `0xC2 (194)` | `0xBC (188)`⚠ | ❌ *Always inputs* `"."` | `0xBC (188)`⚠ | `0xC2 (194)` | `0x6C (108)`⚠ | ❌ *Always inputs* `"."` |
| `"NumpadComma"` inputting `"."` or empty string | `0xC2 (194)` | `0xC2 (194)` | `0xBE (190)`⚠ | `0x6E (110)`⚠ | `0xBE (190)`⚠ | `0xC2 (194)` | `0x6C (108)`⚠ | `0x6E (110)`⚠ |
| `"NumpadDecimal"` inputting `"."` | `0x6E (110)` | `0x6E (110)` | `0x6E (110)` | `0x6E (110)` | `0x6E (110)` | `0x6E (110)` | `0x6E (110)` | `0x6E (110)` |
| `"NumpadDecimal"` inputting `","` | `0x6E (110)` | `0x6E (110)` | `0x6E (110)` | `0x6C (108)`⚠ | `0x6E (110)` | `0x6E (110)` | `0x6E (110)` | `0x6C (108)`⚠ |
| `"NumpadDivide"` | `0x6F (111)` | `0x6F (111)` | `0x6F (111)` | `0x6F (111)` | `0x6F (111)` | `0x6F (111)` | `0x6F (111)` | `0x6F (111)` |
| `"NumpadEnter"` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` | `0x0D (13)` |
| `"NumpadEqual"` | `0x0C (12)` | `0x0C (12)` | `0xBB (187)`⚠ | `0xBB (187)`⚠ | `0xBB (187)`⚠ | `0x0C (12)` | `0x3D (61)`⚠ | `0x3D (61)`⚠ |
| `"NumpadMultiply"` | `0x6A (106)` | `0x6A (106)` | `0x6A (106)` | `0x6A (106)` | `0x6A (106)` | `0x6A (106)` | `0x6A (106)` | `0x6A (106)` |
| `"NumpadSubtract"` | `0x6D (109)` | `0x6D (109)` | `0x6D (109)` | `0x6D (109)` | `0x6D (109)` | `0x6D (109)` | `0x6D (109)` | `0x6D (109)` |
| `KeyboardEvent.code` | Windows | Windows | Mac (10.9) | Linux (Ubuntu 14.04) | Mac (10.9) | Windows | Mac (10.9) | Linux (Ubuntu 14.04) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| IE 11 | Google Chrome 34 | Chromium 34 | Safari 7 | Gecko 29 |

[1] `"NumLock"` key works as `"Clear"` key on Mac.

 keyCode values of each browser's keydown event caused by keys in numpad
 without NumLock state
 | `KeyboardEvent.code` | IE 11 | Google Chrome 34 | Chromium 34 | Gecko 29 |
| --- | --- | --- | --- | --- |
| Windows | Windows | Linux (Ubuntu 14.04) | Windows | Linux (Ubuntu 14.04) |
| `"Numpad0"` (`"Insert"`) | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` | `0x2D (45)` |
| `"Numpad1"` (`"End"`) | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` | `0x23 (35)` |
| `"Numpad2"` (`"ArrowDown"`) | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` | `0x28 (40)` |
| `"Numpad3"` (`"PageDown"`) | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` | `0x22 (34)` |
| `"Numpad4"` (`"ArrowLeft"`) | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` | `0x25 (37)` |
| `"Numpad5"` | `0x0C (12)` | `0x0C (12)` | `0x0C (12)` | `0x0C (12)` | `0x0C (12)` |
| `"Numpad6"` (`"ArrowRight"`) | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` | `0x27 (39)` |
| `"Numpad7"` (`"Home"`) | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` | `0x24 (36)` |
| `"Numpad8"` (`"ArrowUp"`) | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` | `0x26 (38)` |
| `"Numpad9"` (`"PageUp"`) | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` | `0x21 (33)` |
| `"NumpadDecimal"` (`"Delete"`) | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` | `0x2E (46)` |
| `KeyboardEvent.code` | Windows | Windows | Linux (Ubuntu 14.04) | Windows | Linux (Ubuntu 14.04) |
| --- | --- | --- | --- | --- | --- |
| IE 11 | Google Chrome 34 | Chromium 34 | Gecko 29 |

**Note:** Recent Mac doesn't have a `NumLock` key, and therefore state. That's why the unlocked state is not available.

Constants for keyCode value
---------------------------

Gecko defines a lot of `keyCode` values in `KeyboardEvent` for making the mapping table explicitly. These values are useful for add-on developers of Firefox, but not so useful in public web pages.

| Constant | Value | Description |
| --- | --- | --- |
| `DOM_VK_CANCEL` | 0x03 (3) | Cancel key. |
| `DOM_VK_HELP` | 0x06 (6) | Help key. |
| `DOM_VK_BACK_SPACE` | 0x08 (8) | Backspace key. |
| `DOM_VK_TAB` | 0x09 (9) | Tab key. |
| `DOM_VK_CLEAR` | 0x0C (12) |
 "5" key on Numpad when NumLock is unlocked. Or on Mac, clear key which
 is positioned at NumLock key.
  |
| `DOM_VK_RETURN` | 0x0D (13) | Return/enter key on the main keyboard. |
| `DOM_VK_ENTER` | 0x0E (14) |
 Reserved, but not used.
Deprecated
 (Dropped, see
 [Firefox bug 969247](https://bugzil.la/969247).)
  |
| `DOM_VK_SHIFT` | 0x10 (16) | Shift key. |
| `DOM_VK_CONTROL` | 0x11 (17) | Control key. |
| `DOM_VK_ALT` | 0x12 (18) | Alt (Option on Mac) key. |
| `DOM_VK_PAUSE` | 0x13 (19) | Pause key. |
| `DOM_VK_CAPS_LOCK` | 0x14 (20) | Caps lock. |
| `DOM_VK_KANA` | 0x15 (21) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_HANGUL` | 0x15 (21) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_EISU` | 0x 16 (22) | "英数" key on Japanese Mac keyboard. |
| `DOM_VK_JUNJA` | 0x17 (23) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_FINAL` | 0x18 (24) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_HANJA` | 0x19 (25) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_KANJI` | 0x19 (25) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_ESCAPE` | 0x1B (27) | Escape key. |
| `DOM_VK_CONVERT` | 0x1C (28) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_NONCONVERT` | 0x1D (29) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_ACCEPT` | 0x1E (30) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_MODECHANGE` | 0x1F (31) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_SPACE` | 0x20 (32) | Space bar. |
| `DOM_VK_PAGE_UP` | 0x21 (33) | Page Up key. |
| `DOM_VK_PAGE_DOWN` | 0x22 (34) | Page Down key. |
| `DOM_VK_END` | 0x23 (35) | End key. |
| `DOM_VK_HOME` | 0x24 (36) | Home key. |
| `DOM_VK_LEFT` | 0x25 (37) | Left arrow. |
| `DOM_VK_UP` | 0x26 (38) | Up arrow. |
| `DOM_VK_RIGHT` | 0x27 (39) | Right arrow. |
| `DOM_VK_DOWN` | 0x28 (40) | Down arrow. |
| `DOM_VK_SELECT` | 0x29 (41) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_PRINT` | 0x2A (42) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_EXECUTE` | 0x2B (43) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_PRINTSCREEN` | 0x2C (44) | Print Screen key. |
| `DOM_VK_INSERT` | 0x2D (45) | Ins(ert) key. |
| `DOM_VK_DELETE` | 0x2E (46) | Del(ete) key. |
| `DOM_VK_0` | 0x30 (48) | "0" key in standard key location. |
| `DOM_VK_1` | 0x31 (49) | "1" key in standard key location. |
| `DOM_VK_2` | 0x32 (50) | "2" key in standard key location. |
| `DOM_VK_3` | 0x33 (51) | "3" key in standard key location. |
| `DOM_VK_4` | 0x34 (52) | "4" key in standard key location. |
| `DOM_VK_5` | 0x35 (53) | "5" key in standard key location. |
| `DOM_VK_6` | 0x36 (54) | "6" key in standard key location. |
| `DOM_VK_7` | 0x37 (55) | "7" key in standard key location. |
| `DOM_VK_8` | 0x38 (56) | "8" key in standard key location. |
| `DOM_VK_9` | 0x39 (57) | "9" key in standard key location. |
| `DOM_VK_COLON` | 0x3A (58) | Colon (":") key. |
| `DOM_VK_SEMICOLON` | 0x3B (59) | Semicolon (";") key. |
| `DOM_VK_LESS_THAN` | 0x3C (60) | Less-than ("<") key. |
| `DOM_VK_EQUALS` | 0x3D (61) | Equals ("=") key. |
| `DOM_VK_GREATER_THAN` | 0x3E (62) | Greater-than (">") key. |
| `DOM_VK_QUESTION_MARK` | 0x3F (63) | Question mark ("?") key. |
| `DOM_VK_AT` | 0x40 (64) | Atmark ("@") key. |
| `DOM_VK_A` | 0x41 (65) | "A" key. |
| `DOM_VK_B` | 0x42 (66) | "B" key. |
| `DOM_VK_C` | 0x43 (67) | "C" key. |
| `DOM_VK_D` | 0x44 (68) | "D" key. |
| `DOM_VK_E` | 0x45 (69) | "E" key. |
| `DOM_VK_F` | 0x46 (70) | "F" key. |
| `DOM_VK_G` | 0x47 (71) | "G" key. |
| `DOM_VK_H` | 0x48 (72) | "H" key. |
| `DOM_VK_I` | 0x49 (73) | "I" key. |
| `DOM_VK_J` | 0x4A (74) | "J" key. |
| `DOM_VK_K` | 0x4B (75) | "K" key. |
| `DOM_VK_L` | 0x4C (76) | "L" key. |
| `DOM_VK_M` | 0x4D (77) | "M" key. |
| `DOM_VK_N` | 0x4E (78) | "N" key. |
| `DOM_VK_O` | 0x4F (79) | "O" key. |
| `DOM_VK_P` | 0x50 (80) | "P" key. |
| `DOM_VK_Q` | 0x51 (81) | "Q" key. |
| `DOM_VK_R` | 0x52 (82) | "R" key. |
| `DOM_VK_S` | 0x53 (83) | "S" key. |
| `DOM_VK_T` | 0x54 (84) | "T" key. |
| `DOM_VK_U` | 0x55 (85) | "U" key. |
| `DOM_VK_V` | 0x56 (86) | "V" key. |
| `DOM_VK_W` | 0x57 (87) | "W" key. |
| `DOM_VK_X` | 0x58 (88) | "X" key. |
| `DOM_VK_Y` | 0x59 (89) | "Y" key. |
| `DOM_VK_Z` | 0x5A (90) | "Z" key. |
| `DOM_VK_WIN` | 0x5B (91) | Windows logo key on Windows. Or Super or Hyper key on Linux. |
| `DOM_VK_CONTEXT_MENU` | 0x5D (93) | Opening context menu key. |
| `DOM_VK_SLEEP` | 0x5F (95) | Linux support for this keycode was added in Gecko 4.0. |
| `DOM_VK_NUMPAD0` | 0x60 (96) | "0" on the numeric keypad. |
| `DOM_VK_NUMPAD1` | 0x61 (97) | "1" on the numeric keypad. |
| `DOM_VK_NUMPAD2` | 0x62 (98) | "2" on the numeric keypad. |
| `DOM_VK_NUMPAD3` | 0x63 (99) | "3" on the numeric keypad. |
| `DOM_VK_NUMPAD4` | 0x64 (100) | "4" on the numeric keypad. |
| `DOM_VK_NUMPAD5` | 0x65 (101) | "5" on the numeric keypad. |
| `DOM_VK_NUMPAD6` | 0x66 (102) | "6" on the numeric keypad. |
| `DOM_VK_NUMPAD7` | 0x67 (103) | "7" on the numeric keypad. |
| `DOM_VK_NUMPAD8` | 0x68 (104) | "8" on the numeric keypad. |
| `DOM_VK_NUMPAD9` | 0x69 (105) | "9" on the numeric keypad. |
| `DOM_VK_MULTIPLY` | 0x6A (106) | "\*" on the numeric keypad. |
| `DOM_VK_ADD` | 0x6B (107) | "+" on the numeric keypad. |
| `DOM_VK_SEPARATOR` | 0x6C (108) |  |
| `DOM_VK_SUBTRACT` | 0x6D (109) | "-" on the numeric keypad. |
| `DOM_VK_DECIMAL` | 0x6E (110) | Decimal point on the numeric keypad. |
| `DOM_VK_DIVIDE` | 0x6F (111) | "/" on the numeric keypad. |
| `DOM_VK_F1` | 0x70 (112) | F1 key. |
| `DOM_VK_F2` | 0x71 (113) | F2 key. |
| `DOM_VK_F3` | 0x72 (114) | F3 key. |
| `DOM_VK_F4` | 0x73 (115) | F4 key. |
| `DOM_VK_F5` | 0x74 (116) | F5 key. |
| `DOM_VK_F6` | 0x75 (117) | F6 key. |
| `DOM_VK_F7` | 0x76 (118) | F7 key. |
| `DOM_VK_F8` | 0x77 (119) | F8 key. |
| `DOM_VK_F9` | 0x78 (120) | F9 key. |
| `DOM_VK_F10` | 0x79 (121) | F10 key. |
| `DOM_VK_F11` | 0x7A (122) | F11 key. |
| `DOM_VK_F12` | 0x7B (123) | F12 key. |
| `DOM_VK_F13` | 0x7C (124) | F13 key. |
| `DOM_VK_F14` | 0x7D (125) | F14 key. |
| `DOM_VK_F15` | 0x7E (126) | F15 key. |
| `DOM_VK_F16` | 0x7F (127) | F16 key. |
| `DOM_VK_F17` | 0x80 (128) | F17 key. |
| `DOM_VK_F18` | 0x81 (129) | F18 key. |
| `DOM_VK_F19` | 0x82 (130) | F19 key. |
| `DOM_VK_F20` | 0x83 (131) | F20 key. |
| `DOM_VK_F21` | 0x84 (132) | F21 key. |
| `DOM_VK_F22` | 0x85 (133) | F22 key. |
| `DOM_VK_F23` | 0x86 (134) | F23 key. |
| `DOM_VK_F24` | 0x87 (135) | F24 key. |
| `DOM_VK_NUM_LOCK` | 0x90 (144) | Num Lock key. |
| `DOM_VK_SCROLL_LOCK` | 0x91 (145) | Scroll Lock key. |
| `DOM_VK_WIN_OEM_FJ_JISHO` | 0x92 (146) |
 An
 OEM specific key on Windows.
 This was used for "Dictionary" key on Fujitsu OASYS.
  |
| `DOM_VK_WIN_OEM_FJ_MASSHOU` | 0x93 (147) |
 An
 OEM specific key on Windows.
 This was used for "Unregister word" key on Fujitsu OASYS.
  |
| `DOM_VK_WIN_OEM_FJ_TOUROKU` | 0x94 (148) |
 An
 OEM specific key on Windows.
 This was used for "Register word" key on Fujitsu OASYS.
  |
| `DOM_VK_WIN_OEM_FJ_LOYA` | 0x95 (149) |
 An
 OEM specific key on Windows.
 This was used for "Left OYAYUBI" key on Fujitsu OASYS.
  |
| `DOM_VK_WIN_OEM_FJ_ROYA` | 0x96 (150) |
 An
 OEM specific key on Windows.
 This was used for "Right OYAYUBI" key on Fujitsu OASYS.
  |
| `DOM_VK_CIRCUMFLEX` | 0xA0 (160) | Circumflex ("^") key. |
| `DOM_VK_EXCLAMATION` | 0xA1 (161) | Exclamation ("!") key. |
| `DOM_VK_DOUBLE_QUOTE` | 0xA2 (162) | Double quote (""") key. |
| `DOM_VK_HASH` | 0xA3 (163) | Hash ("#") key. |
| `DOM_VK_DOLLAR` | 0xA4 (164) | Dollar sign ("$") key. |
| `DOM_VK_PERCENT` | 0xA5 (165) | Percent ("%") key. |
| `DOM_VK_AMPERSAND` | 0xA6 (166) | Ampersand ("&") key. |
| `DOM_VK_UNDERSCORE` | 0xA7 (167) | Underscore ("\_") key. |
| `DOM_VK_OPEN_PAREN` | 0xA8 (168) | Open parenthesis ("(") key. |
| `DOM_VK_CLOSE_PAREN` | 0xA9 (169) | Close parenthesis (")") key. |
| `DOM_VK_ASTERISK` | 0xAA (170) | Asterisk ("\*") key. |
| `DOM_VK_PLUS` | 0xAB (171) | Plus ("+") key. |
| `DOM_VK_PIPE` | 0xAC (172) | Pipe ("|") key. |
| `DOM_VK_HYPHEN_MINUS` | 0xAD (173) | Hyphen-US/docs/Minus ("-") key. |
| `DOM_VK_OPEN_CURLY_BRACKET` | 0xAE (174) | Open curly bracket ("{") key. |
| `DOM_VK_CLOSE_CURLY_BRACKET` | 0xAF (175) | Close curly bracket ("}") key. |
| `DOM_VK_TILDE` | 0xB0 (176) | Tilde ("~") key. |
| `DOM_VK_VOLUME_MUTE` | 0xB5 (181) | Audio mute key. |
| `DOM_VK_VOLUME_DOWN` | 0xB6 (182) | Audio volume down key |
| `DOM_VK_VOLUME_UP` | 0xB7 (183) | Audio volume up key |
| `DOM_VK_COMMA` | 0xBC (188) | Comma (",") key. |
| `DOM_VK_PERIOD` | 0xBE (190) | Period (".") key. |
| `DOM_VK_SLASH` | 0xBF (191) | Slash ("/") key. |
| `DOM_VK_BACK_QUOTE` | 0xC0 (192) | Back tick ("`") key. |
| `DOM_VK_OPEN_BRACKET` | 0xDB (219) | Open square bracket ("[") key. |
| `DOM_VK_BACK_SLASH` | 0xDC (220) | Back slash ("\") key. |
| `DOM_VK_CLOSE_BRACKET` | 0xDD (221) | Close square bracket ("]") key. |
| `DOM_VK_QUOTE` | 0xDE (222) | Quote (''') key. |
| `DOM_VK_META` | 0xE0 (224) | Meta key on Linux, Command key on Mac. |
| `DOM_VK_ALTGR` | 0xE1 (225) | AltGr key (Level 3 Shift key or Level 5 Shift key) on Linux. |
| `DOM_VK_WIN_ICO_HELP` | 0xE3 (227) |
 An
 OEM specific key on Windows.
 This is (was?) used for Olivetti ICO keyboard.
  |
| `DOM_VK_WIN_ICO_00` | 0xE4 (228) |
 An
 OEM specific key on Windows.
 This is (was?) used for Olivetti ICO keyboard.
  |
| `DOM_VK_WIN_ICO_CLEAR` | 0xE6 (230) |
 An
 OEM specific key on Windows.
 This is (was?) used for Olivetti ICO keyboard.
  |
| `DOM_VK_WIN_OEM_RESET` | 0xE9 (233) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_JUMP` | 0xEA (234) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_PA1` | 0xEB (235) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_PA2` | 0xEC (236) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_PA3` | 0xED (237) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_WSCTRL` | 0xEE (238) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_CUSEL` | 0xEF (239) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_ATTN` | 0xF0 (240) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_FINISH` | 0xF1 (241) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_COPY` | 0xF2 (242) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_AUTO` | 0xF3 (243) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_ENLW` | 0xF4 (244) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_WIN_OEM_BACKTAB` | 0xF5 (245) |
 An
 OEM specific key on Windows.
 This was used for Nokia/Ericsson's device.
  |
| `DOM_VK_ATTN` | 0xF6 (246) | Attn (Attention) key of IBM midrange computers, e.g., AS/400. |
| `DOM_VK_CRSEL` | 0xF7 (247) | CrSel (Cursor Selection) key of IBM 3270 keyboard layout. |
| `DOM_VK_EXSEL` | 0xF8 (248) | ExSel (Extend Selection) key of IBM 3270 keyboard layout. |
| `DOM_VK_EREOF` | 0xF9 (249) | Erase EOF key of IBM 3270 keyboard layout. |
| `DOM_VK_PLAY` | 0xFA (250) | Play key of IBM 3270 keyboard layout. |
| `DOM_VK_ZOOM` | 0xFB (251) | Zoom key. |
| `DOM_VK_PA1` | 0xFD (253) | PA1 key of IBM 3270 keyboard layout. |
| `DOM_VK_WIN_OEM_CLEAR` | 0xFE (254) |
 Clear key, but we're not sure the meaning difference from
 `DOM_VK_CLEAR`.
  |

### OEM specific keys on Windows

On Windows, some values of virtual keycode are defined (reserved) for OEM specific key. They are available for special keys on non-standard keyboard. In other words, some values are used for different meaning by two or more vendors (or hardware).

Starting Gecko 21 (and older than 15), OEM specific key values are available on the keyCode attribute only on Windows. So they are not useful for usual web applications. They are useful only for intranet applications or in similar situations.

See "Manufacturer-specific Virtual-Key Codes (Windows CE 5.0)" in MSDN for the detail.


KeyboardEvent: shiftKey property - Web APIs

KeyboardEvent: shiftKey property
================================

 The **`KeyboardEvent.shiftKey`** read-only property is a
 boolean value that indicates if the `shift` key was pressed
 (`true`) or not (`false`) when the event occurred.

Value
-----

A boolean value.

Examples
--------

```html
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>shiftKey example</title>

    <script>
 function showChar(e) {
 alert(
 "Key Pressed: " +
 String.fromCharCode(e.charCode) +
 "\n" +
 "charCode: " +
 e.charCode +
 "\n" +
 "SHIFT key pressed: " +
 e.shiftKey +
 "\n" +
 "ALT key pressed: " +
 e.altKey +
 "\n",
 );
 }
 </script>
  </head>

  <body onkeypress="showChar(event);">
    <p>
      Press any character key, with or without holding down the SHIFT key.<br />
      You can also use the SHIFT key together with the ALT key.
    </p>
  </body>
</html>
```

Specifications
--------------

| Specification |
| --- |
| UI Events # dom-keyboardevent-shiftkey |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `KeyboardEvent`


KeyboardEvent: initKeyEvent() method - Web APIs

KeyboardEvent: initKeyEvent() method
====================================

**Warning:** Do NOT use this method; Use the `KeyboardEvent()` constructor instead!

 The method has been removed from the DOM specification and is not supported by any current browser.
 Firefox hides this method behind the preference (`dom.keyboardevent.init_key_event.enabled`) from version 93 and plans to remove it shortly afterwards.

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. 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 time.

 The **`KeyboardEvent.initKeyEvent()`** method is used to
 initialize the value of an event created using
 `document.createEvent` `("KeyboardEvent")`. Events initialized in
 this way must have been created with the
 `document.createEvent` `("KeyboardEvent")` method.
 `initKeyEvent()` must be called to set the event before it is dispatched.

Syntax
------

```js
initKeyEvent (type, bubbles, cancelable, view,
                    ctrlKey, altKey, shiftKey, metaKey,
                    keyCode, charCode)
```

### Parameters

`type`

A string representing the type of event.

`bubbles`

 A boolean value indicating whether the event should bubble up through the
 event chain or not (see bubbles).

`cancelable`

A boolean value indicating whether the event can be canceled (see cancelable).

`view`

Specifies the `UIEvent.view`; this value may be `null`.

`ctrlKey`

 A boolean value that is `true` if the virtual key to be
 generated is a combination of keys containing the `Ctrl` key.

`altKey`

 A boolean value that is `true` if the virtual key to be
 generated is a combination of keys containing the `Alt` key.

`shiftKey`

 A boolean value that is `true` if the virtual key to be generated
 is a combination of keys containing the `Shift`key.

`metaKey`

 A boolean value that is `true` if the virtual key to be
 generated is a combination of keys containing the `Meta` key.

`keyCode`

 An `unsigned long` representing the virtual key code value of the key
 which was pressed, otherwise `0`. See `KeyboardEvent.keyCode` for the list of key codes.

`charCode`

 An `unsigned long` representing the Unicode character associated with
 the pressed key otherwise `0`.

### Return value

None (`undefined`).

Examples
--------

```js
const event = document.createEvent("KeyboardEvent"); // create a key event
// define the event
event.initKeyEvent(
  "keypress", // typeArg,
  true, // canBubbleArg,
  true, // cancelableArg,
  null, // viewArg, Specifies UIEvent.view. This value may be null.
  false, // ctrlKeyArg,
  false, // altKeyArg,
  false, // shiftKeyArg,
  false, // metaKeyArg,
  9, // keyCodeArg,
  0,
); // charCodeArg);

document.getElementById("blah").dispatchEvent(event);
```

Specifications
--------------

 This implementation of keyboard events is based on the key events spec in the early versions of DOM 2 Events, later removed from that spec in favor of
 `KeyboardEvent()` that should be used instead.


KeyboardEvent: code property - Web APIs

KeyboardEvent: code property
============================

The `KeyboardEvent.code` property represents a physical key on the keyboard (as opposed to the character generated by pressing the key). In other words, this property returns a value that isn't altered by keyboard layout or the state of the modifier keys.

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.

This property is useful when you want to handle keys based on their physical positions on the input device rather than the characters associated with those keys; this is especially common when writing code to handle input for games that simulate a gamepad-like environment using keys on the keyboard. Be aware, however, that you can't use the value reported by `KeyboardEvent.code` to determine the character generated by the keystroke, because the keycode's name may not match the actual character that's printed on the key or that's generated by the computer when the key is pressed.

For example, the `code` returned is "`KeyQ`" for the `Q` key on a QWERTY layout keyboard, but the same `code` value also represents the `'` key on Dvorak keyboards and the `A` key on AZERTY keyboards. That makes it impossible to use the value of `code` to determine what the name of the key is to users if they're not using an anticipated keyboard layout.

To determine what character corresponds with the key event, use the `KeyboardEvent.key` property instead.

Value
-----

The code values for Windows, Linux, and macOS are listed on the KeyboardEvent: code values page.

Examples
--------

### Exercising KeyboardEvent

#### HTML

```html
<p>
  Press keys on the keyboard to see what the KeyboardEvent's key and code values
  are for each one.
</p>
<div id="output" tabindex="0"></div>
```

#### CSS

```css
#output {
  font-family: Arial, Helvetica, sans-serif;
  border: 1px solid black;
  width: 95%;
  margin: auto;
}
#output:focus-visible {
  outline: 3px solid dodgerblue;
}
```

#### JavaScript

```js
window.addEventListener(
  "keydown",
  (event) => {
    const p = document.createElement("p");
    p.textContent = `KeyboardEvent: key='${event.key}' | code='${event.code}'`;
    document.getElementById("output").appendChild(p);
    window.scrollTo(0, document.body.scrollHeight);
  },
  true,
);
```

#### Try it out

To ensure that keystrokes go to the sample, click or focus the output box below before pressing keys.

### Handle keyboard events in a game

This example establishes an event listener for `keydown` events that handle keyboard input for a game that uses the typical "WASD" keyboard layout for steering forward, left, backward, and right. This will use the same four keys physically regardless of what the actual corresponding characters are, such as if the user is using an AZERTY keyboard.

#### HTML

```html
<p>Use the WASD (ZQSD on AZERTY) keys to move and steer.</p>
<svg
 xmlns="http://www.w3.org/2000/svg"
 version="1.1"
 class="world"
 tabindex="0">
  <polygon id="spaceship" points="15,0 0,30 30,30" />
</svg>
```

#### CSS

```css
.world {
  margin: 0px;
  padding: 0px;
  background-color: black;
  width: 400px;
  height: 400px;
}
.world:focus-visible {
  outline: 5px solid dodgerblue;
}
#spaceship {
  fill: orange;
  stroke: red;
  stroke-width: 2px;
}
```

#### JavaScript

The first section of the JavaScript code establishes some variables we'll be using. `shipSize` contains the size of the ship the player is moving around, for convenience. `position` is used to track the position of the ship within the play field. `moveRate` is the number of pixels each keystroke moves the ship forward and backward, and `turnRate` is how many degrees of rotation the left and right steering controls apply per keystroke. `angle` is the current amount of rotation applied to the ship in degrees; it starts at 0° (pointing straight up). Finally, `spaceship` is set to refer to the element with the ID `"spaceship"`, which is the SVG polygon representing the ship the player controls.

```js
let shipSize = {
  width: 30,
  height: 30,
};

let position = {
  x: 200,
  y: 200,
};

let moveRate = 9;
let turnRate = 5;

let angle = 0;

let spaceship = document.getElementById("spaceship");
```

Next comes the function `updatePosition()`. This function takes as input the distance the ship is to be moved, where positive is a forward movement and negative is a backward movement. This function computes the new position of the ship given the distance moved and the current direction the ship is facing. It also handles ensuring that the ship wraps across the boundaries of the play field instead of vanishing.

```js
function updatePosition(offset) {
  let rad = angle \* (Math.PI / 180);
  position.x += Math.sin(rad) \* offset;
  position.y -= Math.cos(rad) \* offset;

  if (position.x < 0) {
    position.x = 399;
  } else if (position.x > 399) {
    position.x = 0;
  }

  if (position.y < 0) {
    position.y = 399;
  } else if (position.y > 399) {
    position.y = 0;
  }
}
```

The `refresh()` function handles applying the rotation and position by using an SVG transform.

```js
function refresh() {
  let x = position.x - shipSize.width / 2;
  let y = position.y - shipSize.height / 2;
  let transform = `translate(${x} ${y}) rotate(${angle} 15 15) `;

  spaceship.setAttribute("transform", transform);
}
refresh();
```

Finally, the `addEventListener()` method is used to start listening for `keydown` events, acting on each key by updating the ship position and rotation angle, then calling `refresh()` to draw the ship at its new position and angle.

```js
window.addEventListener(
  "keydown",
  (event) => {
    if (event.defaultPrevented) {
      return; // Do nothing if event already handled
    }

    switch (event.code) {
      case "KeyS":
      case "ArrowDown":
        // Handle "back"
        updatePosition(-moveRate);
        break;
      case "KeyW":
      case "ArrowUp":
        // Handle "forward"
        updatePosition(moveRate);
        break;
      case "KeyA":
      case "ArrowLeft":
        // Handle "turn left"
        angle -= turnRate;
        break;
      case "KeyD":
      case "ArrowRight":
        // Handle "turn right"
        angle += turnRate;
        break;
    }

    refresh();

    if (event.code !== "Tab") {
      // Consume the event so it doesn't get handled twice,
      // as long as the user isn't trying to move focus away
      event.preventDefault();
    }
  },
  true,
);
```

#### Try it out

To ensure that keystrokes go to the sample code, click or focus the black game play field below before pressing keys.

There are several ways this code can be made better. Most real games would watch for `keydown` events, start motion when that happens, and stop the motion when the corresponding `keyup` occurs, instead of relying on key repeats. That would allow both smoother and faster movement, but would also allow the player to be moving and steering at the same time. Transitions or animations could be used to make the ship's movement smoother, too.

Specifications
--------------

| Specification |
| --- |
| UI Events # dom-keyboardevent-code |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


KeyboardEvent: charCode property - Web APIs

KeyboardEvent: charCode property
================================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. 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 time.

 The **`charCode`** read-only property of the
 `KeyboardEvent` interface returns the Unicode value of a character key
 pressed during a `keypress` event.

**Warning:** Do not use this property, as it is deprecated. Instead, get the
 Unicode value of the character using the `key`
 property.

Value
-----

A number that represents the Unicode value of the character key that was pressed.

Examples
--------

### HTML

```html
<p>Type anything into the input box below to log a <code>charCode</code>.</p>
<input type="text" />
<p id="log"></p>
```

### JavaScript

```js
const input = document.querySelector("input");
const log = document.querySelector("#log");

input.addEventListener("keypress", (e) => {
  log.innerText = `Key pressed: ${String.fromCharCode(e.charCode)}\ncharCode: ${
 e.charCode
 }`;
});
```

### Result

Notes
-----

* In a `keypress` event, the Unicode value of the key pressed is stored in
 either the `keyCode` or `charCode`
 property, but never both. If the key pressed generates a character (e.g., 'a'),
 `charCode` is set to the code of that character; `charCode`
 respects the letter case (in other words, `charCode` takes into account
 whether the
 `shift`
 key is held down). Otherwise, the code of the pressed key
 is stored in `keyCode`.
* When one or more modifier keys are pressed, there are some complex rules for
 `charCode`. See Gecko Keypress Event
 for details.
* `charCode` is never set in the `keydown` and
 `keyup` events. In these cases, `keyCode` is set instead.
* 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`.
* For a list of the `charCode` values associated with particular keys, run
 Example 7: Displaying Event Object Properties and view the resulting HTML table.
Specifications
--------------

| Specification |
| --- |
| UI Events # dom-keyboardevent-charcode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


KeyboardEvent: location property - Web APIs

KeyboardEvent: location property
================================

 The **`KeyboardEvent.location`** read-only property returns an
 `unsigned long` representing the location of the key on the keyboard or other
 input device.

Possible values are:

| Constant | Value | Description |
| --- | --- | --- |
| `DOM_KEY_LOCATION_STANDARD` | 0 |
 The key has only one version, or can't be distinguished between the left
 and right versions of the key, and was not pressed on the numeric keypad
 or a key that is considered to be part of the keypad.
  |
| `DOM_KEY_LOCATION_LEFT` | 1 |
 The key was the left-hand version of the key; for example, the left-hand
 `Control` key was pressed on a standard 101 key US keyboard.
 This value is only used for keys that have more than one possible
 location on the keyboard.
  |
| `DOM_KEY_LOCATION_RIGHT` | 2 |
 The key was the right-hand version of the key; for example, the
 right-hand `Control` key is pressed on a standard 101 key US
 keyboard. This value is only used for keys that have more than one
 possible location on the keyboard.
  |
| `DOM_KEY_LOCATION_NUMPAD` | 3 |
 The key was on the numeric keypad, or has a virtual key code that
 corresponds to the numeric keypad.

**Note:** When `NumLock` is locked, Firefox
 always returns `DOM_KEY_LOCATION_NUMPAD` for the keys on
 the numeric pad. Otherwise, when `NumLock` is unlocked and
 the keyboard actually has a numeric keypad, Firefox always returns
 `DOM_KEY_LOCATION_NUMPAD` too. On the other hand, if the
 keyboard doesn't have a keypad, such as on a notebook computer, some
 keys become Numpad only when NumLock is locked. When such keys fires
 key events, the location attribute value depends on the key. That
 is, it must not be `DOM_KEY_LOCATION_NUMPAD`.

**Note:** `NumLock` key's key events indicate
 `DOM_KEY_LOCATION_STANDARD` both on Firefox and Internet
 Explorer.

 |
| `DOM_KEY_LOCATION_MOBILE`

Non-standard

Deprecated
 | 4 |
 The key was on a mobile device; this can be on either a physical
 keypad or a virtual keyboard.
  |
| `DOM_KEY_LOCATION_JOYSTICK`
Non-standard

Deprecated
 | 5 |
 The key was a button on a game controller or a joystick on a mobile
 device.
  |

Value
-----

A number.

Examples
--------

```js
function keyEvent(event) {
  console.log(`Location of key pressed: ${event.location}`);
}
```

Specifications
--------------

| Specification |
| --- |
| UI Events # dom-keyboardevent-location |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `KeyboardEvent`


KeyboardEvent: metaKey property - Web APIs

KeyboardEvent: metaKey property
===============================

 The **`KeyboardEvent.metaKey`** read-only property returning a
 boolean value that indicates if the `Meta` key was pressed
 (`true`) or not (`false`) when the event occurred. Some operating
 systems may intercept the key so it is never detected.

**Note:** On Macintosh keyboards, this is the `⌘ Command` key.

**Note:** Before Firefox 118, the `⊞ Windows` key was handled
 as an "OS" key rather than the "Meta" key. `KeyboardEvent.metaKey` was
 `false` when the `⊞ Windows` key was pressed.

Value
-----

A boolean value.

Examples
--------

```html
<button onclick="ismetaKey(event)">Click me with the meta key</button>

<p id="output"></p>
```

```js
function ismetaKey(e) {
  document.querySelector("#output").textContent =
    `metaKey pressed? ${e.metaKey}`;
}
```

### Result

Specifications
--------------

| Specification |
| --- |
| UI Events # dom-keyboardevent-metakey |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `KeyboardEvent`


TextFormatUpdateEvent: getTextFormats() method - Web APIs

TextFormatUpdateEvent: getTextFormats() method
==============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`getTextFormats()`** method of the `TextFormatUpdateEvent` interface returns an `Array` of `TextFormat` objects that represent the formats that an Input Method Editor (IME) window wants to apply to the text being composed.

Syntax
------

```js
getTextFormats()
```

### Return value

An `Array` containing `TextFormat` objects.

Examples
--------

### Styling IME-composed text

In the following example, the `textformatupdate` event is used to update the formatting of the text in the editable region.

```html
<canvas id="editor-canvas"></canvas>
```

```js
const TEXT\_X = 10;
const TEXT\_Y = 10;

const canvas = document.getElementById("editor-canvas");
const ctx = canvas.getContext("2d");

const editContext = new EditContext();
canvas.editContext = editContext;

editContext.addEventListener("textformatupdate", (e) => {
  // Clear the canvas.
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Render the text.
  ctx.fillText(editContext.text, TEXT\_X, TEXT\_Y);
  console.log(`Rendering text: ${editContext.text}`);

  // Get the text formats that the IME window wants to apply.
  const formats = e.getTextFormats();

  // Iterate over the text formats
  for (const format of formats) {
    const { rangeStart, rangeEnd, underlineStyle, underlineThickness } = format;

    console.log(
      `Applying underline ${underlineThickness} ${underlineStyle} between ${rangeStart} and ${rangeEnd}.`,
    );

    const underlineXStart = ctx.measureText(
      editContext.text.substring(0, rangeStart),
    ).width;
    const underlineXEnd = ctx.measureText(
      editContext.text.substring(0, rangeEnd),
    ).width;
    const underlineY = TEXT\_Y + 3;

    // For brevity, this example only draws a simple underline.
    // Use underlineStyle and underlineThickness to draw the correct underline.

    ctx.beginPath();
    ctx.moveTo(TEXT\_X + underlineXStart, underlineY);
    ctx.lineTo(TEXT\_X + underlineXEnd, underlineY);
    ctx.stroke();
  }
});
```

Specifications
--------------

| Specification |
| --- |
| EditContext API # dom-textformatupdateevent-gettextformats |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


TextFormatUpdateEvent: TextFormatUpdateEvent() constructor - Web APIs

TextFormatUpdateEvent: TextFormatUpdateEvent() constructor
==========================================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`TextFormatUpdateEvent()`** constructor returns a new `TextFormatUpdateEvent` object.

Syntax
------

```js
new TextFormatUpdateEvent(type)
new TextFormatUpdateEvent(type, options)
```

### Parameters

`type`

A string representing the type of the event. Possible values: `"textformatupdate"`.

`options` Optional

An optional object with the following properties:

`textFormats`

An `Array` of `TextFormat` objects representing the text formats that need to be applied with this event.

Specifications
--------------

| Specification |
| --- |
| EditContext API # dom-textformatupdateevent-constructor |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `TextFormatUpdateEvent` interface it belongs to.


DocumentPictureInPictureEvent: DocumentPictureInPictureEvent() constructor - Web APIs

DocumentPictureInPictureEvent: DocumentPictureInPictureEvent() constructor
==========================================================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`DocumentPictureInPictureEvent()`** constructor creates a new
 `DocumentPictureInPictureEvent` object instance.

Syntax
------

```js
new DocumentPictureInPictureEvent(type, init)
```

### Parameters

`type`

A string representing the type of event. In the case of `DocumentPictureInPictureEvent` this is always `enter`.

`init`

An object containing the following properties:

`window`

A `Window` instance representing the browsing context inside the `DocumentPictureInPicture` window the event was fired on.

Examples
--------

A developer would not use this constructor manually. A new `DocumentPictureInPictureEvent` object is constructed when a handler is invoked as a result of the `enter` event firing.

```js
documentPictureInPicture.addEventListener("enter", (event) => {
  const pipWindow = event.window;
  console.log("Video player has entered the pip window");

  const pipMuteButton = pipWindow.document.createElement("button");
  pipMuteButton.textContent = "Mute";
  pipMuteButton.addEventListener("click", () => {
    const pipVideo = pipWindow.document.querySelector("#video");
    if (!pipVideo.muted) {
      pipVideo.muted = true;
      pipMuteButton.textContent = "Unmute";
    } else {
      pipVideo.muted = false;
      pipMuteButton.textContent = "Mute";
    }
  });

  pipWindow.document.body.append(pipMuteButton);
});
```

Specifications
--------------

| Specification |
| --- |
| Document Picture-in-Picture Specification # dom-documentpictureinpictureevent-documentpictureinpictureevent |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Document Picture-in-Picture API
* Using the Document Picture-in-Picture API


DocumentPictureInPictureEvent: window property - Web APIs

DocumentPictureInPictureEvent: window property
==============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`window`** read-only property of the
 `DocumentPictureInPictureEvent` interface returns a `Window` instance representing the browsing context inside the `DocumentPictureInPicture` window the event was fired on.

Value
-----

A `Window` object instance.

Examples
--------

```js
documentPictureInPicture.addEventListener("enter", (event) => {
  const pipWindow = event.window;
  console.log("Video player has entered the pip window");

  const pipMuteButton = pipWindow.document.createElement("button");
  pipMuteButton.textContent = "Mute";
  pipMuteButton.addEventListener("click", () => {
    const pipVideo = pipWindow.document.querySelector("#video");
    if (!pipVideo.muted) {
      pipVideo.muted = true;
      pipMuteButton.textContent = "Unmute";
    } else {
      pipVideo.muted = false;
      pipMuteButton.textContent = "Mute";
    }
  });

  pipWindow.document.body.append(pipMuteButton);
});
```

Specifications
--------------

| Specification |
| --- |
| Document Picture-in-Picture Specification # dom-documentpictureinpictureevent-window |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Document Picture-in-Picture API
* Using the Document Picture-in-Picture API


VideoPlaybackQuality: droppedVideoFrames property - Web APIs

VideoPlaybackQuality: droppedVideoFrames property
=================================================

 The read-only **`droppedVideoFrames`**
 property of the `VideoPlaybackQuality` interface returns the number of
 video frames which have been dropped rather than being displayed since the last time
 the media was loaded into the `HTMLVideoElement`.

Value
-----

 An unsigned 64-bit value indicating the number of frames that have been dropped since
 the last time the media in the `<video>` element was loaded or reloaded.
 This information can be used to determine whether or not to downgrade the video stream
 to avoid dropping frames.

 Frames are typically dropped either before or after decoding them, when it's determined
 that it will not be possible to draw them to the screen at the correct time.

Examples
--------

 This example calls `getVideoPlaybackQuality()` to obtain a `VideoPlaybackQuality` object,
 then determines what percentage of frames have been dropped. That value is then
 presented in an element for the user's reference.

```js
const videoElem = document.getElementById("my\_vid");
const percentElem = document.getElementById("percent");
const quality = videoElem.getVideoPlaybackQuality();

const dropPercent =
  (quality.droppedVideoFrames / quality.totalVideoFrames) \* 100;
percentElem.innerText = Math.trunc(dropPercent).toString(10);
```

Specifications
--------------

| Specification |
| --- |
| Media Playback Quality # dom-videoplaybackquality-droppedvideoframes |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `HTMLVideoElement.getVideoPlaybackQuality()` method, which creates
 and returns `VideoPlaybackQuality` objects


VideoPlaybackQuality: corruptedVideoFrames property - Web APIs

VideoPlaybackQuality: corruptedVideoFrames property
===================================================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. 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 time.

 The `VideoPlaybackQuality` interface's read-only
 **`corruptedVideoFrames`** property the number of corrupted
 video frames that have been received since the `<video>` element was
 last loaded or reloaded.

Value
-----

 The number of corrupted video frames that have been received since the
 `<video>` element was last loaded or reloaded.

 It is up to the user agent to determine whether or not to display a
 corrupted video frame. If a corrupted frame is dropped, then both
 `corruptedVideoFrames` and
 `droppedVideoFrames` are
 incremented.

Examples
--------

 This example determines the percentage of frames which have been corrupted, and if the
 value is greater than 5%, calls a function called `downgradeVideo()` that
 would be implemented to switch to a different video that might tax the network less.

```js
const videoElem = document.getElementById("my\_vid");
const quality = videoElem.getVideoPlaybackQuality();

if (quality.corruptedVideoFrames / quality.totalVideoFrames > 0.05) {
  downgradeVideo(videoElem);
}
```

Specifications
--------------

| Specification |
| --- |
| Media Playback Quality # dom-videoplaybackquality-corruptedvideoframes |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `HTMLVideoElement.getVideoPlaybackQuality()` method for
 constructing and returning this interface


VideoPlaybackQuality: creationTime property - Web APIs

VideoPlaybackQuality: creationTime property
===========================================

 The read-only **`creationTime`** property on the
 `VideoPlaybackQuality` interface reports the number of milliseconds since
 the browsing context was created this quality sample was recorded.

Value
-----

 A `DOMHighResTimeStamp` object which indicates the number of milliseconds
 that elapsed between the time the browsing context was created and the time at which
 this sample of the video quality was obtained.

For details on how the time is determined, see `Performance.now()`.

Examples
--------

 This example calls `getVideoPlaybackQuality()` to obtain a
 `VideoPlaybackQuality` object, then determines what percentage of frames
 have been lost by either corruption or being dropped. If that exceeds 10% (0.1), a
 function called `lostFramesThresholdExceeded()` is called to, perhaps,
 update a quality indicator to show an increase in frame loss.

```js
const videoElem = document.getElementById("my\_vid");
const quality = videoElem.getVideoPlaybackQuality();

if (
  (quality.corruptedVideoFrames + quality.droppedVideoFrames) /
    quality.totalVideoFrames >
  0.1
) {
  lostFramesThresholdExceeded();
}
```

Specifications
--------------

| Specification |
| --- |
| Media Playback Quality # dom-videoplaybackquality-creationtime |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `HTMLVideoElement.getVideoPlaybackQuality()` method, which
 returns `VideoPlaybackQuality` objects


VideoPlaybackQuality: totalVideoFrames property - Web APIs

VideoPlaybackQuality: totalVideoFrames property
===============================================

 The `VideoPlaybackQuality` interface's
 **`totalVideoFrames`** read-only property returns the total
 number of video frames that have been displayed or dropped since the media was
 loaded.

Value
-----

 The total number of frames that the `<video>` element has displayed or
 dropped since the media was loaded into it. Essentially, this is the number of frames
 the element *would have presented* had no problems occurred.

This value is reset when the media is reloaded or replaced.

Examples
--------

 This example calls `getVideoPlaybackQuality()` to obtain a `VideoPlaybackQuality` object,
 then determines what percentage of frames have been lost by either corruption or being
 dropped. If that exceeds 10% (0.1), a function called
 `lostFramesThresholdExceeded()` is called to, perhaps, update a quality
 indicator to show an increase in frame loss.

```js
const videoElem = document.getElementById("my\_vid");
const quality = videoElem.getVideoPlaybackQuality();

if (
  (quality.corruptedVideoFrames + quality.droppedVideoFrames) /
    quality.totalVideoFrames >
  0.1
) {
  lostFramesThresholdExceeded();
}
```

 A similar algorithm might be used to attempt to switch to a lower-resolution video that
 requires less bandwidth, in order to avoid dropping frames.

Specifications
--------------

| Specification |
| --- |
| Media Playback Quality # dom-videoplaybackquality-totalvideoframes |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `HTMLVideoElement.getVideoPlaybackQuality()` method for
 constructing and returning this interface.


VideoPlaybackQuality: totalFrameDelay property - Web APIs

VideoPlaybackQuality: totalFrameDelay property
==============================================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. 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 time.

**Non-standard:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

 The **`VideoPlaybackQuality.totalFrameDelay`** read-only
 property returns a `double` containing the sum of the frame delay since the
 creation of the associated `HTMLVideoElement`. The frame delay is the
 difference between a frame's theoretical presentation time and its effective display
 time.

Value
-----

A number.

Examples
--------

```js
const videoElt = document.getElementById("my\_vid");
const quality = videoElt.getVideoPlaybackQuality();

alert(quality.totalFrameDelay);
```

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `HTMLVideoElement.getVideoPlaybackQuality()` method for
 constructing and returning this interface.
* `MediaSource`
* `SourceBuffer`


GeolocationPositionError: message property - Web APIs

GeolocationPositionError: message property
==========================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

The **`message`** read-only property of the `GeolocationPositionError` interface returns a human-readable string describing the details of the error.

Value
-----

A human-readable string describing the details of the error.

Specifications
--------------

| Specification |
| --- |
| Geolocation API # message-attribute |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using the Geolocation API
* `GeolocationPositionError`


GeolocationPositionError: code property - Web APIs

GeolocationPositionError: code property
=======================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

The **`code`** read-only property of the `GeolocationPositionError` interface is an `unsigned short` representing the error code.

The following values are possible:

| Value | Associated constant | Description |
| --- | --- | --- |
| `1` | `PERMISSION_DENIED` |
 The acquisition of the geolocation information failed because the page
 didn't have the permission to do it.
  |
| `2` | `POSITION_UNAVAILABLE` | The acquisition of the geolocation failed because one or several internal sources of position returned an internal error. |
| `3` | `TIMEOUT` | Geolocation information was not obtained in the allowed time. |

Specifications
--------------

| Specification |
| --- |
| Geolocation API # code-attribute |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using geolocation
* `GeolocationPositionError`


CookieStore: getAll() method - Web APIs

CookieStore: getAll() method
============================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`getAll()`** method of the `CookieStore` interface returns a list of cookies that match the name or options passed to it. Passing no parameters will return all cookies for the current context.

**Note:** This feature is available in Web Workers

Syntax
------

```js
getAll(name)
getAll(options)
```

### Parameters

`name` Optional

A string with the name of a cookie.

Or

`options` Optional

An object containing:

`name`

A string with the name of a cookie.

`url`

A string with the URL of a cookie.

**Note:** The `url` option enables the modification of a cookie scoped under a particular URL. Service workers can obtain cookies that would be sent to any URL under their scope. From a document you may only obtain the cookies at the current URL, so the only valid URL in a document context is the document's URL.

### Return value

A `Promise` that resolves with an array of objects representing cookies that match the given name or options.

Each object contains the following properties:

`domain`

A string containing the domain of the cookie.

`expires`

A timestamp, given as Unix time in milliseconds, containing the expiration date of the cookie.

`name`

A string containing the name of the cookie.

`partitioned`

A boolean indicating whether the cookie is a partitioned cookie (`true`) or not (`false`). See Cookies Having Independent Partitioned State (CHIPS) for more information.

`path`

A string containing the path of the cookie.

`sameSite`

One of the following `SameSite` values:

`"strict"`

Cookies will only be sent in a first-party context and not be sent with requests initiated by third party websites.

`"lax"`

Cookies are not sent on normal cross-site subrequests (for example to load images or frames into a third party site), but are sent when a user is navigating within the origin site (i.e. when following a link).

`"none"`

Cookies will be sent in all contexts.

`secure`

A boolean value indicating whether the cookie is to be used in secure contexts only (`true`) or not (`false`).

`value`

A string containing the value of the cookie.

### Exceptions

`SecurityError` `DOMException`

Thrown if the origin does not serialize to a URL.

`TypeError`

Thrown if:

* The `url` option is present and is not equal with the creation URL, if in main thread.
* The `url` option is present and its origin is not the same as the origin of the creation URL.
* Querying cookies represented by the given `name` or `options` fails.

Examples
--------

In this example, we use `getAll()` with no parameters. This returns all of the cookies for this context as an array of objects.

```js
const cookies = await cookieStore.getAll();

if (cookies.length > 0) {
  console.log(cookies);
} else {
  console.log("Cookie not found");
}
```

Specifications
--------------

| Specification |
| --- |
| Cookie Store API # dom-cookiestore-getall |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


CookieStore: get() method - Web APIs

CookieStore: get() method
=========================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`get()`** method of the `CookieStore` interface returns a single cookie with the given name or options object. The method will return the first matching cookie for the passed parameters.

**Note:** This feature is available in Web Workers

Syntax
------

```js
get(name)
get(options)
```

### Parameters

This method requires one of the following:

`name` Optional

A string with the name of a cookie.

Or

`options` Optional

An object containing:

`name`

A string with the name of a cookie.

`url`

A string with the URL of a cookie.

**Note:** The `url` option enables the modification of a cookie scoped under a particular URL. Service workers can obtain cookies that would be sent to any URL under their scope. From a document you may only obtain the cookies at the current URL, so the only valid URL in a document context is the document's URL.

### Return value

A `Promise` that resolves with an object representing the first cookie matching the submitted name or options. This object contains the following properties:

`domain`

A string containing the domain of the cookie.

`expires`

A timestamp, given as Unix time in milliseconds, containing the expiration date of the cookie.

`name`

A string containing the name of the cookie.

`partitioned`

A boolean indicating whether the cookie is a partitioned cookie (`true`) or not (`false`). See Cookies Having Independent Partitioned State (CHIPS) for more information.

`path`

A string containing the path of the cookie.

`sameSite`

One of the following `SameSite` values:

`"strict"`

Cookies will only be sent in a first-party context and not be sent with requests initiated by third party websites.

`"lax"`

Cookies are not sent on normal cross-site subrequests (for example to load images or frames into a third party site), but are sent when a user is navigating within the origin site (i.e. when following a link).

`"none"`

Cookies will be sent in all contexts.

`secure`

A boolean value indicating whether the cookie is to be used in secure contexts only (`true`) or not (`false`).

`value`

A string containing the value of the cookie.

### Exceptions

`SecurityError` `DOMException`

Thrown if the origin does not serialize to a URL.

`TypeError`

Thrown if:

* The `options` parameter is an empty object.
* The `url` option is present and is not equal with the creation URL, if in main thread.
* The `url` option is present and its origin is not the same as the origin of the creation URL.
* Querying cookies represented by the given `name` or `options` fails.

Examples
--------

In this example, we return a cookie named "cookie1". If the cookie is found the result of the Promise is an object containing the details of a single cookie.

```js
const cookie = await cookieStore.get("cookie1");

if (cookie) {
  console.log(cookie);
} else {
  console.log("Cookie not found");
}
```

Specifications
--------------

| Specification |
| --- |
| Cookie Store API # dom-cookiestore-get |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


CookieStore: set() method - Web APIs

CookieStore: set() method
=========================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`set()`** method of the `CookieStore` interface sets a cookie with the given name and value or options object.

**Note:** This feature is available in Web Workers

Syntax
------

```js
set(name, value)
set(options)
```

### Parameters

This method requires one of the following:

`name` Optional

A string with the name of the cookie.

`value` Optional

A string with the value of the cookie.

Or

`options` Optional

An object containing:

`domain` Optional

A string containing the domain of the cookie. Defaults to `null`.

`expires` Optional

A timestamp, given as Unix time in milliseconds, containing the expiration date of the cookie. Defaults to `null`.

`name`

A string with the name of a cookie.

`partitioned` Optional

A boolean value that defaults to `false`. If set to `true`, the set cookie will be a partitioned cookie. See Cookies Having Independent Partitioned State (CHIPS) for more information.

`path` Optional

A string containing the path of the cookie. Defaults to `/`.

`sameSite` Optional

One of the following `SameSite` values:

`"strict"`

Cookies will only be sent in a first-party context and not be sent along with requests initiated by third party websites. This is the default.

`"lax"`

Cookies are not sent on normal cross-site subrequests (for example to load images or frames into a third party site), but are sent when a user is navigating to the origin site (i.e. when following a link).

`"none"`

Cookies will be sent in all contexts.

`value`

A string with the value of the cookie.

### Return value

A `Promise` that resolves with `undefined` when setting the cookie completes.

### Exceptions

`SecurityError` `DOMException`

Thrown if the origin can not be serialized to a URL.

`TypeError`

Thrown if setting the cookie with the given `name` and `value` or `options` fails.

Examples
--------

The following example sets a cookie by passing an object with `name`, `value`, `expires`, and `domain`.

```js
const day = 24 \* 60 \* 60 \* 1000;

cookieStore.set({
  name: "cookie1",
  value: "cookie1-value",
  expires: Date.now() + day,
  domain: "example.com",
});
```

Specifications
--------------

| Specification |
| --- |
| Cookie Store API # dom-cookiestore-set |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


CookieStore: delete() method - Web APIs

CookieStore: delete() method
============================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`delete()`** method of the `CookieStore` interface deletes a cookie with the given name or options object. The `delete()` method expires the cookie by changing the date to one in the past.

**Note:** This feature is available in Web Workers

Syntax
------

```js
delete(name)
delete(options)
```

### Parameters

This method requires one of the following:

`name` Optional

A string with the name of a cookie.

Or

`options` Optional

An object containing:

`name`

A string with the name of a cookie.

`domain` Optional

A string with the domain of a cookie. Defaults to `null`.

`path` Optional

A string containing a path. Defaults to `/`.

`partitioned` Optional

A boolean value that defaults to `false`. Setting it to `true` specifies that the cookie to delete will be a partitioned cookie. See Cookies Having Independent Partitioned State (CHIPS) for more information.

**Note:** The `url` option enables the modification of a cookie scoped under a particular URL. Service workers can obtain cookies that would be sent to any URL under their scope. From a document you may only obtain the cookies at the current URL, so the only valid URL in a document context is the document's URL.

### Return value

A `Promise` that resolves with `undefined` when deletion completes.

### Exceptions

`SecurityError` `DOMException`

Thrown if the origin can not be serialized to a URL.

`TypeError`

Thrown if deleting the cookie represented by the given `name` or `options` fails.

Examples
--------

In this example, a cookie is deleted by passing the name to the `delete()` method.

```js
const result = cookieStore.delete("cookie1");

console.log(result);
```

Specifications
--------------

| Specification |
| --- |
| Cookie Store API # dom-cookiestore-delete |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


CookieStore: change event - Web APIs

CookieStore: change event
=========================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

A `change` event is fired at a `CookieStore` object when a change is made to any cookie.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
cookieStore.addEventListener("change", (event) => { })

cookieStore.onchange = (event) => { }
```

Event type
----------

A `CookieChangeEvent`. Inherits from `Event`.

Event

CookieChangeEventExamples
--------

To be informed when a cookie has changed, you can add a handler to the `cookieStore` instance using `addEventListener()`, like this:

```js
cookieStore.addEventListener("change", (event) => {
  console.log("1 change event");
});
```

Alternatively, you can use the `onchange` event handler property to establish a handler for the `change` event:

```js
cookieStore.onchange = (event) => {
  console.log("1 change event");
};
```

Specifications
--------------

| Specification |
| --- |
| Cookie Store API # intro-monitor |
| Cookie Store API # dom-cookiestore-onchange |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


IDBCursorWithValue: value property - Web APIs

IDBCursorWithValue: value property
==================================

 The **`value`** read-only property of the
 `IDBCursorWithValue` interface returns the value of the current cursor,
 whatever that is.

**Note:** This feature is available in Web Workers

Value
-----

The value of the current cursor.

Examples
--------

 In this example we create a transaction, retrieve an object store, then use a cursor to
 iterate through all the records in the object store. Within each iteration we log the
 value of the cursor with `cursor.value`.

 The cursor does not require us to select the data based
 on a key; we can just grab all of it. Also note that in each iteration of the loop,
 you can grab data from the current record under the cursor object using `cursor.value.foo`.
 For a complete working example, see our IDBCursor example
 (view example live.)

```js
function displayData() {
  const transaction = db.transaction(["rushAlbumList"], "readonly");
  const objectStore = transaction.objectStore("rushAlbumList");

  objectStore.openCursor().onsuccess = (event) => {
    const cursor = event.target.result;
    if (cursor) {
      const listItem = document.createElement("li");
      listItem.textContent = `${cursor.value.albumTitle}, ${cursor.value.year}`;
      list.appendChild(listItem);

      console.log(cursor.value);
      cursor.continue();
    } else {
      console.log("Entries all displayed.");
    }
  };
}
```

Specifications
--------------

| Specification |
| --- |
| Indexed Database API 3.0 # ref-for-dom-idbcursorwithvalue-value① |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using IndexedDB
* Starting transactions: `IDBDatabase`
* Using transactions: `IDBTransaction`
* Setting a range of keys: `IDBKeyRange`
* Retrieving and making changes to your data: `IDBObjectStore`
* Using cursors: `IDBCursor`
* Reference example: To-do Notifications (View the example live).


CSSSkewY: CSSSkewY() constructor - Web APIs

CSSSkewY: CSSSkewY() constructor
================================

 The **`CSSSkewY()`** constructor creates a new
 `CSSSkewY` object which represents the
 `skewY()` value
 of the individual `transform` property in CSS.

Syntax
------

```js
new CSSSkewY(ay)
```

### Parameters

`ay`

 A value for the `ay` angle of the `CSSSkewY` object to be
 constructed. This must be a `CSSNumericValue`.

Examples
--------

To do

Specifications
--------------

| Specification |
| --- |
| CSS Typed OM Level 1 # dom-cssskewy-cssskewy |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.