JavaScript keycode 检测器,免费
按下键盘上的任意按键,查看其 JavaScript 事件属性。
JavaScript 键盘事件 30 年简史
工作原理
- 按下一个按键:点击输入区,按下任意键 · 字母、数字、功能键、方向键、修饰键或特殊键。
- 读取 keycode:工具立即显示按键的 event.key、event.code、event.keyCode(遗留)和 charCode 值。
- 在代码中使用:复制您在键盘事件监听器或快捷键实现中需要的确切值。
为什么使用 keycode 检测器?
JavaScript 的键盘事件暴露多个不同属性 · key、code、keyCode、charCode 和 which · 知道用哪一个以及比较什么值常常令人困惑。KeyCode 检测器让您按下按键即可立即看到其所有事件属性,省去猜测。构建键盘快捷键、处理特殊按键、实现热键以及调试键盘事件监听器时非常有价值。
功能特性
- 所有事件属性:为每次按键显示 event.key、event.code、event.keyCode、event.which 和 event.charCode。
- 修饰键检测:显示按键时是否按住了 Shift、Ctrl、Alt 和 Meta。
- 支持特殊按键:兼容功能键(F1–F12)、方向键、Enter、Esc、Tab、Backspace 及所有其他特殊按键。
- 按键历史:保留最近按键的日志,便于比较多个按键。
- 复制值:点击任意值即可直接复制到剪贴板。
常见问题
event.key 和 event.keyCode 有什么区别?
event.key 是现代标准 · 返回「ArrowLeft」「Enter」等可读字符串。event.keyCode 是遗留的数字代码(已弃用但仍被支持)。新代码请使用 event.key;event.keyCode 用于保持对旧浏览器的兼容性。
如何检测 Ctrl+S 或其他组合键?
键盘组合结合 event.key 和修饰键检查:if (event.ctrlKey && event.key === "s")。在此工具中按下 Ctrl+S 查看所有值,然后在事件监听器中复现相同条件。
为什么有些按键显示相同的 keyCode?
keyCode 值未被规范化,某些按键在不同上下文下共享代码。event.code 更可靠 · 它标识按键的物理位置(如「KeyA」),与键盘布局无关;而 event.key 反映该键产生的字符。
JavaScript 键盘事件 30 年简史
键盘事件在 DOM 中有着臭名昭著的混乱历史。Netscape Navigator 2(1995)引入了原始的 onkeydown、onkeypress 和 onkeyup 处理器,带有一个没有规范的数字 keyCode 属性;浏览器各自发明了自己的值。Internet Explorer 4(1997)实现了自己的变体,以 event.keyCode 作为唯一属性,而 Netscape 坚持使用 event.which。DOM Level 2 Events(W3C,2000 年 11 月)标准化了事件流(捕获/冒泡),但因供应商无法达成一致,明确搁置了键盘事件。结果:开发者在十多年里写着像 e.keyCode || e.which 这样的代码。DOM Level 3 Events(W3C Working Draft 2003,Recommendation 2018)终于引入了现代的 event.key(Unicode 字符或命名键如「ArrowLeft」)和 event.code(物理键位置如「KeyA」,与布局无关),同时弃用 keyCode、charCode 和 which。UI Events 规范(W3C,持续中)是这项工作的现代家园。浏览器逐步赶上:Chrome 51(2016 年 5 月)、Firefox 47(2016 年 6 月)、Safari 10.1(2017 年 3 月)都发布了 event.code 支持。传统的 keypress 事件被 beforeinput 和 input 事件取代,已被弃用。
5 个属性,解码
event.key(现代,使用此)。产生的字符或命名键。字母和数字给你 Unicode 字符,尊重修饰符和布局(Shift+a = 「A」,AZERTY Q 位置 = 「a」)。命名键是像 「Enter」、「Escape」、「ArrowLeft」、「F5」、「Control」这样的字符串。在 UI Events 中定义。event.code(现代,用于游戏)。识别键盘上的物理键,与布局或修饰符无关。示例:「KeyA」、「Digit1」、「ArrowUp」、「ShiftLeft」、「MetaLeft」。将此用于 WASD 移动、vim 风格导航,以及应忽略键盘布局的快捷键。event.keyCode(已弃用)。数字代码。13 = Enter,27 = Escape,32 = 空格,37-40 = 箭头 左/上/右/下,65-90 = A-Z,112-123 = F1-F12。值从未标准化,仅通过收敛在浏览器之间变得一致。在新代码中避免。event.which(已弃用)。Netscape 的 keyCode 等价物。对于大多数可打印字符和不可打印键,与 keyCode 相同。旧的 polyfille.keyCode || e.which处理了一个为 0 的情况。event.charCode(已弃用,仅在 keypress 上)。字符的 Unicode 代码点。97为 「a」,65为 「A」。仅在keypress上触发(其本身已弃用)。input和beforeinput事件是现代替代品。- 修饰符布尔值。
event.shiftKey、event.ctrlKey、event.altKey、event.metaKey(macOS 上的 Command,Windows 上的 Windows 键)。始终明确检查修饰符:e.metaKey || e.ctrlKey用于跨平台「保存」(Mac 上 Cmd+S,Windows/Linux 上 Ctrl+S)。 event.location。区分左与右修饰符以及数字键盘。0=标准,1=左修饰符,2=右修饰符,3=数字键盘。对于区分游戏布局的左 Shift 与右 Shift 很有用。
键代码查找真正重要的地方
- 应用程序键盘快捷键。Cmd/Ctrl+S 保存、Cmd/Ctrl+Z 撤销、Cmd/Ctrl+K 打开命令面板(Slack、Linear、GitHub、Notion 自 2020 年左右都使用此功能)。始终使用
event.key表示可打印键,使用修饰符布尔值表示元键。 - 命令面板和模糊查找器。由 Slack(2014)和 Linear(2019)推广的 Cmd+K 模式。全局监听打开快捷键,然后处理 ArrowUp/ArrowDown 导航、Enter 选择、Escape 关闭。
- 浏览器游戏和 HTML5 游戏开发。Phaser、Babylon.js、Three.js。对于移动键,始终使用
event.code,以便 WASD 在 AZERTY 键盘上工作(其中「W」位于「Z」位置)。Sebastian Lague、Notch(早期 Minecraft 原型)和 itch.io 游戏都遇到了这个 AZERTY 陷阱。 - 无障碍模式。模态对话框需要 Escape 关闭。Combobox 控件需要 ArrowDown/ArrowUp/Enter/Escape。工具提示需要在 Escape 时关闭。WAI-ARIA Authoring Practices Guide 为每个常见控件定义了键盘交互模式;
event.key是这些检查的标准。 - 文本编辑器和代码编辑器实现。Monaco(浏览器中的 VS Code 编辑器)、CodeMirror、ProseMirror、Lexical 都将键盘事件映射到命令。它们使用
event.code用于不依赖布局的 vim/emacs 风格键绑定。 - 表单 UX 增强。Enter 提交、Escape 失焦、Tab 推进焦点。在结账流程、搜索栏、自动完成字段中常见。
- 浏览器扩展热键。Vimium、SurfingKeys、Tridactyl 为整个网络提供键盘导航。它们在文档级别监听并处理复杂的模态键序列(gg = 转到顶部,像 vim)。
键盘事件处理中的常见错误
- 在新代码中使用
keyCode。自 DOM Level 3(2018)起已弃用,历史上在浏览器之间不一致,在非美国布局上中断(逗号键在美国上keyCode为 188,在某些德国键盘上为 191)。改用event.key。 - 硬编码
e.key === "w"用于游戏移动。在 AZERTY(法语)键盘上,物理 W 键键入「z」。玩家伸手去找他们记忆中的 WASD 集群,但得到错误的输入。改用event.code === "KeyW",它识别物理位置。 - 仅检查
ctrlKey来「保存」。在 macOS 上,Cmd+S 是惯例;ctrlKey为假但metaKey为真。始终检查两者:(e.metaKey || e.ctrlKey) && e.key === "s"。 - 忘记对浏览器保留快捷键使用
preventDefault。不使用 preventDefault 劫持 Cmd+S 仍会触发 Save Page As。Cmd+P(打印)、Ctrl+F(浏览器查找)、Ctrl+N(新窗口 , 反正不能阻止)、Ctrl+Tab(Chrome 不让你)也一样。在处理器中调用e.preventDefault()。 - 忽略 IME 组合。日语、中文、韩语输入法(IME)在用户组合字符时触发
keydown事件。在触发你的快捷键处理器之前检查e.isComposing或使用compositionend事件。Slack 在 2017 年为日语用户搞砸了这一点,众所周知。 - 使用已弃用的
keypress事件。仅为产生字符的键触发(不是箭头键、功能键等)。已弃用;对快捷键使用keydown,对文本更改使用input/beforeinput。 - 在每次重复时触发快捷键。按住键会重复触发
keydown事件。对于切换操作(打开面板、切换标签),检查e.repeat并提前退出,以避免在用户意外按住键时注册 30 个「打开」命令。
更多常见问题
为什么当用户使用非美国键盘时,我的键处理器不触发?
几乎总是因为你正在检查 event.key 中只在该布局上用 Shift 存在的字符。在德国 QWERTZ 键盘上,「/」是 Shift+7(不是自己的键);在法语 AZERTY 上,数字 0-9 用 Shift+上一行键入。对基于位置的快捷键使用 event.code(物理键),或对基于内容的快捷键使用 event.key(你真正想要用户刚键入的字符)。
如何在跨平台一致地处理 Cmd+K / Ctrl+K?
标准惯用法:if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); openPalette(); }。在 macOS 上,e.metaKey 是 Cmd 键;在 Windows/Linux 上,e.ctrlKey 是用户所期望的。接受两者。始终 preventDefault,因为浏览器在某些浏览器中将 Cmd+K 绑定到「聚焦地址栏」。添加 !e.repeat 以避免在按住键时触发。
JavaScript 能检测页面外的全局击键吗?
不,这是出于安全设计。浏览器仅为聚焦的页面或元素触发键盘事件。浏览器扩展可以使用 chrome.commands API 以更广泛的范围监听。原生应用在 Electron、Tauri 等中可以使用操作系统级别的全局钩子。银行和 2FA 应用依赖于这种隔离:恶意标签不能键盘记录你的密码管理器。
检测「刚按下」与「正在按住」的正确方法是什么?
对于切换,在 keydown 处理器中检查 !e.repeat , 第一个事件具有 repeat: false,后续自动重复事件具有 repeat: true。对于连续操作(游戏移动),在 Set 中跟踪键状态:在 keydown 上添加,在 keyup 上移除,然后在渲染循环中检查 keysHeld.has("KeyW")。这将输入与帧率解耦,并处理多个同时键(移动 + 跳跃)。
我在这里按键时,任何东西会发送到服务器吗?
不会。键事件由 JavaScript 在本地捕获并显示在此页面上,无需任何网络请求。在 DevTools 中打开 Network 标签,尽情打字;你会看到零出站流量。对于在任何上下文中测试都是安全的,包括发现密码或敏感快捷键在你的键盘上产生什么。