← HTML 表单:从控件到提交与校验 / key vs code:按键的两种名字 待审核 2 / 24
key · code · keyCode

key vs code:按键的两种名字

一次按键在 KeyboardEvent 上有两个名字:event.key 说「这次输入是什么字符 / 什么语义」(受键盘布局、Shift、输入法影响),event.code 说「按的是哪个物理键位」(如 KeyW,和布局无关——Dvorak 用户按同一颗键帽,code 不变、key 变)。而这三个旧属性 keyCode / charCode / which 已全部废弃——它们三个语义各不相同、跨浏览器还不一致,正是这页要现场验证的混乱。

1 · 按任意键,看全部属性

点下面的区域聚焦,然后随便按——试试左 Shift vs 右 ShiftShift+2小键盘数字、长按一个键:

什么时候用哪个? 判断用户想输入什么(字符、Enter、Esc)→ 用 key;做位置型快捷键(游戏 WASD、Vim 风格 hjkl 希望「手感位置」不随布局漂移)→ 用 code;keyCode / which / charCode一律别再用,只在维护旧代码时需要认识它们。另外注意 repeat:长按时 keydown 连发,每发都带 repeat: true

2 · 同一颗键帽,QWERTY 与 Dvorak 各叫什么

code 的命名按 QWERTY 键帽固定(左上字母区第一颗永远叫 KeyQ),哪怕系统切成 Dvorak / AZERTY,这颗键的 code 也不变——变的是 key:

物理键位(code) QWERTY 的 key Dvorak 的 key AZERTY 的 key
KeyQ q ' a
KeyW w , z
KeyE e e e
Semicolon ; s m

用错属性的代价: 不少网页游戏用 key === 'w' 判前进,Dvorak 玩家就得按物理的「,」位置才动——操作位置完全错位。改用 code === 'KeyW',所有布局下都是「左手食指上方那颗」。反过来,快捷键 Ctrl+Z 这类靠字母记忆的应当用 key:用户记的是字母 Z,不是物理位置。

3 · keyCode 到底乱在哪

字母 / 数字区的 keyCode 恰好等于大写字母的 ASCII 码(A=65……),看起来规整——但标点区从未标准化,Chrome 系与 Firefox 各用各的取值:

按键 code(统一) keyCode @ Chrome/Safari keyCode @ Firefox
; Semicolon 186 59
= Equal 187 61
- Minus 189 173

更糟的是语义分裂: keydown 的 keyCode 是「键号」(不分大小写),keypress 的 keyCode 却是「字符码」(分大小写)——同名属性在两个事件里含义不同;which 只是它的别名,charCode 只在 keypress 有值。三个属性、两套语义、若干浏览器方言,这就是 UI Events 规范把它们全部标记 deprecated、换成 key / code 的原因。上面的实测面板可以直接验证:按 ; 时当前浏览器给出的 keyCode 是几。