AnalyserNode.fftSize - Web API 接口参考

AnalyserNode.fftSize
====================

`AnalyserNode` 接口的 `fftSize` 属性的值是一个无符号长整型的值，表示（信号）样本的窗口大小。当执行快速傅里叶变换（Fast Fourier Transfor (FFT)）时，这些（信号）样本被用来获取频域数据。

fftSize 属性的值必须是从 32 到 32768 范围内的 2 的非零幂; 其默认值为 2048.

**备注：** 如果其值不是 2 的幂，或者它在指定范围之外，则抛出异常 INDEX\_SIZE\_ERR.

语法
--

```js
var audioCtx = new AudioContext();
var analyser = audioCtx.createAnalyser();
analyser.fftSize = 2048;
```

### 值

一个无符号长整型。

例子
--

下面的例子展示了 `AudioContext` 创建一个 `AnalyserNode`, 然后用 `requestAnimationFrame` 和 `<canvas>` 去反复收集当前音频的时域数据，并绘制为一个示波器风格的输出 (频谱).

更多的例子/信息，查看 Voice-change-O-matic 演示 (相关代码在 app.js 在 128 行~205 行).

```js
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var analyser = audioCtx.createAnalyser();

  ...

analyser.fftSize = 2048;
var bufferLength = analyser.fftSize;
var dataArray = new Uint8Array(bufferLength);
analyser.getByteTimeDomainData(dataArray);

// draw an oscilloscope of the current audio source

function draw() {

      drawVisual = requestAnimationFrame(draw);

      analyser.getByteTimeDomainData(dataArray);

      canvasCtx.fillStyle = 'rgb(200, 200, 200)';
      canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

      canvasCtx.lineWidth = 2;
      canvasCtx.strokeStyle = 'rgb(0, 0, 0)';

      canvasCtx.beginPath();

      var sliceWidth = WIDTH \* 1.0 / bufferLength;
      var x = 0;

      for(var i = 0; i < bufferLength; i++) {

        var v = dataArray[i] / 128.0;
        var y = v \* HEIGHT/2;

        if(i === 0) {
          canvasCtx.moveTo(x, y);
        } else {
          canvasCtx.lineTo(x, y);
        }

        x += sliceWidth;
      }

      canvasCtx.lineTo(canvas.width, canvas.height/2);
      canvasCtx.stroke();
    };

    draw();
```

规范
--

| Specification |
| --- |
| Web Audio API # dom-analysernode-fftsize |

浏览器兼容性
------

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

相关内容
----

* Using the Web Audio API (en-US)


AnalyserNode.frequencyBinCount - Web API 接口参考

AnalyserNode.frequencyBinCount
==============================

**`frequencyBinCount`** 的值固定为 `AnalyserNode` 接口中 fftSize 值的一半。该属性通常用于可视化的数据值的数量。

语法
--

```js
var audioCtx = new AudioContext();
var analyser = audioCtx.createAnalyser();
var bufferLength = analyser.frequencyBinCount;
```

### 值类型

无符号长整形 (unsigned long).

例子
--

下面的例子展示了 `AudioContext` 创建一个 `AnalyserNode`, 然后用 `requestAnimationFrame` 和 `<canvas>` 去反复收集频率数据，并绘制为一个柱状风格的输出 (频谱).

更多的例子/信息，查看 Voice-change-O-matic 演示 (相关代码在 app.js 的 128 行~205 行).

```js
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var analyser = audioCtx.createAnalyser();
analyser.minDecibels = -90;
analyser.maxDecibels = -10;

  ...

analyser.fftSize = 256;
var bufferLength = analyser.frequencyBinCount;
console.log(bufferLength);
var dataArray = new Uint8Array(bufferLength);

canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

function draw() {
  drawVisual = requestAnimationFrame(draw);

  analyser.getByteFrequencyData(dataArray);

  canvasCtx.fillStyle = 'rgb(0, 0, 0)';
  canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

  var barWidth = (WIDTH / bufferLength) \* 2.5;
  var barHeight;
  var x = 0;

  for(var i = 0; i < bufferLength; i++) {
    barHeight = dataArray[i];

    canvasCtx.fillStyle = 'rgb(' + (barHeight+100) + ',50,50)';
    canvasCtx.fillRect(x,HEIGHT-barHeight/2,barWidth,barHeight/2);

    x += barWidth + 1;
  }
};

draw();
```

规范
--

| Specification |
| --- |
| Web Audio API # dom-analysernode-frequencybincount |

浏览器兼容性
------

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

相关内容
----

* Using the Web Audio API (en-US)


AnalyserNode.getByteFrequencyData() - Web API 接口参考

AnalyserNode.getByteFrequencyData()
===================================

`AnalyserNode`接口的 **`getByteFrequencyData()`** 方法将当前频率数据复制到传入的 Uint8Array（无符号字节数组）中。

如果数组的长度小于 `AnalyserNode.frequencyBinCount`, 那么 Analyser 多出的元素会被删除。如果是大于，那么数组多余的元素会被忽略。

语法
--

```js
var audioCtx = new AudioContext();
var analyser = audioCtx.createAnalyser();
var dataArray = new Uint8Array(analyser.frequencyBinCount); // Uint8Array 的长度应该和 frequencyBinCount 相等
analyser.getByteFrequencyData(dataArray); // 调用 getByteFrequencyData 方法填充 Uint8Array
```

### 返回值

一个 `Uint8Array` (en-US)（无符号字节数组）.

例子
--

下面的例子展示了 `AudioContext` 创建一个 `AnalyserNode`, 然后用 `requestAnimationFrame` 和 `<canvas>` 去反复收集当前音频的频率数据，并绘制为一个柱状风格的输出 (频谱).

更多的例子/信息，查看 Voice-change-O-matic 演示 (相关代码在 app.js 的 128 行~205 行).

```js
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var analyser = audioCtx.createAnalyser();

  ...

analyser.fftSize = 256;
var bufferLength = analyser.frequencyBinCount;
console.log(bufferLength);
var dataArray = new Uint8Array(bufferLength);

canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

function draw() {
  drawVisual = requestAnimationFrame(draw);

  analyser.getByteFrequencyData(dataArray);

  canvasCtx.fillStyle = 'rgb(0, 0, 0)';
  canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

  var barWidth = (WIDTH / bufferLength) \* 2.5;
  var barHeight;
  var x = 0;

  for(var i = 0; i < bufferLength; i++) {
    barHeight = dataArray[i];

    canvasCtx.fillStyle = 'rgb(' + (barHeight+100) + ',50,50)';
    canvasCtx.fillRect(x,HEIGHT-barHeight/2,barWidth,barHeight/2);

    x += barWidth + 1;
  }
};

draw();
```

参数
--

array (数组)

必须为`Uint8Array` (en-US), 频域数据将复制到该数组内。

规范
--

| Specification |
| --- |
| Web Audio API # dom-analysernode-getbytefrequencydata |

浏览器兼容性
------

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

相关内容
----

* Using the Web Audio API (en-US)


KeyboardEvent.initKeyEvent() - Web API 接口参考

KeyboardEvent.initKeyEvent()
============================

**警告：** 不要再使用这个方法，而是使用 `KeyboardEvent()` 构造函数。

该方法已从 DOM 规范中删除，并且不受任何现代浏览器支持。Firefox 从版本 93 开始默认通过首选项（`dom.keyboardevent.init_key_event.enabled`）隐藏此方法，并计划很快移除它。

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

KeyboardEvent.initKeyEvent 方法用于初始化使用`document.createEvent`("KeyboardEvent") 创建的事件的值。以这种方式初始化的事件必须使用`document.createEvent`("KeyboardEvent") 方法创建。在调度之前，必须调用 initKeyEvent 来设置事件。

Syntax
------
```

event.initKeyEvent (type, bubbles, cancelable, viewArg,
                    ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg,
                    keyCodeArg, charCodeArg)
```

### Parameters

* *`type`*
    + : 是表示事件类型的`DOMString`。
* *`bubbles`*
    + : 是`Boolean`指示事件是否应该通过事件链冒泡（请参阅冒泡）。
* *`cancelable`*
    + : 是`Boolean`我指出事件是否可以被取消（见可取消）。
* *`viewArg`*
    + : 指定`UIEvent.view`; 此值可能为空。
* *`ctrlKeyArg`*
    + : 如果要生成的虚拟键是包含
     `Ctrl`
     键的键的组合，则为`Boolean`
* *`altKeyArg`*
    + *: `如果要生成的虚拟键是包含`*
    `Alt`
    *`键的键的组合，则为`Boolean`。`*
* *`shiftKeyArg`*
    + : A `Boolean`如果要生成的虚拟键是包含
     `Shift`
     键的键组合，则返回 true。
* *`metaKeyArg`*
    + *: `是`Boolean`如果要生成的虚拟键是包含`*
    `Meta`
    *`键的键的组合，则为 true。`*
* *`keyCodeArg`*
    + : 是一个无符号长整型，表示被按下的键的虚拟键码值，否则为 0.请参阅`KeyboardEvent.keyCode`以获取键码列表。
* *`charCodeArg`*
    + : 是一个无符号长整型，表示与按下的键相关的 Unicode 字符，否则为 0。
Example
-------
```

var 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);
```

Specification
-------------

