KeyboardEvent:key 属性

KeyboardEvent 接口的key只读属性返回用户按下的键的值,同时考虑了修饰键(如 Shift)的状态以及键盘区域设置和布局。

字符串。

其值按如下方式确定

  • 如果按下的键具有打印表示形式,则返回值是一个非空 Unicode 字符串,其中包含该键的可打印表示形式。例如:如果按下的键是 Space 键,则返回值是一个空格 (" ")。如果按下的键是 B 键,则返回值是字符串 "b"。但是,如果同时按下 Shift 键(因此 shiftKeytrue),则返回值是字符串 "B"
  • 如果按下的键是控制键或特殊字符,则返回值是 预定义键值 之一。
  • 如果 KeyboardEvent 表示按下 死键,则键值必须为 "Dead"。
  • 某些特殊键盘键(例如多媒体键盘上用于控制媒体的扩展键)在 Windows 上不会生成键码;而是触发 WM_APPCOMMAND 事件。这些事件被映射到 DOM 键盘事件,并在 Windows 的“虚拟键码”中列出,即使它们实际上并不是键码。
  • 如果无法识别键,则返回值为 Unidentified

KeyboardEvent 序列

每个 KeyboardEvent 都以预定的顺序触发。对于给定的按键,假设未调用 Event.preventDefault,则触发的 KeyboardEvent 序列如下所示

  1. 首先触发 keydown 事件。如果继续按住该键并且该键产生字符键,则事件将以平台实现相关的间隔继续发出,并且 KeyboardEvent.repeat 只读属性设置为 true
  2. 如果该键产生字符键,该字符键将导致字符可能插入到 <input><textarea>HTMLElement.contentEditable 设置为 true 的元素中,则 beforeinputinput 事件类型按此顺序触发。请注意,如果支持,某些其他实现可能会触发 keypress 事件。在按住键的同时,这些事件将重复触发。
  3. 释放键后,会触发 keyup 事件。这完成了整个过程。

在序列 1 和 3 中,KeyboardEvent.key 属性已定义,并根据前面定义的规则适当地设置为某个值。

KeyboardEvent 序列示例

考虑当我们使用美国键盘布局与 Shift2 键交互时生成的事件序列,以及当我们使用英国键盘布局时生成的事件序列。

尝试使用以下两个测试用例进行实验

  1. 按住 Shift 键,然后按下 2 并释放它。接下来,释放 Shift 键。
  2. 按住 Shift 键,然后按住 2。释放 Shift 键。最后,释放 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
const textarea = document.getElementById("test-target");
const consoleLog = document.getElementById("console-log");
const btnReset = document.getElementById("btn-reset");

function logMessage(message) {
  consoleLog.innerText += `${message}\n`;
}

textarea.addEventListener("keydown", (e) => {
  if (!e.repeat) {
    logMessage(`Key "${e.key}" pressed [event: keydown]`);
  } else {
    logMessage(`Key "${e.key}" repeating [event: keydown]`);
  }
});

textarea.addEventListener("beforeinput", (e) => {
  logMessage(`Key "${e.data}" about to be input [event: beforeinput]`);
});

textarea.addEventListener("input", (e) => {
  logMessage(`Key "${e.data}" input [event: input]`);
});

textarea.addEventListener("keyup", (e) => {
  logMessage(`Key "${e.key}" released [event: keyup]`);
});

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

结果

注意:在未完全实现 InputEvent 接口(用于 beforeinputinput 事件)的浏览器上,您可能会在日志输出的这些行中获得不正确的输出。

案例 1

按下 Shift 键时,首先会触发 keydown 事件,并且 key 属性值设置为字符串 Shift。当我们继续按住此键时,keydown 事件不会继续重复触发,因为它不会产生字符键。

按下“键 2”时,会为这个新的按键触发另一个 keydown 事件,并且该事件的 key 属性值由于活动修饰符 shift 键而被设置为字符串 @(对于美国键盘类型)和 "(对于英国键盘类型)。接下来触发 beforeinputinput 事件,因为已产生字符键。

当我们释放“键 2”时,会触发 keyup 事件,并且 key 属性将分别为不同的键盘布局保持字符串值 @"

当我们最终释放 shift 键时,会为它触发另一个 keyup 事件,并且 key 属性值保持为 Shift

案例 2

按下 Shift 键时,首先会触发 keydown 事件,并且 key 属性值被设置为字符串 Shift。当我们继续按住此键时,keydown 事件不会继续重复触发,因为它没有产生字符键。

按下“键 2”时,会为这个新的按键触发另一个 keydown 事件,并且该事件的 key 属性值由于活动修饰符 shift 键而被设置为字符串 @(对于美国键盘类型)和 "(对于英国键盘类型)。接下来触发 beforeinputinput 事件,因为已产生字符键。当我们继续按住该键时,keydown 事件会继续重复触发,并且 KeyboardEvent.repeat 属性设置为 truebeforeinputinput 事件也会重复触发。

当我们释放 shift 键时,会为它触发 keyup 事件,并且 key 属性值保持为 Shift。此时,请注意,“键 2”按键的重复 keydown 事件的 key 属性值现在为“2”,因为修饰符 shift 键不再处于活动状态。beforeinputinput 事件的 InputEvent.data 属性也是如此。

当我们最终释放“键 2”时,会触发 keyup 事件,但 key 属性将被设置为字符串值 2(对于两种键盘布局),因为修饰符 shift 键不再处于活动状态。

示例

此示例使用 EventTarget.addEventListener() 监听 keydown 事件。当这些事件发生时,会检查按键的值是否为代码感兴趣的按键之一,如果是,则以某种方式处理它(可能是控制航天器,也可能是更改电子表格中选定的单元格)。

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

    switch (event.key) {
      case "ArrowDown":
        // Do something for "down arrow" key press.
        break;
      case "ArrowUp":
        // Do something for "up arrow" key press.
        break;
      case "ArrowLeft":
        // Do something for "left arrow" key press.
        break;
      case "ArrowRight":
        // Do something for "right arrow" key press.
        break;
      case "Enter":
        // Do something for "enter" or "return" key press.
        break;
      case " ":
        // Do something for "space" key press.
        break;
      case "Escape":
        // Do something for "esc" key press.
        break;
      default:
        return; // Quit when this doesn't handle the key event.
    }

    // Cancel the default action to avoid it being handled twice
    event.preventDefault();
  },
  true,
);

规范

规范
UI 事件
# dom-keyboardevent-key

浏览器兼容性

BCD 表格仅在浏览器中加载