
理解 JavaScript 键盘事件:开发者指南
键盘事件是交互式 Web 应用程序的基础。无论你是在构建游戏、快捷键驱动的编辑器还是无障碍表单,理解如何捕获和解释按键操作都至关重要。本指南深入探讨 JavaScript 键盘事件模型,解释事件对象上可用的属性,并展示如何使用我们的 Keycode Info 工具 快速识别按键代码。
键盘事件生命周期
当用户按下某个键时,三个事件按顺序触发:
keydown– 当键首次按下时触发。在键保持按下状态时重复触发(在操作系统的重复延迟生效之前)。keypress– 针对产生字符值的键(字母、数字、符号)触发。此事件已弃用,但仍被广泛支持。它不会为修饰键(如 Shift 或 Ctrl)触发。keyup– 当键释放时触发。
对于大多数现代应用程序,keydown 和 keyup 就足够了。应避免使用 keypress,因为它在不同浏览器中行为不一致且已被弃用。
事件对象上的关键属性
KeyboardEvent 对象提供了几个属性来识别按下的键及其状态:
| 属性 | 描述 | 示例(按下 'a') |
|---|---|---|
key |
键值字符串。对于可打印字符,它是字符本身。对于特殊键,它是命名字符串,如 "Enter"、"ArrowUp" 或 "Shift"。 |
"a" 或 "A"(带 Shift) |
code |
键盘上的物理键位置,与当前键盘布局无关。值如 "KeyA"、"Digit1"、"ArrowUp"。 |
"KeyA" |
keyCode |
表示键的数字代码。已弃用,但在旧代码中仍在使用。对于 'a' 是 65,对于 'A' 也是 65(不区分大小写)。 |
65 |
charCode |
字符的 Unicode 值。仅在 keypress 中可用。已弃用。 |
97(对于 'a'),65(对于 'A') |
shiftKey |
布尔值,指示 Shift 是否被按住。 | false |
ctrlKey |
布尔值,指示 Ctrl 是否被按住。 | false |
altKey |
布尔值,指示 Alt 是否被按住。 | false |
metaKey |
布尔值,指示 Meta(Mac 上的 Cmd,Windows 键)是否被按住。 | false |
为什么 key 和 code 比 keyCode 更重要
旧的 keyCode 属性已被弃用,并且在不同的浏览器和键盘布局中行为不一致。例如,在美国键盘上按 ';' 键会得到 keyCode 186,但在法式 AZERTY 布局上,相同的物理键可能会产生不同的字符和代码。相比之下:
key提供逻辑字符(例如,根据 Shift 状态返回"a"或"A")。当你关心输入的字符时使用它。code提供物理键位置(例如,无论布局或 Shift 状态如何,都返回"KeyA")。在游戏控制或依赖键位置的快捷键中使用它。
实践示例:构建键盘快捷键记录器
让我们构建一个简单的 HTML 页面,记录每个键盘事件并显示相关属性。然后你可以将输出与我们的 Keycode Info 工具 进行比较,以验证你的理解。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Key Logger</title>
<style>
#log { white-space: pre-wrap; font-family: monospace; }
</style>
</head>
<body>
<h1>Press any key</h1>
<div id="log"></div>
<script>
const logDiv = document.getElementById('log');
document.addEventListener('keydown', (event) => {
const line = [
`Event: ${event.type}`,
`key: "${event.key}"`,
`code: "${event.code}"`,
`keyCode: ${event.keyCode}`,
`shiftKey: ${event.shiftKey}`,
`ctrlKey: ${event.ctrlKey}`,
`altKey: ${event.altKey}`,
`metaKey: ${event.metaKey}`
].join(' | ');
logDiv.textContent += line + '\n';
// 如果需要,阻止某些键的默认行为
// event.preventDefault();
});
</script>
</body>
</html>
在浏览器中打开此页面并按下各种键。注意:
- 按下 'a' 会得到
key: "a"、code: "KeyA"、keyCode: 65。 - 按下 Shift+a 会得到
key: "A"、code: "KeyA"(相同的 code,不同的 key)。 - 按下左箭头会得到
key: "ArrowLeft"、code: "ArrowLeft"、keyCode: 37。
使用 Keycode Info 工具
我们的 Keycode Info 工具 提供了一种交互方式,可以实时查看按键事件的所有属性。你可以按下任意键,立即看到 key、code、keyCode 和修饰键状态。当你实现键盘快捷键并需要确认特定按键组合的确切值时,这尤其有用。
例如,如果你想绑定 Ctrl+S 进行保存,可以在工具中按下 Ctrl+S,看到 ctrlKey 为 true,key 为 "s"(如果 CapsLock 开启则为 "S"),code 为 "KeyS"。这确认了你的事件处理器应检查 event.ctrlKey && event.key === 's'(不区分大小写)。
常见陷阱
- 在新代码中使用
keyCode。 它已被弃用,可能在未来的浏览器中失效。请改用key或code。 - 忘记
key是区分大小写的。 检查字母时,始终与小写版本比较(例如event.key.toLowerCase() === 's')以处理 CapsLock 或 Shift。 - 假设
keypress对所有键触发。 它只对可打印字符触发。对于不可打印键(如箭头、Enter 或 Escape),请使用keydown。 - 未阻止默认行为。 如果你要覆盖浏览器快捷键(如 Ctrl+S),请调用
event.preventDefault()以阻止浏览器保存页面。 - 忽略键盘布局差异。 如果你的应用依赖于特定的物理键位置(例如游戏中的 WASD),请使用
code而不是key。
安全与性能考虑
- 永远不要信任客户端输入的安全性。 键盘事件可能被浏览器扩展伪造或阻止。始终在服务器端验证输入。
- 避免在事件处理器中进行繁重处理。 键盘事件触发频繁,尤其是当键被按住时。如果需要执行昂贵操作,请进行防抖或节流。
- 注意无障碍性。 不要仅依赖键盘快捷键;为无法使用键盘的用户提供替代 UI 元素。
常见问题解答
key 和 code 有什么区别?
key 表示键的字符或功能(例如 "a"、"Enter"、"Shift"),而 code 表示物理键位置(例如 "KeyA"、"Enter"、"ShiftLeft")。key 会随修饰键和键盘布局变化;code 不会。
为什么 keyCode 被弃用?
keyCode 从未被正确标准化,并且在不同的浏览器和键盘布局中行为不一致。Web 超文本应用技术工作组(WHATWG)建议改用 key 或 code。
如何检测像 Ctrl+Shift+F 这样的组合键?
检查修饰键属性(ctrlKey、shiftKey、altKey、metaKey)以及 key 或 code 属性。例如:
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.shiftKey && e.key === 'F') {
// 处理 Ctrl+Shift+F
}
});
按住键时 keydown 会重复触发吗?
是的。keydown 事件会根据操作系统的重复速率重复触发。你可以检查 event.repeat(布尔值)来区分首次按下和重复触发。
我可以离线使用 Keycode Info 工具吗?
该工具基于 Web,需要互联网连接。不过,你可以保存页面或使用上面的代码片段创建自己的本地版本。
理解键盘事件是交互式 Web 开发的基石。通过使用现代属性如 key 和 code,并利用像我们的 Keycode Info 这样的工具,你可以构建健壮、跨浏览器的键盘交互。