键盘事件的这种实现基于 DOM 2 事件早期版本中的关键事件规范，后来从该规范中删除。

initKeyEvent 是 DOM Level 3 事件的当前 Gecko 等价物（最初起草并且不推荐使用`KeyboardEvent()` `Keyboard.initKeyboardEvent()`方法与以下参数：
```

typeArg of type DOMString
canBubbleArg of type boolean
cancelableArg of type boolean
viewArg of type views::AbstractView
keyIdentifierArg of type DOMString
keyLocationArg of type unsigned long
modifiersList of type DOMString);
```


KeyboardEvent.charCode - Web API 接口参考

KeyboardEvent.charCode
======================

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

`KeyboardEvent.charCode` 只读属性，返回 `keypress` 事件触发时按下的字符键的字符 Unicode 值。

与这些数值代码等价的常量，请参考 `KeyEvent`.

**备注：** **该属性已被废弃，请勿再使用该属性。**

请使用 `KeyboardEvent.key` 取代。

语法
--
```

var value = event.charCode;
```

* *`value`* 被按下的字符键的字符 Unicode 值
示例
--

```js
<html>
<head>
<title>charCode example</title>

<script type="text/javascript">

function showChar(e)
{
alert("Key Pressed: " + String.fromCharCode(e.charCode) + "\n"
      + "charCode: " + e.charCode);
}

</script>
</head>

<body onkeypress="showChar(event);">
<p>Press any 'character' type key.</p>
</body>
</html>
```

注意
--

在 `keypress` 事件中，按键的 Unicode 值保存在 `keyCode` 或 `charCode` 属性其中之一，不会二者同时都有。如果按下的是字符键 (例如 'a'), `charCode` 被设置为字符的代码值，并区分大小写。（即 `charCode` 会考虑 `Shift` 键是否被按下）。否则，被按下的键的代码被存储在 `keyCode` 中。

如果有一个或多个修饰键被按下，有一些复杂的规则来产生 `charCode` 的值，细节可参考 Gecko Keypress 事件 。

`charCode` 用于不会在 `keydown` 和 `keyup` 事件中被设置。这两种情况下，`keyCode` 会被设置。

要获取按键代码而不考虑是 `keyCode` 还是`charCode`, 请使用 `which` 属性。

通过输入法输入的字符，不会被设置到注册到通过 `keyCode` 和 `charCode`。 Actually with the Chinese IME I'm using, entering the IME results in a keypress event with keyCode = 229 and no other key events fire until the IME exits (which may happen after multiple characters are inputted). I'm not sure if other IME's work this way.

要查看特定按键的 `charCode` 值的列表，运行这个示例页面 Gecko DOM Reference:Examples #Example 7: Displaying Event Object Constants ，然后查看 HTML 表格结果。

规范
--

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

浏览器兼容性
------

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


KeyboardEvent.isComposing - Web API 接口参考

KeyboardEvent.isComposing
=========================

**`KeyboardEvent.isComposing`** 只读属性，返回一个 `Boolean` 值，表示该事件是否在 `compositionstart` 之后和 `compositionend` 之前被触发。

语法
--
```

var bool = event.isComposing;
```

示例
--

```js
var kbdEvent = new KeyboardEvent("syntheticKey", false);
console.log(kbdEvent.isComposing); // return false
```

规范
--

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

浏览器兼容性
------

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

参考
--

* `compositionstart` 与 `compositionend`
* `KeyboardEvent`


键盘事件 KeyboardEvent() - Web API 接口参考

键盘事件 KeyboardEvent()
====================

**`KeyboardEvent()`** 构造函数新建一个 `KeyboardEvent` 实例。

语法
--
```

 event = new KeyboardEvent(typeArg, KeyboardEventInit);
```

### 值

*typeArg*

`DOMString` 类型，表示事件名称。

*KeyboardEventInit*可选

`KeyboardEventInit` 字典，有以下几种值：

* `"key"`, 可选，默认为 `""`, `DOMString` 类型，设置 `KeyboardEvent.key` 的值。
* `"code"`, 可选，默认为 `""`, `DOMString` 类型，设置`KeyboardEvent.code` 的值。
* `"location"`, 可选，默认为 `0`, `unsigned long`类型，设置 `KeyboardEvent.location` (en-US) 的值。
* `"ctrlKey"`, 可选，默认为 `false`, `Boolean` 类型，设置 `KeyboardEvent.ctrlKey` 的值。
* `"shiftKey"`, 可选，默认为 `false`, `Boolean` 类型，设置`KeyboardEvent.shiftKey` 的值。
* `"altKey"`, 可选，默认为 `false`, `Boolean` 类型，设置 `KeyboardEvent.altKey` 的值。
* `"metaKey"`, 可选，默认为 `false`, `Boolean` 类型，设置 `KeyboardEvent.metaKey` 的值。
* `"repeat"`, 可选，默认为 `false`, `Boolean` 类型，设置 `KeyboardEvent.repeat` 的值。
* `"isComposing"`, 可选，默认为 `false`, `Boolean` 类型，设置 `KeyboardEvent.isComposing` 的值。
* `"charCode"`, 可选，默认为 `0`, `unsigned long` 类型，设置 `KeyboardEvent.charCode` (已废弃) 的值。
* `"keyCode"`, 可选，默认为 `0`, `unsigned long` 类型，设置`KeyboardEvent.keyCode` (已废弃) 的值。
* `"which"`, 可选，默认为 `0`, `unsigned long` 类型，设置`KeyboardEvent.which` (已废弃) 的值。

**备注：** `KeyboardEventInit` 字典也可以接受来自 `UIEventInit` 和 `EventInit` 的字典字段值。

规范
--

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

浏览器兼容性
------

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

参考
--

* `KeyboardEvent` 构造的相关对象的接口


KeyboardEvent.ctrlKey - Web API 接口参考

KeyboardEvent.ctrlKey
=====================

**`KeyboardEvent.ctrlKey`** 只读属性返回一个 `Boolean` 值，表示事件触发时 `control` 键是 (`true`) 否 (`false`) 按下。

语法
--
```

var ctrlKeyPressed = instanceOfKeyboardEvent.ctrlKey
```

### 返回值

布尔值

示例
--

```js
<html>
<head>
<title>ctrlKey example</title>

<script type="text/javascript">

function showChar(e){
  alert(
    "Key Pressed: " + String.fromCharCode(e.charCode) + "\n"
    + "charCode: " + e.charCode + "\n"
    + "CTRL key pressed: " + e.ctrlKey + "\n"
  );
}

</script>
</head>

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

规范
--

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

浏览器兼容性
------

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

参考
--

* `KeyboardEvent`


KeyboardEvent.shiftKey - Web API 接口参考

KeyboardEvent.shiftKey
======================

**`KeyboardEvent.shiftKey`** 只读属性返回一个 `Boolean` 值，表示事件触发时 `shift` 键是 (`true`) 否 (`false`) 按下。

语法
--
```

var shiftKeyPressed = instanceOfKeyboardEvent.shiftKey
```

### 返回值

布尔值

示例
--

```js
<html>
<head>
<title>shiftKey example</title>

<script type="text/javascript">

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>
```

规范
--

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

浏览器兼容性
------

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

参考
--

* `KeyboardEvent`


KeyboardEvent.altKey - Web API 接口参考

KeyboardEvent.altKey
====================

**`KeyboardEvent.altKey`** 只读属性返回一个 `Boolean` 值，表示事件触发时 `alt` 键 (OS X 系统上的 `Option` 或 `⌥` 键) 是 (`true`) 否 (`false`) 被按下。

语法
--
```

var altKeyPressed = instanceOfKeyboardEvent.altKey
```

### 返回值

布尔值

示例
--

```js
<html>
<head>
<title>altKey example</title>

<script type="text/javascript">

function showChar(e){
  alert(
    "Key Pressed: " + String.fromCharCode(e.charCode) + "\n"
    + "charCode: " + e.charCode + "\n"
    + "ALT key pressed: " + e.altKey + "\n"
  );
}

</script>
</head>

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

规范
--

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

浏览器兼容性
------

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

参考
--

* `KeyboardEvent`


KeyboardEvent.repeat - Web API 接口参考

KeyboardEvent.repeat
====================

\*\*`KeyboardEvent.repeat`\*\*是一个只读属性，返回一个布尔值`Boolean`，如果按键被一直按住，返回值为`true`。

语法
--
```

var repeat = event.repeat;
```

规范
--

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

浏览器兼容性
------

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


KeyboardEvent.key - Web API 接口参考

KeyboardEvent.key
=================

只读属性 **`KeyboardEvent.key`** 返回用户按下的物理按键的值。它还与 `shiftKey` 等调节性按键的状态和键盘的区域 / 和布局有关。它的值由以下因素决定：

查看所有键值列表 (en-US)

* 如果按下的键拥有可打印的内容，则返回一个非空的 Unicode 字符来代表这个键的可打印内容。
* 如果按下的键是一个控制键或特殊字符，则返回一个事先定义好的值，见预定义键值列表 (en-US)。
* 如果 `KeyboardEvent` 显示按下的键是一个死键（dead key），则键值为 `"Dead"`。
* 有些特殊键盘的键（比如多媒体键盘上用来控制媒体播放的扩展按键）在 Windows 下会触发 `WM_APPCOMMAND` 事件，而不会产生按键代码。虽然没有按键代码，这些事件将映射到 DOM 键盘事件中，并将列入 Windows 的“虚拟按键码”列表中。
* 如果按键无法识别，则返回 `"Unidentified"`。
KeyboardEvent 次序
----------------

