KeyboardEvent:key 属性
KeyboardEvent
接口的key
只读属性返回用户按下的键的值,同时考虑了修饰键(如 Shift)的状态以及键盘区域设置和布局。
值
字符串。
其值按如下方式确定
- 如果按下的键具有打印表示形式,则返回值是一个非空 Unicode 字符串,其中包含该键的可打印表示形式。例如:如果按下的键是 Space 键,则返回值是一个空格 (
" "
)。如果按下的键是 B 键,则返回值是字符串"b"
。但是,如果同时按下 Shift 键(因此shiftKey
为true
),则返回值是字符串"B"
。 - 如果按下的键是控制键或特殊字符,则返回值是 预定义键值 之一。
- 如果
KeyboardEvent
表示按下 死键,则键值必须为 "Dead
"。 - 某些特殊键盘键(例如多媒体键盘上用于控制媒体的扩展键)在 Windows 上不会生成键码;而是触发
WM_APPCOMMAND
事件。这些事件被映射到 DOM 键盘事件,并在 Windows 的“虚拟键码”中列出,即使它们实际上并不是键码。 - 如果无法识别键,则返回值为
Unidentified
。
KeyboardEvent 序列
每个 KeyboardEvent
都以预定的顺序触发。对于给定的按键,假设未调用 Event.preventDefault
,则触发的 KeyboardEvent
序列如下所示
- 首先触发
keydown
事件。如果继续按住该键并且该键产生字符键,则事件将以平台实现相关的间隔继续发出,并且KeyboardEvent.repeat
只读属性设置为true
。 - 如果该键产生字符键,该字符键将导致字符可能插入到
<input>
、<textarea>
或HTMLElement.contentEditable
设置为 true 的元素中,则beforeinput
和input
事件类型按此顺序触发。请注意,如果支持,某些其他实现可能会触发keypress
事件。在按住键的同时,这些事件将重复触发。 - 释放键后,会触发
keyup
事件。这完成了整个过程。
在序列 1 和 3 中,KeyboardEvent.key
属性已定义,并根据前面定义的规则适当地设置为某个值。
KeyboardEvent 序列示例
考虑当我们使用美国键盘布局与 Shift 和 2 键交互时生成的事件序列,以及当我们使用英国键盘布局时生成的事件序列。
尝试使用以下两个测试用例进行实验
- 按住 Shift 键,然后按下 2 并释放它。接下来,释放 Shift 键。
- 按住 Shift 键,然后按住 2。释放 Shift 键。最后,释放 2。
HTML
<div class="fx">
<div>
<textarea rows="5" name="test-target" id="test-target"></textarea>
<button type="button" name="btn-reset" id="btn-reset">Reset</button>
</div>
<div class="flex">
<pre id="console-log"></pre>
</div>
</div>
CSS
.fx {
-webkit-display: flex;
display: flex;
margin-left: -20px;
margin-right: -20px;
}
.fx > div {
padding-left: 20px;
padding-right: 20px;
}
.fx > div:first-child {
width: 30%;
}
.flex {
-webkit-flex: 1;
flex: 1;
}
#test-target {
display: block;
width: 100%;
margin-bottom: 10px;
}
JavaScript
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
接口(用于 beforeinput
和 input
事件)的浏览器上,您可能会在日志输出的这些行中获得不正确的输出。
案例 1
按下 Shift 键时,首先会触发 keydown
事件,并且 key
属性值设置为字符串 Shift
。当我们继续按住此键时,keydown
事件不会继续重复触发,因为它不会产生字符键。
按下“键 2”时,会为这个新的按键触发另一个 keydown
事件,并且该事件的 key
属性值由于活动修饰符 shift
键而被设置为字符串 @
(对于美国键盘类型)和 "
(对于英国键盘类型)。接下来触发 beforeinput
和 input
事件,因为已产生字符键。
当我们释放“键 2”时,会触发 keyup
事件,并且 key
属性将分别为不同的键盘布局保持字符串值 @
和 "
。
当我们最终释放 shift
键时,会为它触发另一个 keyup
事件,并且 key 属性值保持为 Shift
。
案例 2
按下 Shift 键时,首先会触发 keydown
事件,并且 key
属性值被设置为字符串 Shift
。当我们继续按住此键时,keydown 事件不会继续重复触发,因为它没有产生字符键。
按下“键 2”时,会为这个新的按键触发另一个 keydown
事件,并且该事件的 key
属性值由于活动修饰符 shift
键而被设置为字符串 @
(对于美国键盘类型)和 "
(对于英国键盘类型)。接下来触发 beforeinput
和 input
事件,因为已产生字符键。当我们继续按住该键时,keydown
事件会继续重复触发,并且 KeyboardEvent.repeat
属性设置为 true
。beforeinput
和 input
事件也会重复触发。
当我们释放 shift
键时,会为它触发 keyup
事件,并且 key 属性值保持为 Shift
。此时,请注意,“键 2”按键的重复 keydown 事件的 key
属性值现在为“2”,因为修饰符 shift
键不再处于活动状态。beforeinput
和 input
事件的 InputEvent.data
属性也是如此。
当我们最终释放“键 2”时,会触发 keyup
事件,但 key
属性将被设置为字符串值 2
(对于两种键盘布局),因为修饰符 shift
键不再处于活动状态。
示例
此示例使用 EventTarget.addEventListener()
监听 keydown
事件。当这些事件发生时,会检查按键的值是否为代码感兴趣的按键之一,如果是,则以某种方式处理它(可能是控制航天器,也可能是更改电子表格中选定的单元格)。
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 表格仅在浏览器中加载