正在加载,请稍候…

理解 JavaScript 键盘事件:开发者指南

学习 JavaScript 中键盘事件的工作原理,如何使用 Keycode Info 工具识别按键事件,以及常见陷阱的避免方法。

理解 JavaScript 键盘事件:开发者指南

理解 JavaScript 键盘事件:开发者指南

键盘事件是交互式 Web 应用程序的基础。无论你是在构建游戏、快捷键驱动的编辑器还是无障碍表单,理解如何捕获和解释按键操作都至关重要。本指南深入探讨 JavaScript 键盘事件模型,解释事件对象上可用的属性,并展示如何使用我们的 Keycode Info 工具 快速识别按键代码。

理解 JavaScript 键盘事件:开发者指南 插图

键盘事件生命周期

当用户按下某个键时,三个事件按顺序触发:

  1. keydown – 当键首次按下时触发。在键保持按下状态时重复触发(在操作系统的重复延迟生效之前)。
  2. keypress – 针对产生字符值的键(字母、数字、符号)触发。此事件已弃用,但仍被广泛支持。它不会为修饰键(如 Shift 或 Ctrl)触发。
  3. keyup – 当键释放时触发。

对于大多数现代应用程序,keydownkeyup 就足够了。应避免使用 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

理解 JavaScript 键盘事件:开发者指南 插图

为什么 keycodekeyCode 更重要

旧的 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

理解 JavaScript 键盘事件:开发者指南 插图

使用 Keycode Info 工具

我们的 Keycode Info 工具 提供了一种交互方式,可以实时查看按键事件的所有属性。你可以按下任意键,立即看到 keycodekeyCode 和修饰键状态。当你实现键盘快捷键并需要确认特定按键组合的确切值时,这尤其有用。

例如,如果你想绑定 Ctrl+S 进行保存,可以在工具中按下 Ctrl+S,看到 ctrlKeytruekey"s"(如果 CapsLock 开启则为 "S"),code"KeyS"。这确认了你的事件处理器应检查 event.ctrlKey && event.key === 's'(不区分大小写)。

常见陷阱

  • 在新代码中使用 keyCode 它已被弃用,可能在未来的浏览器中失效。请改用 keycode
  • 忘记 key 是区分大小写的。 检查字母时,始终与小写版本比较(例如 event.key.toLowerCase() === 's')以处理 CapsLock 或 Shift。
  • 假设 keypress 对所有键触发。 它只对可打印字符触发。对于不可打印键(如箭头、Enter 或 Escape),请使用 keydown
  • 未阻止默认行为。 如果你要覆盖浏览器快捷键(如 Ctrl+S),请调用 event.preventDefault() 以阻止浏览器保存页面。
  • 忽略键盘布局差异。 如果你的应用依赖于特定的物理键位置(例如游戏中的 WASD),请使用 code 而不是 key

安全与性能考虑

  • 永远不要信任客户端输入的安全性。 键盘事件可能被浏览器扩展伪造或阻止。始终在服务器端验证输入。
  • 避免在事件处理器中进行繁重处理。 键盘事件触发频繁,尤其是当键被按住时。如果需要执行昂贵操作,请进行防抖或节流。
  • 注意无障碍性。 不要仅依赖键盘快捷键;为无法使用键盘的用户提供替代 UI 元素。

常见问题解答

keycode 有什么区别?

key 表示键的字符或功能(例如 "a""Enter""Shift"),而 code 表示物理键位置(例如 "KeyA""Enter""ShiftLeft")。key 会随修饰键和键盘布局变化;code 不会。

为什么 keyCode 被弃用?

keyCode 从未被正确标准化,并且在不同的浏览器和键盘布局中行为不一致。Web 超文本应用技术工作组(WHATWG)建议改用 keycode

如何检测像 Ctrl+Shift+F 这样的组合键?

检查修饰键属性(ctrlKeyshiftKeyaltKeymetaKey)以及 keycode 属性。例如:

document.addEventListener('keydown', (e) => {
  if (e.ctrlKey && e.shiftKey && e.key === 'F') {
    // 处理 Ctrl+Shift+F
  }
});

按住键时 keydown 会重复触发吗?

是的。keydown 事件会根据操作系统的重复速率重复触发。你可以检查 event.repeat(布尔值)来区分首次按下和重复触发。

我可以离线使用 Keycode Info 工具吗?

该工具基于 Web,需要互联网连接。不过,你可以保存页面或使用上面的代码片段创建自己的本地版本。


理解键盘事件是交互式 Web 开发的基石。通过使用现代属性如 keycode,并利用像我们的 Keycode Info 这样的工具,你可以构建健壮、跨浏览器的键盘交互。