`KeyboardEvent` 事件以一个预设的次序触发，理解这一点对于理解特定 `KeyboardEvent` 的 `key` 属性值大有帮助。对于一个给定的按键操作，`KeyboardEvent` 将假定 `Event.preventDefault` 未调用并按下面次序触发：

1. 首先触发 `keydown` 事件。如果按键长按且生成一个字符，则事件将以一个与平台实现方式相关的时间间隔持续发出，同时将只读属性 `KeyboardEvent.repeat` 设定为 `true`。
2. 如果按键生成的字符即将插入某个 `<input>`、`<textarea>` 或其他某个 `HTMLElement.contentEditable` 设为 true 的元素，则依次触发 `beforeinput`、`input` 事件。注意某些实现中若支持 `keypress` 事件则可能将其触发。当按键长按时重复触发。
3. 当按键松开时触发 `keyup` 事件。操作结束。

在次序 1、3 中，`KeyboardEvent.key` 属性按照事先定义的规则设定为恰当的值。

KeyboardEvent 次序示例
------------------

考虑使用美国或英国键盘布局生成的点击 `shiftKey` 和一个未知的 `key 2` 时的事件次序。

请检测以下两个测试用例：

1. 按下并长按 `shift` 键，然后按下 `key 2` 并松开。下一步，松开 `shift` 键。
2. 按下并长按 `shift` 键，然后按下并长按 `key 2`。然后松开 shift 键，最后松开 `key 2`。
### HTML

```html
<div class="fx">
  <div>
    <textarea rows="5" name="test-target" id="test-target"></textarea>
    <button type="button" name="btn-reset" id="btn-reset">Reset</button>
  </div>
  <div class="flex">
    <pre id="console-log"></pre>
  </div>
</div>
```

### CSS

```css
.fx {
  -webkit-display: flex;
  display: flex;
  margin-left: -20px;
  margin-right: -20px;
}

.fx > div {
  padding-left: 20px;
  padding-right: 20px;
}

.fx > div:first-child {
  width: 30%;
}

.flex {
  -webkit-flex: 1;
  flex: 1;
}

#test-target {
  display: block;
  width: 100%;
  margin-bottom: 10px;
}
```

### JavaScript

```js
let textarea = document.getElementById("test-target"),
  consoleLog = document.getElementById("console-log"),
  btnReset = document.getElementById("btn-reset");

function logMessage(message) {
  consoleLog.innerHTML += `${message}<br>`;
}

textarea.addEventListener("keydown", (e) => {
  if (!e.repeat) {
    logMessage(`按下 "${e.key}" 键 [事件：keydown]`);
  } else {
    logMessage(`重复 "${e.key}" 键 [事件：keydown]`);
  }
});

textarea.addEventListener("beforeinput", (e) => {
  logMessage(`即将输入 "${e.data}" 键 [事件：beforeinput]`);
});

textarea.addEventListener("input", (e) => {
  logMessage(`输入 "${e.data}" 键 [事件：input]`);
});

textarea.addEventListener("keyup", (e) => {
  logMessage(`释放 "${e.key}" 键 [事件：keyup]`);
});

btnReset.addEventListener("click", (e) => {
  let child = consoleLog.firstChild;
  while (child) {
    consoleLog.removeChild(child);
    child = consoleLog.firstChild;
  }
  textarea.value = "";
});
```

### 结果

### 用例 1

当按下 shift 键时，首先触发 `keydown` 事件，然后将 `key` 属性的值设为 `"Shift"` 字符串。如果继续长按 shift 键，由于不会生成字符按键值，`keydown` 事件不会继续重复触发。

当按下 `key 2` 时，另一个 `keydown` 事件将会为这个新的按键动作触发，若使用的是美式键盘，它的 `key` 属性将被设为 `"@"` 字符，若为英式键盘，则会设为 `"""` 字符。这是因为 `key` 属性 `"shift"` 处于激活状态。由于生成了一个字符的按键值，`beforeinput` 和 `input` 事件随后触发。

松开 `key 2` 时，`keyup` 事件将触发，`key` 属性将会为不同键盘布局设定合适的字符值，比如 `"@"`、`"""`。

最后在松开 shift 键时，另一个 `keyup` 事件触发，`key` 值将保持 `"Shift"` 不变。

### 用例 2

当按下 shift 键时，首先触发 `keydown` 事件，然后将 `key` 属性的值设为 `"Shift"` 字符串。如果继续长按 shift 键，由于不会生成字符按键值，`keydown` 事件不会继续重复触发。

当按下 `key 2` 时，另一个 `keydown` 事件将会为这个新的按键动作触发，若使用的是美式键盘，它的 `key` 属性将被设为 `"@"` 字符，若为英式键盘，则会设为 `"""` 字符。这是因上档键处于激活状态。由于生成了一个字符的按键值，`beforeinput` 和 `input` 事件随后触发。如果继续长按 `2` 键，则 `keydown` 事件将持续重复触发，同时将 `KeyboardEvent.repeat` 属性设置为 `true`。`beforeinput` 和 `input` 事件也将持续重复触发。

当松开 shift 键时，`keyup` 事件随之触发，且 `key` 属性保留为 `"Shift"`。此时请注意为 `key 2` 长按触发的重复 `keydown` 事件的 `key` 值会变成 `"2"`，因为上档键不再处于激活状态。`beforeinput` 与 `input` 事件的 `InputEvent.data` 属性同理。

最终 `key 2` 松开，`keyup` 事件触发，但两种键盘布局的 `key` 属性均为 `"2"`。就是因为没有激活上档键。

示例
--

这个示例使用 `EventTarget.addEventListener()` 监听 `keydown` 事件。当我们事件触发时，将检测按键的值是否为代码所关注，如果是，就进行某项操作。（可能是给飞船转向，或者是调整电子表格中选中单元格的位置。）

```js
window.addEventListener(
  "keydown",
  function (event) {
    if (event.defaultPrevented) {
      return; // 如果事件已经在进行中，则不做任何事。
    }

    switch (event.key) {
      case "ArrowUp":
        // 按“↑”方向键时要做的事。
        break;
      case "ArrowDown":
        // 按“↓”方向键时要做的事。
        break;
      case "ArrowLeft":
        // 按“←”方向键时要做的事。
        break;
      case "ArrowRight":
        // 按“→”方向键时要做的事。
        break;
      case "Enter":
        // 按“回车”键时要做的事。
        break;
      case "Escape":
        // 按“ESC”键时要做的事。
        break;
      default:
        return; // 什么都没按就退出吧。
    }

    // 取消默认动作，从而避免处理两次。
    event.preventDefault();
  },
  true,
);
```

规范
--

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

浏览器兼容性
------

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


KeyboardEvent.code - Web API 接口参考

KeyboardEvent.code
==================

`KeyboardEvent.code`属性表示键盘上的物理键（与按键生成的字符相对）。换句话说，此属性返回一个值，该值不会被键盘布局或修饰键的状态改变。

如果输入设备不是物理键盘，而是虚拟键盘或辅助功能设备，则浏览器将设置返回值，以尽可能地匹配物理键盘所发生的情况，从而最大限度地提高物理和虚拟输入设备之间的兼容性。

当你想要根据输入设备上的物理位置处理键而不是与这些键相关联的字符时，此属性非常有用;这在编写代码来处理游戏输入时尤为常见，这些游戏使用键盘上的键来模拟类似游戏板的环境。但请注意，你无法使用 `KeyboardEvent.code`报告的值来确定击键生成的字符，因为键码的名称可能与按键上打印的实际字符或按下键时计算机生成的字符不匹配。

例如，QWERTY 布局键盘上的“`q`”键返回的`code`是“`KeyQ`”，但 Dvorak 键盘上的“`'`”键和 AZERTY 键盘上的“`a`”键也返回的相同`code`值。这使得如果用户没有使用预期的键盘布局，则无法使用`code`值来确定用户按键的名称。

要确定哪个字符与键事件对应，请改用`KeyboardEvent.key`属性。

示例
--

### 练习 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"></div>
```

#### CSS

```css
#output {
  font-family: Arial, Helvetica, sans-serif;
  border: 1px solid black;
}
```

#### JavaScript

```js
window.addEventListener(
  "keydown",
  function (event) {
    let str =
      "KeyboardEvent: key='" + event.key + "' | code='" + event.code + "'";
    let el = document.createElement("span");
    el.innerHTML = str + "<br/>";

    document.getElementById("output").appendChild(el);
  },
  true,
);
```

#### Try it out

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

### Handle keyboard events in a game

This example establishes an event listener for `keydown` events which handles keyboard input for a game which 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">
  <polygon id="spaceship" points="15,0 0,30 30,30" />
</svg>
<script>
 refresh();
</script>
```

#### CSS

```css
.world {
  margin: 0px;
  padding: 0px;
  background-color: black;
  width: 400px;
  height: 400px;
}

#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` and `turnRate` are the number of pixels forward and backward each keystroke moves the ship and 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);
}
```

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",
  function (event) {
    if (event.preventDefaulted) {
      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();

    // Consume the event so it doesn't get handled twice
    event.preventDefault();
  },
  true,
);
```

#### Try it out

To ensure that keystrokes go to the sample code, click inside 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.

Specification
-------------

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

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

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

Code values
-----------

The following tables show what code values are used for each native scancode or virtual keycode on major platforms. Because some browsers choose to interpret physical keys differently, there are some differences in which keys map to which codes. These tables show those variations when known.

### Code values on Windows

This table shows the Windows scan codes representing keys and the `KeyboardEvent.code` values which correspond to those hardware keys. Only keys which generate scan codes on Windows are listed.

|  | **`KeyboardEvent.code`** value |
| --- | --- |
| Code | Firefox | Chrome |
| `0x0000` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0001` | `"Escape"` | `"Escape"` |
| `0x0002` | `"Digit0"` | `"Digit0"` |
| `0x0003` | `"Digit1"` | `"Digit1"` |
| `0x0004` | `"Digit2"` | `"Digit2"` |
| `0x0005` | `"Digit3"` | `"Digit3"` |
| `0x0006` | `"Digit4"` | `"Digit4"` |
| `0x0007` | `"Digit5"` | `"Digit5"` |
| `0x0008` | `"Digit6"` | `"Digit6"` |
| `0x0009` | `"Digit7"` | `"Digit7"` |
| `0x000A` | `"Digit8"` | `"Digit8"` |
| `0x000B` | `"Digit9"` | `"Digit9"` |
| `0x000C` | `"Minus"` | `"Minus"` |
| `0x000D` | `"Equal"` | `"Equal"` |
| `0x000E` | `"Backspace"` | `"Backspace"` |
| `0x000F` | `"Tab"` | `"Tab"` |
| `0x0010` | `"KeyQ"` | `"KeyQ"` |
| `0x0011` | `"KeyW"` | `"KeyW"` |
| `0x0012` | `"KeyE"` | `"KeyE"` |
| `0x0013` | `"KeyR"` | `"KeyR"` |
| `0x0014` | `"KeyT"` | `"KeyT"` |
| `0x0015` | `"KeyY"` | `"KeyY"` |
| `0x0016` | `"KeyU"` | `"KeyU"` |
| `0x0017` | `"KeyI"` | `"KeyI"` |
| `0x0018` | `"KeyO"` | `"KeyO"` |
| `0x0019` | `"KeyP"` | `"KeyP"` |
| `0x001A` | `"BracketLeft"` | `"BracketLeft"` |
| `0x001B` | `"BracketRight"` | `"BracketRight"` |
| `0x001C` | `"Enter"` | `"Enter"` |
| `0x001D` | `"ControlLeft"` | `"ControlLeft"` |
| `0x001E` | `"KeyA"` | `"KeyA"` |
| `0x001F` | `"KeyS"` | `"KeyS"` |
| `0x0020` | `"KeyD"` | `"KeyD"` |
| `0x0021` | `"KeyF"` | `"KeyF"` |
| `0x0022` | `"KeyG"` | `"KeyG"` |
| `0x0023` | `"KeyH"` | `"KeyH"` |
| `0x0024` | `"KeyJ"` | `"KeyJ"` |
| `0x0025` | `"KeyK"` | `"KeyK"` |
| `0x0026` | `"KeyL"` | `"KeyL"` |
| `0x0027` | `"Semicolon"` | `"Semicolon"` |
| `0x0028` | `"Quote"` | `"Quote"` |
| `0x0029` | `"Backquote"` | `"Backquote"` |
| `0x002A` | `"ShiftLeft"` | `"ShiftLeft"` |
| `0x002B` | `"Backslash"` | `"Backslash"` |
| `0x002C` | `"KeyZ"` | `"KeyZ"` |
| `0x002D` | `"KeyX"` | `"KeyX"` |
| `0x002E` | `"KeyC"` | `"KeyC"` |
| `0x002F` | `"KeyV"` | `"KeyV"` |
| `0x0030` | `"KeyB"` | `"KeyB"` |
| `0x0031` | `"KeyN"` | `"KeyN"` |
| `0x0032` | `"KeyM"` | `"KeyM"` |
| `0x0033` | `"Comma"` | `"Comma"` |
| `0x0034` | `"Period"` | `"Period"` |
| `0x0035` | `"Slash"` | `"Slash"` |
| `0x0036` | `"ShiftRight"` | `"ShiftRight"` |
| `0x0037` | `"NumpadMultiply"` | `"NumpadMultiply"` |
| `0x0038` | `"AltLeft"` | `"AltLeft"` |
| `0x0039` | `"Space"` | `"Space"` |
| `0x003A` | `"CapsLock"` | `"CapsLock"` |
| `0x003B` | `"F1"` | `"F1"` |
| `0x003C` | `"F2"` | `"F2"` |
| `0x003D` | `"F3"` | `"F3"` |
| `0x003E` | `"F4"` | `"F4"` |
| `0x003F` | `"F5"` | `"F5"` |
| `0x0040` | `"F6"` | `"F6"` |
| `0x0041` | `"F7"` | `"F7"` |
| `0x0042` | `"F8"` | `"F8"` |
| `0x0043` | `"F9"` | `"F9"` |
| `0x0044` | `"F10"` | `"F10"` |
| `0x0045` | `"Pause"` | `"Pause"` |
| `0x0046` | `"ScrollLock"` | `"ScrollLock"` |
| `0x0047` | `"Numpad7"` | `"Numpad7"` |
| `0x0048` | `"Numpad8"` | `"Numpad8"` |
| `0x0049` | `"Numpad9"` | `"Numpad9"` |
| `0x004A` | `"NumpadSubtract"` | `"NumpadSubtract"` |
| `0x004B` | `"Numpad4"` | `"Numpad4"` |
| `0x004C` | `"Numpad5"` | `"Numpad5"` |
| `0x004D` | `"Numpad6"` | `"Numpad6"` |
| `0x004E` | `"NumpadAdd"` | `"NumpadAdd"` |
| `0x004F` | `"Numpad1"` | `"Numpad1"` |
| `0x0050` | `"Numpad2"` | `"Numpad2"` |
| `0x0051` | `"Numpad3"` | `"Numpad3"` |
| `0x0052` | `"Numpad0"` | `"Numpad0"` |
| `0x0053` | `"NumpadDecimal"` | `"NumpadDecimal"` |
| `0x0054 (`Alt` + `PrintScreen`)` | `"PrintScreen"` | `""` |
| `0x0055` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0056` | `"IntlBackslash"` | `"IntlBackslash"` |
| `0x0057` | `"F11"` | `"F11"` |
| `0x0058` | `"F12"` | `"F12"` |
| `0x0059` | `"NumpadEqual"` | `""` |
| `0x005A` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x005B` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"F13"` |
| `0x005C` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"F14"` |
| `0x005D` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"F15"` |
| `0x005E` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x005F` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0060` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0061` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0062` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0063` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"F16"` |
| `0x0064` | `"F13"` | `"F17"` |
| `0x0065` | `"F14"` | `"F18"` |
| `0x0066` | `"F15"` | `"F19"` |
| `0x0067` | `"F16"` | `"F20"` |
| `0x0068` | `"F17"` | `"F21"` |
| `0x0069` | `"F18"` | `"F22"` |
| `0x006A` | `"F19"` | `"F23"` |
| `0x006B` | `"F20"` | `"F24"` |
| `0x006C` | `"F21"` | `""` |
| `0x006D` | `"F22"` | `""` |
| `0x006E` | `"F23"` | `""` |
| `0x006F` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0070` | `"KanaMode"` | `""` |
| `0x0071` (`Hanja` key without Korean keyboard
 layout)
  | `"Lang2"` | `""` |
| `0x0072` (`Han/Yeong` key without Korean keyboard
 layout)
  | `"Lang1"` | `""` |
| `0x0073` | `"IntlRo"` | `""` |
| `0x0074`, `0x0075` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0076` | `"F24"` | `""` |
| `0x0077`, `0x0078` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x0079` | `"Convert"` | `""` |
| `0x007A` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x007B` | `"NonConvert"` | `""` |
| `0x007C` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x007D` | `"IntlYen"` | `"IntlYen"` |
| `0x007E` | `"NumpadComma"` | `""` |
| `0x007F` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE000` ～ `0xE007` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE008` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"Undo"` |
| `0xE009` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE00A` | `""` | `"Paste"` |
| `0xE00B` ～ `0xE00F` | "" | `""` |
| `0xE010` | `"MediaTrackPrevious"` | `"MediaTrackPrevious"` |
| `0xE011` ～ `0xE016` | `""` | `""` |
| `0xE017` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"Cut"` |
| `0xE018` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"Copy"` |
| `0xE019` | `"MediaTrackNext"` | `"MediaTrackNext"` |
| `0xE01A, 0xE01B` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE01C` | `"NumpadEnter"` | `"NumpadEnter"` |
| `0xE01D` | `"ControlRight"` | `"ControlRight"` |
| `0xE01E` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"LaunchMail"` |
| `0xE01F` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE020` | `"AudioVolumeMute"` (was `"VolumeMute"` until
 Firefox 49)
  | `"AudioVolumeMute"` (was `"VolumeMute"` until
 Chrome 50)
  |
| `0xE021` | `"LaunchApp2"` | `""` |
| `0xE022` | `"MediaPlayPause"` | `"MediaPlayPause"` |
| `0xE023` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE024` | `"MediaStop"` | `"MediaStop"` |
| `0xE025` ～ `0xE02B` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE02C` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"Eject"` |
| `0xE02D` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE02E` | `"AudioVolumeDown"`

 Prior to Firefox 48, this key code is reported as
 `"VolumeDown"`.

 | `"VolumeDown"` (was `"VolumeDown"` until Chrome
 50)
  |
| `0xE02F` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE030` | `"AudioVolumeUp"`

 Prior to Firefox 48, this key code is reported as
 `"VolumeUp"`.

 | `"VolumeUp"` (was `"VolumeUp"` until Chrome 50) |
| `0xE031` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE032` | `"BrowserHome"` | `"BrowserHome"` |
| `0xE033`, `0xE034` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE035` | `"NumpadDivide"` | `"NumpadDivide"` |
| `0xE036` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE037` | `"PrintScreen"` | `"PrintScreen"` |
| `0xE038` | `"AltRight"` | `"AltRight"` |
| `0xE039`, `0xE03A` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE03B` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"Help"` |
| `0xE03C`～ `0xE044` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE045` | `"NumLock"` | `"NumLock"` |
| `0xE046` (`Ctrl` + `Pause`) | `"Pause"` | `"Pause"` |
| `0xE047` | `"Home"` | `"Home"` |
| `0xE048` | `"ArrowUp"` | `"ArrowUp"` |
| `0xE049` | `"PageUp"` | `"PageUp"` |
| `0xE04A` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE04B` | `"ArrowLeft"` | `"ArrowLeft"` |
| `0xE04C` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE04D` | `"ArrowRight"` | `"ArrowRight"` |
| `0xE04E` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE04F` | `"End"` | `"End"` |
| `0xE050` | `"ArrowDown"` | `"ArrowDown"` |
| `0xE051` | `"PageDown"` | `"PageDown"` |
| `0xE052` | `"Insert"` | `"Insert"` |
| `0xE053` | `"Delete"` | `"Delete"` |
| `0xE054` ～ `0xE05A` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE05B` | `"MetaLeft"`

 Prior to Firefox 48, this key code was reported as
 `"OSLeft"`.

 | `"OSLeft"` |
| `0xE05C` | `"MetaRight"`

 Prior to Firefox 48, this key code was reported as
 `"OSRight"`.

 | `"OSRight"` |
| `0xE05D` | `"ContextMenu"` | `"ContextMenu"` |
| `0xE05E` | `"Power"` | `""` |
| `0xE05F` ～ `0xE064` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE065` | `"BrowserSearch"` | `"BrowserSearch"` |
| `0xE066` | `"BrowserFavorites"` | `"BrowserFavorites"` |
| `0xE067` | `"BrowserRefresh"` | `"BrowserRefresh"` |
| `0xE068` | `"BrowserStop"` | `"BrowserStop"` |
| `0xE069` | `"BrowserForward"` | `"BrowserForward"` |
| `0xE06A` | `"BrowserBack"` | `"BrowserBack"` |
| `0xE06B` | `"LaunchApp1"` | `""` |
| `0xE06C` | `"LaunchMail"` | `""` |
| `0xE06D` | `"LaunchMediaPlayer"` (`"MediaSelect"` prior to
 Firefox 49)
  | `""` |
| `0xE06E ～ 0xE0F0` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0xE0F1` (`Hanja` key with Korean keyboard layout) | `"Lang2"` | `""` |
| `0xE0F2` (`Han/Yeong` key with Korean keyboard
 layout)
  | `"Lang1"` | `""` |

### Code values on Mac

On Mac OS X, it's hard to get scancode or something which can distinguish a physical key from a key event. Therefore, Gecko always maps `code` value from the virtual keycode.

| Virtual keycode | Gecko (32) | Chromium (48) |
| --- | --- | --- |
| `kVK_ANSI_A (0x00)` | `"KeyA"` | `"KeyA"` |
| `kVK_ANSI_S (0x01)` | `"KeyS"` | `"KeyS"` |
| `kVK_ANSI_D (0x02)` | `"KeyD"` | `"KeyD"` |
| `kVK_ANSI_F (0x03)` | `"KeyF"` | `"KeyF"` |
| `kVK_ANSI_H (0x04)` | `"KeyH"` | `"KeyH"` |
| `kVK_ANSI_G (0x05)` | `"KeyG"` | `"KeyG"` |
| `kVK_ANSI_Z (0x06)` | `"KeyZ"` | `"KeyZ"` |
| `kVK_ANSI_X (0x07)` | `"KeyX"` | `"KeyX"` |
| `kVK_ANSI_C (0x08)` | `"KeyC"` | `"KeyC"` |
| `kVK_ANSI_V (0x09)` | `"KeyV"` | `"KeyV"` |
| `kVK_ISO_Section (0x0A)` | `"IntlBackslash"` | `"IntlBackslash"` |
| `kVK_ANSI_B (0x0B)` | `"KeyB"` | `"KeyB"` |
| `kVK_ANSI_Q (0x0C)` | `"KeyQ"` | `"KeyQ"` |
| `kVK_ANSI_W (0x0D)` | `"KeyW"` | `"KeyW"` |
| `kVK_ANSI_E (0x0E)` | `"KeyE"` | `"KeyE"` |
| `kVK_ANSI_R (0x0F)` | `"KeyR"` | `"KeyR"` |
| `kVK_ANSI_Y (0x10)` | `"KeyY"` | `"KeyY"` |
| `kVK_ANSI_T (0x11)` | `"KeyT"` | `"KeyT"` |
| `kVK_ANSI_1 (0x12)` | `"Digit1"` | `"Digit1"` |
| `kVK_ANSI_2 (0x13)` | `"Digit2"` | `"Digit2"` |
| `kVK_ANSI_3 (0x14)` | `"Digit3"` | `"Digit3"` |
| `kVK_ANSI_4 (0x15)` | `"Digit4"` | `"Digit4"` |
| `kVK_ANSI_6 (0x16)` | `"Digit6"` | `"Digit6"` |
| `kVK_ANSI_5 (0x17)` | `"Digit7"` | `"Digit7"` |
| `kVK_ANSI_Equal (0x18)` | `"Equal"` | `"Equal"` |
| `kVK_ANSI_9 (0x19)` | `"Digit9"` | `"Digit9"` |
| `kVK_ANSI_7 (0x1A)` | `"Digit7"` | `"Digit7"` |
| `kVK_ANSI_Minus (0x1B)` | `"Minus"` | `"Minus"` |
| `kVK_ANSI_8 (0x1C)` | `"Digit8"` | `"Digit8"` |
| `kVK_ANSI_0 (0x1D)` | `"Digit0"` | `"Digit0"` |
| `kVK_ANSI_RightBracket (0x1E)` | `"BracketRight"` | `"BracketRight"` |
| `kVK_ANSI_O (0x1F)` | `"KeyO"` | `"KeyO"` |
| `kVK_ANSI_U (0x20)` | `"KeyU"` | `"KeyU"` |
| `kVK_ANSI_LeftBracket (0x21)` | `"BracketLeft"` | `"BracketLeft"` |
| `kVK_ANSI_I (0x22)` | `"KeyI"` | `"KeyI"` |
| `kVK_ANSI_P (0x23)` | `"KeyP"` | `"KeyP"` |
| `kVK_Return (0x24)` | `"Enter"` | `"Enter"` |
| `kVK_ANSI_L (0x25)` | `"KeyL"` | `"KeyL"` |
| `kVK_ANSI_J (0x26)` | `"KeyJ"` | `"KeyJ"` |
| `kVK_ANSI_Quote (0x27)` | `"Quote"` | `"Quote"` |
| `kVK_ANSI_K (0x28)` | `"KeyK"` | `"KeyK"` |
| `kVK_ANSI_Semicolon (0x29)` | `"Semicolon"` | `"Semicolon"` |
| `kVK_Tab (0x30)` | `"Tab"` | `"Tab"` |
| `kVK_Space (0x31)` | `"Space"` | `"Space"` |
| `kVK_ANSI_Grave (0x32)` | `"Backquote"` | `"Backquote"` |
| `kVK_Delete (0x33)` | `"Backspace"` | `"Backspace"` |
| Enter key on keypad of PowerBook (`0x34`) | `"NumpadEnter"` | `""` |
| `kVK_Escape (0x35)` | `"Escape"` | `"Escape"` |
| right-command key (`0x36`) | `"OSRight"` | `"OSRight"` |
| `kVK_Command (0x37)` | `"OSLeft"` | `"OSLeft"` |
| `kVK_Shift (0x38)` | `"ShiftLeft"` | `"ShiftLeft"` |
| `kVK_CapsLock (0x39)` | `"CapsLock"` | `"CapsLock"` |
| `kVK_Option (0x3A)` | `"AltLeft"` | `"AltLeft"` |
| `kVK_Control (0x3B)` | `"ControlLeft"` | `"ControlLeft"` |
| `kVK_RightShift (0x3C)` | `"ShiftRight"` | `"ShiftRight"` |
| `kVK_RightOption (0x3D)` | `"AltRight"` | `"AltRight"` |
| `kVK_RightControl (0x3E)` | `"ControlRight"` | `"ControlRight"` |
| `kVK_Function (0x3F)` | `"Fn"` *(no events fired actually)* | `""` *(no events fired actually)* |
| `kVK_F17 (0x40)` | `"F17"` | `"F17"` |
| `kVK_ANSI_KeypadDecimal (0x41)` | `"NumpadDecimal"` | `"NumpadDecimal"` |
| `kVK_ANSI_KeypadMultiply (0x43)` | `"NumpadMultiply"` | `"NumpadMultiply"` |
| `kVK_ANSI_KeypadPlus (0x45)` | `"NumpadAdd"` | `"NumpadAdd"` |
| `kVK_ANSI_KeypadClear (0x47)` | `"NumLock"` | `"NumLock"` |
| `kVK_VolumeUp (0x48)` | `"AudioVolumeUp"` (was `"VolumeUp"` until Firefox
 48)
  | `"AudioVolumeUp"` (was `"VolumeUp"` until Chrome
 50)
  |
| `kVK_VolumeDown (0x49)` | `"AudioVolumeDown"` (was `"VolumeDown"` until
 Firefox 49)
  | `"AudioVolumeDown"` (was `"VolumeDown"` until
 Chrome 50)
  |
| `kVK_Mute (0x4A)` | `"AudioVolumeMute"` (was `"VolumeMute"` until
 Firefox 49)
  | `"AudioVolumeMute"` (was `"VolumeMute"` until
 Chrome 50)
  |
| `kVK_ANSI_KeypadDivide (0x4B)` | `"NumpadDivide"` | `"NumpadDivide"` |
| `kVK_ANSI_KeypadEnter (0x4C)` | `"NumpadEnter"` | `"NumpadEnter"` |
| `kVK_ANSI_KeypadMinus (0x4E)` | `"NumpadSubtract"` | `"NumpadSubtract"` |
| `kVK_F18 (0x4F)` | `"F18"` | `"F18"` |
| `kVK_F19 (0x50)` | `"F19"` | `"F19"` |
| `kVK_ANSI_KeypadEquals (0x51)` | `"NumpadEqual"` | `"NumpadEqual"` |
| `kVK_ANSI_Keypad0 (0x52)` | `"Numpad0"` | `"Numpad0"` |
| `kVK_ANSI_Keypad1 (0x53)` | `"Numpad1"` | `"Numpad1"` |
| `kVK_ANSI_Keypad2 (0x54)` | `"Numpad2"` | `"Numpad2"` |
| `kVK_ANSI_Keypad3 (0x55)` | `"Numpad3"` | `"Numpad3"` |
| `kVK_ANSI_Keypad4 (0x56)` | `"Numpad4"` | `"Numpad4"` |
| `kVK_ANSI_Keypad5 (0x57)` | `"Numpad5"` | `"Numpad5"` |
| `kVK_ANSI_Keypad6 (0x58)` | `"Numpad6"` | `"Numpad6"` |
| `kVK_ANSI_Keypad7 (0x59)` | `"Numpad7"` | `"Numpad7"` |
| `kVK_F20 (0x5A)` | `"F20"` | `"F20"` |
| `kVK_ANSI_Keypad8 (0x5B)` | `"Numpad8"` | `"Numpad8"` |
| `kVK_ANSI_Keypad9 (0x5C)` | `"Numpad9"` | `"Numpad9"` |
| `kVK_JIS_Yen (0x5D)` | `"IntlYen"` | `"IntlYen"` |
| `kVK_JIS_Underscore (0x5E)` | `"IntlRo"` | `"IntlRo"` |
| `kVK_JIS_KeypadComma (0x5F)` | `"NumpadComma"` | `"NumpadComma"` |
| `kVK_F5 (0x60)` | `"F5"` | `"F5"` |
| `kVK_F6 (0x61)` | `"F6"` | `"F6"` |
| `kVK_F7 (0x62)` | `"F7"` | `"F7"` |
| `kVK_F3 (0x63)` | `"F3"` | `"F3"` |
| `kVK_F8 (0x64)` | `"F8"` | `"F8"` |
| `kVK_F9 (0x65)` | `"F9"` | `"F9"` |
| `kVK_JIS_Eisu (0x66)` | `"Lang2"`

 Prior to
 Firefox 37 (en-US),
 this key incorrectly generated the key code
 `"RomanCharacters"`.

 | `""` *(no events fired actually)* |
| `kVK_F11 (0x67)` | `"F11"` | `"F11"` |
| `kVK_JIS_Kana (0x68)` | `"Lang1"` | `"KanaMode"` *(no events fired actually)* |
| `kVK_F13 (0x69)` | `"F13"` | `"F13"` |
| `kVK_F16 (0x6A)` | `"F16"` | `"F16"` |
| `kVK_F14 (0x6B)` | `"F14"` | `"F14"` |
| `kVK_F10 (0x6D)` | `"F10"` | `"F10"` |
| `kVK_F12 (0x6F)` | `"F12"` | `"F12"` |
| `kVK_F15 (0x71)` | `"F15"` | `"F15"` |
| `kVK_Help (0x72)` | `"Help"` | `"Insert"` |
| `kVK_Home (0x73)` | `"Home"` | `"Home"` |
| `kVK_PageUp (0x74)` | `"PageUp"` | `"PageUp"` |
| `kVK_ForwardDelete (0x75)` | `"Delete"` | `"Delete"` |
| `kVK_F4 (0x76)` | `"F4"` | `"F4"` |
| `kVK_End (0x77)` | `"End"` | `"End"` |
| `kVK_F2 (0x78)` | `"F2"` | `"F2"` |
| `kVK_PageDown (0x79)` | `"PageDown"` | `"PageDown"` |
| `kVK_F1 (0x7A)` | `"F1"` | `"F1"` |
| `kVK_LeftArrow (0x7B)` | `"ArrowLeft"` | `"ArrowLeft"` |
| `kVK_RightArrow (0x7C)` | `"ArrowRight"` | `"ArrowRight"` |
| `kVK_DownArrow (0x7D)` | `"ArrowDown"` | `"ArrowDown"` |
| `kVK_UpArrow (0x7E)` | `"ArrowUp"` | `"ArrowUp"` |

### Code values on Linux (X11) (When scancode is available)

Note that X has too many keys and some of them are not testable with usual keyboard. So, following table is created from source code which maps from scancode to code value.

| scancode (hardware\_keycode) | Gecko (32) | Chromium (44) |
| --- | --- | --- |
| `0x0009` | `"Escape"` | `"Escape"` |
| `0x000A` | `"Digit1"` | `"Digit1"` |
| `0x000B` | `"Digit2"` | `"Digit2"` |
| `0x000C` | `"Digit3"` | `"Digit3"` |
| `0x000D` | `"Digit4"` | `"Digit4"` |
| `0x000E` | `"Digit5"` | `"Digit5"` |
| `0x000F` | `"Digit6"` | `"Digit6"` |
| `0x0010` | `"Digit7"` | `"Digit7"` |
| `0x0011` | `"Digit8"` | `"Digit8"` |
| `0x0012` | `"Digit9"` | `"Digit9"` |
| `0x0013` | `"Digit0"` | `"Digit0"` |
| `0x0014` | `"Minus"` | `"Minus"` |
| `0x0015` | `"Equal"` | `"Equal"` |
| `0x0016` | `"Backspace"` | `"Backspace"` |
| `0x0017` | `"Tab"` | `"Tab"` |
| `0x0018` | `"KeyQ"` | `"KeyQ"` |
| `0x0019` | `"KeyW"` | `"KeyW"` |
| `0x001A` | `"KeyE"` | `"KeyE"` |
| `0x001B` | `"KeyR"` | `"KeyR"` |
| `0x001C` | `"KeyT"` | `"KeyT"` |
| `0x001D` | `"KeyY"` | `"KeyY"` |
| `0x001E` | `"KeyU"` | `"KeyU"` |
| `0x001F` | `"KeyI"` | `"KeyI"` |
| `0x0020` | `"KeyO"` | `"KeyO"` |
| `0x0021` | `"KeyP"` | `"KeyP"` |
| `0x0022` | `"BracketLeft"` | `"BracketLeft"` |
| `0x0023` | `"BracketRight"` | `"BracketRight"` |
| `0x0024` | `"Enter"` | `"Enter"` |
| `0x0025` | `"ControlLeft"` | `"ControlLeft"` |
| `0x0026` | `"KeyA"` | `"KeyA"` |
| `0x0027` | `"KeyS"` | `"KeyS"` |
| `0x0028` | `"KeyD"` | `"KeyD"` |
| `0x0029` | `"KeyF"` | `"KeyF"` |
| `0x002A` | `"KeyG"` | `"KeyG"` |
| `0x002B` | `"KeyH"` | `"KeyH"` |
| `0x002C` | `"KeyJ"` | `"KeyJ"` |
| `0x002D` | `"KeyK"` | `"KeyK"` |
| `0x002E` | `"KeyL"` | `"KeyL"` |
| `0x002F` | `"Semicolon"` | `"Semicolon"` |
| `0x0030` | `"Quote"` | `"Quote"` |
| `0x0031` | `"Backquote"` | `"Backquote"` |
| `0x0032` | `"ShiftLeft"` | `"ShiftLeft"` |
| `0x0033` | `"Backslash"` | `"Backslash"` |
| `0x0034` | `"KeyZ"` | `"KeyZ"` |
| `0x0035` | `"KeyX"` | `"KeyX"` |
| `0x0036` | `"KeyC"` | `"KeyC"` |
| `0x0037` | `"KeyV"` | `"KeyV"` |
| `0x0038` | `"KeyB"` | `"KeyB"` |
| `0x0039` | `"KeyN"` | `"KeyN"` |
| `0x003A` | `"KeyM"` | `"KeyM"` |
| `0x003B` | `"Comma"` | `"Comma"` |
| `0x003C` | `"Period"` | `"Period"` |
| `0x003D` | `"Slash"` | `"Slash"` |
| `0x003E` | `"ShiftRight"` | `"ShiftRight"` |
| `0x003F` | `"NumpadMultiply"` | `"NumpadMultiply"` |
| `0x0040` | `"AltLeft"` | `"AltLeft"` |
| `0x0041` | `"Space"` | `"Space"` |
| `0x0042` | `"CapsLock"` | `"CapsLock"` |
| `0x0043` | `"F1"` | `"F1"` |
| `0x0044` | `"F2"` | `"F2"` |
| `0x0045` | `"F3"` | `"F3"` |
| `0x0046` | `"F4"` | `"F4"` |
| `0x0047` | `"F5"` | `"F5"` |
| `0x0048` | `"F6"` | `"F6"` |
| `0x0049` | `"F7"` | `"F7"` |
| `0x004A` | `"F8"` | `"F8"` |
| `0x004B` | `"F9"` | `"F9"` |
| `0x004C` | `"F10"` | `"F10"` |
| `0x004D` | `"NumLock"` | `"NumLock"` |
| `0x004E` | `"ScrollLock"` | `"ScrollLock"` |
| `0x004F` | `"Numpad7"` | `"Numpad7"` |
| `0x0050` | `"Numpad8"` | `"Numpad8"` |
| `0x0051` | `"Numpad9"` | `"Numpad9"` |
| `0x0052` | `"NumpadSubtract"` | `"NumpadSubtract"` |
| `0x0053` | `"Numpad4"` | `"Numpad4"` |
| `0x0054` | `"Numpad5"` | `"Numpad5"` |
| `0x0055` | `"Numpad6"` | `"Numpad6"` |
| `0x0056` | `"NumpadAdd"` | `"NumpadAdd"` |
| `0x0057` | `"Numpad1"` | `"Numpad1"` |
| `0x0058` | `"Numpad2"` | `"Numpad2"` |
| `0x0059` | `"Numpad3"` | `"Numpad3"` |
| `0x005A` | `"Numpad0"` | `"Numpad0"` |
| `0x005B` | `"NumpadDecimal"` | `"NumpadDecimal"` |
| `0x005C`, `0x005D` | `"Unidentified"` | `""` |
| `0x005E` | `"IntlBackslash"` | `"IntlBackslash"` |
| `0x005F` | `"F11"` | `"F11"` |
| `0x0060` | `"F12"` | `"F12"` |
| `0x0061` | `"IntlRo"` | `"IntlRo"` |
| `0x0062`, `0x0063` | `"Unidentified"` | `""` |
| `0x0064` | `"Convert"` | `"Convert"` |
| `0x0065` | `"KanaMode"` | `"KanaMode"` |
| `0x0066` | `"NonConvert"` | `"NonConvert"` |
| `0x0067` | `"Unidentified"` | `""` |
| `0x0068` | `"NumpadEnter"` | `"NumpadEnter"` |
| `0x0069` | `"ControlRight"` | `"ControlRight"` |
| `0x006A` | `"NumpadDivide"` | `"NumpadDivide"` |
| `0x006B` | `"PrintScreen"` | `"PrintScreen"` |
| `0x006C` | `"AltRight"` | `"AltRight"` |
| `0x006D` | `"Unidentified"` | `""` |
| `0x006E` | `"Home"` | `"Home"` |
| `0x006F` | `"ArrowUp"` | `"ArrowUp"` |
| `0x0070` | `"PageUp"` | `"PageUp"` |
| `0x0071` | `"ArrowLeft"` | `"ArrowLeft"` |
| `0x0072` | `"ArrowRight"` | `"ArrowRight"` |
| `0x0073` | `"End"` | `"End"` |
| `0x0074` | `"ArrowDown"` | `"ArrowDown"` |
| `0x0075` | `"PageDown"` | `"PageDown"` |
| `0x0076` | `"Insert"` | `"Insert"` |
| `0x0077` | `"Delete"` | `"Delete"` |
| `0x0078` | `"Unidentified"` | `""` |
| `0x0079` | `"AudioVolumeMute"` (was `"VolumeMute"` until
 Firefox 49)
  | `"AudioVolumeMute"` (was `"VolumeMute"` until
 Chrome 50)
  |
| `0x007A` | `"AudioVolumeDown"` (was `"VolumeDown"` until
 Firefox 49)
  | `"AudioVolumeDown"` (was `"VolumeDown"` until
 Chrome 50)
  |
| `0x007B` | `"AudioVolumeUp"` (was `"VolumeUp"` until Firefox
 49)
  | `"AudioVolumeUp"` (was `"VolumeUp"` until Chrome
 50)
  |
| `0x007C` | `"Unidentified"` | `"Power"` |
| `0x007D` | `"NumpadEqual"` | `"NumpadEqual"` |
| `0x007E` | `"Unidentified"` | `"NumpadChangeSign"` |
| `0x007F` | `"Pause"` | `"Pause"` |
| `0x0080` | `"Unidentified"` | `""` |
| `0x0081` | `"NumpadComma"` | `""` |
| `0x0082` | `"Lang1"` | `"HangulMode"` |
| `0x0083` | `"Lang2"` | `"Hanja"` |
| `0x0084` | `"IntlYen"` | `"IntlYen"` |
| `0x0085` | `"OSLeft"` | `"OSLeft"` |
| `0x0086` | `"OSRight"` | `"OSRight"` |
| `0x0087` | `"ContextMenu"` | `"ContextMenu"` |
| `0x0088` | `"BrowserStop"` | `"Cancel"` |
| `0x0089` | "Again" | `""` |
| `0x008A` | `"Props"` | `""` |
| `0x008B` | `"Undo"` | `"Undo"` |
| `0x008C` | `"Select"` | `""` |
| `0x008D` | `"Copy"` | `"Copy"` |
| `0x008E` | `"Open"` | `""` |
| `0x008F` | `"Paste"` | `"Paste"` |
| `0x0090` | `"Find"` | `""` |
| `0x0091` | `"Cut"` | `"Cut"` |
| `0x0092` | `"Help"` | `"Help"` |
| `0x0093` | `"Unidentified"` | `""` |
| `0x0094` | `"LaunchApp2"` | `""` |
| `0x0095`, `0x0096` | `"Unidentified"` | `""` |
| `0x0097` | `"WakeUp"` | `""` |
| `0x0098` | `"LaunchApp1"` | `""` |
| `0x0099` ～ `0x00A2` | `"Unidentified"` | `""` |
| `0x00A3` | `"LaunchMail"` | `""` |
| `0x00A4` | `"BrowserFavorites"` | `""` |
| `0x00A5` | `"Unidentified"` | `""` |
| `0x00A6` | `"BrowserBack"` | `"BrowserBack"` |
| `0x00A7` | `"BrowserForward"` | `"BrowserForward"` |
| `0x00A8` | `"Unidentified"` | `""` |
| `0x00A9` | `"Eject"` | `""` |
| `0x00AA` | `"Unidentified"` | `""` |
| `0x00AB` | `"MediaTrackNext"` | `""` |
| `0x00AC` | `"MediaPlayPause"` | `""` |
| `0x00AD` | `"MediaTrackPrevious"` | `""` |
| `0x00AE` | `"MediaStop"` | `""` |
| `0x00AF` ～ `0x00B2` | `"Unidentified"` | `""` |
| `0x00B3` | `"LaunchMediaPlayer"` (`"MediaSelect"` prior to
 Firefox 49)
  | `""` |
| `0x00B4` | `"BrowserHome"` | `""` |
| `0x00B5` | `"BrowserRefresh"` | `"BrowserRefresh"` |
| `0x00B6` ～ `0x00BA` | `"Unidentified"` | `""` |
| `0x00BB` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"NumpadParenLeft"` |
| `0x00BC` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `"NumpadParenRight"` |
| `0x00BD`, `0x00BE` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x00BF` | `"F13"` | `""` |
| `0x00C0` | `"F14"` | `""` |
| `0x00C1` | `"F15"` | `""` |
| `0x00C2` | `"F16"` | `""` |
| `0x00C3` | `"F17"` | `""` |
| `0x00C4` | `"F18"` | `""` |
| `0x00C5` | `"F19"` | `""` |
| `0x00C6` | `"F20"` | `""` |
| `0x00C7` | `"F21"` | `""` |
| `0x00C8` | `"F22"` | `""` |
| `0x00C9` | `"F23"` | `""` |
| `0x00CA` | `"F24"` | `""` |
| `0x00CB ～ 0x00E0` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 | `""` |
| `0x00E1` | `"BrowserSearch"` | `""` |

### Code values on Android and Firefox OS (When scancode is available)

| scancode | Gecko (32) |
| --- | --- |
| `0x0001` | `"Escape"` |
| `0x0002` | `"Digit1"` |
| `0x0003` | `"Digit2"` |
| `0x0004` | `"Digit3"` |
| `0x0005` | `"Digit4"` |
| `0x0006` | `"Digit5"` |
| `0x0007` | `"Digit6"` |
| `0x0008` | `"Digit7"` |
| `0x0009` | `"Digit8"` |
| `0x000A` | `"Digit9"` |
| `0x000B` | `"Digit0"` |
| `0x000C` | `"Minus"` |
| `0x000D` | `"Equal"` |
| `0x000E` | `"Backspace"` |
| `0x000F` | `"Tab"` |
| `0x0010` | `"KeyQ"` |
| `0x0011` | `"KeyW"` |
| `0x0012` | `"KeyE"` |
| `0x0013` | `"KeyR"` |
| `0x0014` | `"KeyT"` |
| `0x0015` | `"KeyY"` |
| `0x0016` | `"KeyU"` |
| `0x0017` | `"KeyI"` |
| `0x0018` | `"KeyO"` |
| `0x0019` | `"KeyP"` |
| `0x001A` | `"BracketLeft"` |
| `0x001B` | `"BracketRight"` |
| `0x001C` | `"Enter"` |
| `0x001D` | `"ControlLeft"` |
| `0x001E` | `"KeyA"` |
| `0x001F` | `"KeyS"` |
| `0x0020` | `"KeyD"` |
| `0x0021` | `"KeyF"` |
| `0x0022` | `"KeyG"` |
| `0x0023` | `"KeyH"` |
| `0x0024` | `"KeyJ"` |
| `0x0025` | `"KeyK"` |
| `0x0026` | `"KeyL"` |
| `0x0027` | `"Semicolon"` |
| `0x0028` | `"Quote"` |
| `0x0029` | `"Backquote"` |
| `0x002A` | `"ShiftLeft"` |
| `0x002B` | `"Backslash"` |
| `0x002C` | `"KeyZ"` |
| `0x002D` | `"KeyX"` |
| `0x002E` | `"KeyC"` |
| `0x002F` | `"KeyV"` |
| `0x0030` | `"KeyB"` |
| `0x0031` | `"KeyN"` |
| `0x0032` | `"KeyM"` |
| `0x0033` | `"Comma"` |
| `0x0034` | `"Period"` |
| `0x0035` | `"Slash"` |
| `0x0036` | `"ShiftRight"` |
| `0x0037` | `"NumpadMultiply"` |
| `0x0038` | `"AltLeft"` |
| `0x0039` | `"Space"` |
| `0x003A` | `"CapsLock"` |
| `0x003B` | `"F1"` |
| `0x003C` | `"F2"` |
| `0x003D` | `"F3"` |
| `0x003E` | `"F4"` |
| `0x003F` | `"F5"` |
| `0x0040` | `"F6"` |
| `0x0041` | `"F7"` |
| `0x0042` | `"F8"` |
| `0x0043` | `"F9"` |
| `0x0044` | `"F10"` |
| `0x0045` | `"NumLock"` |
| `0x0046` | `"ScrollLock"` |
| `0x0047` | `"Numpad7"` |
| `0x0048` | `"Numpad8"` |
| `0x0049` | `"Numpad9"` |
| `0x004A` | `"NumpadSubtract"` |
| `0x004B` | `"Numpad4"` |
| `0x004C` | `"Numpad5"` |
| `0x004D` | `"Numpad6"` |
| `0x004E` | `"NumpadAdd"` |
| `0x004F` | `"Numpad1"` |
| `0x0050` | `"Numpad2"` |
| `0x0051` | `"Numpad3"` |
| `0x0052` | `"Numpad0"` |
| `0x0053` | `"NumpadDecimal"` |
| `0x0054`, `0x0055` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x0056` | `"IntlBackslash"` |
| `0x0057` | `"F11"` |
| `0x0058` | `"F12"` |
| `0x0059` | `"IntlRo"` |
| `0x005A`, `0x005B` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x005C` | `"Convert"` |
| `0x005D` | `"KanaMode"` |
| `0x005E` | `"NonConvert"` |
| `0x005F` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x0060` | `"NumpadEnter"` |
| `0x0061` | `"ControlRight"` |
| `0x0062` | `"NumpadDivide"` |
| `0x0063` | `"PrintScreen"` |
| `0x0064` | `"AltRight"` |
| `0x0065` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x0066` | `"Home"` |
| `0x0067` | `"ArrowUp"` |
| `0x0068` | `"PageUp"` |
| `0x0069` | `"ArrowLeft"` |
| `0x006A` | `"ArrowRight"` |
| `0x006B` | `"End"` |
| `0x006C` | `"ArrowDown"` |
| `0x006D` | `"PageDown"` |
| `0x006E` | `"Insert"` |
| `0x006F` | `"Delete"` |
| `0x0070` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x0071` | `"AudioVolumeMute"`

 Prior to Firefox 48, this key code is identifi9ed as
 `"VolumeMute"`.

 |
| `0x0072` | `"AudioVolumeDown"`

 Prior to Firefox 48, this key code is identifi9ed as
 `"VolumeDown"`.

 |
| `0x0073` | `"AudioVolumeUp"`

 Prior to Firefox 48, this key code is identifi9ed as
 `"VolumeUp"`.
  |
| `0x0074` | `"Power"` |
| `0x0075` | `"NumpadEqual"` |
| `0x0076` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x0077` | `"Pause"` |
| `0x0078` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x0079` | `"NumpadComma"` |
| `0x007A` | `"Lang1"` |
| `0x007B` | `"Lang2"` |
| `0x007C` | `"IntlYen"` |
| `0x007D` | `"MetaLeft"`

 Prior to Firefox 48, this key code is reported as
 `"OSLeft"`.

 |
| `0x007E` | `"MetaRight"`

 Prior to Firefox 49, this key code is reported as
 `"MetaRight"`.

 |
| `0x007F` | `"ContextMenu"` |
| `0x0080` | `"BrowserStop"` |
| `0x0081` | "Again" |
| `0x0082` | `"Props"` |
| `0x0083` | `"Undo"` |
| `0x0084` | `"Select"` |
| `0x0085` | `"Copy"` |
| `0x0086` | `"Open"` |
| `0x0087` | `"Paste"` |
| `0x0088` | `"Find"` |
| `0x0089` | `"Cut"` |
| `0x008A` | `"Help"` |
| `0x008B` ～ `0x008D` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x008E` | `"Sleep"` |
| `0x008F` | `"WakeUp"` |
| `0x0090` | `"LaunchApp1"` |
| `0x0091` ～ `0x009B` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x009C` | `"BrowserFavorites"` |
| `0x009D` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x009E` | `"BrowserBack"` |
| `0x009F` | `"BrowserForward"` |
| `0x00A0` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x00A1` | `"Eject"` |
| `0x00A2` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x00A3` | `"MediaTrackNext"` |
| `0x00A4` | `"MediaPlayPause"` |
| `0x00A5` | `"MediaTrackPrevious"` |
| `0x00A6` | `"MediaStop"` |
| `0x00A7` ～ `0x00AC` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x00AD` | `"BrowserRefresh"` |
| `0x00AE` ～ `0x00B6` |
 "Unidentified" Prior to Firefox 48, this key code is reported as "" (an
 empty string).
  |
| `0x00B7` | `"F13"` |
| `0x00B8` | `"F14"` |
| `0x00B9` | `"F15"` |
| `0x00BA` | `"F16"` |
| `0x00BB` | `"F17"` |
| `0x00BC` | `"F18"` |
| `0x00BD` | `"F19"` |
| `0x00BE` | `"F20"` |
| `0x00BF` | `"F21"` |
| `0x00C0` | `"F22"` |
| `0x00C1` | `"F23"` |
| `0x00C2` | `"F24"` |
| `0x00C3` ～ `0x00D8` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x00D9` | `"BrowserSearch"` |
| `0x00DA` ～ `0x01CF` | `"Unidentified"`

 Prior to Firefox 48, this key code is reported as
 `""` (an empty string).

 |
| `0x01D0` | `"Fn"` |


KeyboardEvent.metaKey - Web API 接口参考

KeyboardEvent.metaKey
=====================

**`KeyboardEvent.metaKey`** 为只读属性，返回一个 `布尔值`，在事件发生时，用于指示 `Meta` 键是按下状态（`true`），还是释放状态（`false`）。

**备注：** 在 MAC 键盘上，表示 Command 键（`⌘`），在 Windows 键盘上，表示 Windows 键（`⊞`）。

语法
--
```

var metaKeyPressed = instanceOfKeyboardEvent.metaKey
```

### 返回值

一个布尔值

示例
--

```js
function goInput(e) {
  // 检测 metaKey 值
  if (e.metaKey) {
    // 继续处理事件
    superSizeOutput(e);
  } else {
    doOutput(e);
  }
}
```

规范
--

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

浏览器兼容性
------

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

相关链接
----

* `KeyboardEvent`