告别JS keyCode
byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9755
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
一、为什么keyCode不推荐使用了?
对于这个问题的答案,说实话,我找了很多资料,并没有特别明确的回答。
早些年,我得到的说法是,用户可能会自定义键盘,导致keyCode不准。
但是,这次搜寻资料,没有见到类似的说法。
MDN上的解释是对打印字符不友好。
我琢磨着可能是这几个意思:
1. 不同字符共用keyCode
键盘上有很多按键是同时对应两个字符的,例如“<,”和“>.”就在一个键上,数字键那里(1!、2@、3#、4$、5%、……)都是一个键对应多个字符,如果想要输入两位字符,往往需要按住Shift键才行,例如字符“<>!@#$%^&*()……”等字符的输入。
而 keyCode
值是跟着键盘走的,而不是字符内容,也就是,当我们输入“<,”和“>.”等字符的时候,返回的 keyCode
值是一样的,我们需要通过判断用户是否按下了Shift键才知道究竟输入的是哪个字符。
这就很啰嗦。
例如:
window.addEventListener('keydown', function (event) { console.log(event.keyCode); });
然后在页面中分别输入字符“.>”,则会看到输出的keyCode值都是一样的 190
,如下截图所示:
明明是两个不同的字符,结果输出的keyCode值是一样的,对开发就不友好。
2. 相同按键不同keyCode
例如全键盘中的数字键按住Shift键可以输出其他内容,例如下图所示的数字键盘。

,
例如右下角的小数点字符 '.'
同时有Del键的能力。
此时,按下此键和Shift+按下此键的keyCode值是不一样的。
然后大家就会发现按下 '.'
返回的keyCode是110,加了个Shift键之后返回的就变成了46了。
这就蛋疼了,因为上面同样按键返回同样keyCode,这里居然摇身一变,相同按键返回了不同的keyCode。
3. 相同字符不同keyCode
还没完,Shift+ '.'
返回keyCode就是直接按下delete键的keyCode值,给人感觉只要最终行为或字符输出是一样的,keyCode值也应该是一样的,实际上,并不是这样的。
即使输入同一字符,也可能会是不同的keyCode值。
这里大家注意力放在下图中右上方的加号和减号上。
同时,上方的一排数字键那里也是有加号和减号的,如下图所示:
此时,分别按下这两个键,会发现输出的字符是一模一样的,但是keyCode值却是不同的,如下截图示意。
上方数字键那里的短横线连字符的keyCode是189,而数字键盘那里的减号字符的keyCode是109,实际上这两个字符一模一样。
试想下,如果开发过程中判断用户是否按下的是连字符,使用keyCode判断,是不是很容易出bug?
其他的几个数字可有类似的问题,例如数字键盘输出的1-9的keyCode和键盘上面1-9数字的keyCode值是不一样的。
4. 中文输入法下标点符号keyCode都是一样的
例如输入框中是中文输入法,此时,“,。;‘【】-=”这些字符的keyCode全部都返回229,根本就没法继续玩了。
或许是因为上面指出的4个keyCode对打印字符不友好的地方,keyCode才不推荐使用,目前规范推荐使用event.code或event.key。
//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=9755(作者张鑫旭)
二、event.code和event.key的区别
event.code
指明按下的是具体哪个物理键,键盘上每一个按键都对应一个唯一的 event.code
值,均使用大写英文单词表示。
event.key
指明具体输入的字符内容,如果是非打印字符(例如Enter键、Esc键、Shift键、Alt键等),则返回具体的非打印字符的英文名称,如果输入内容与输入法有关则返回固定的Process名称。
为了方便大家快速了解差异,我选取了几个具有代表性的按键,整理了个表格,显示了不同按键下 event.code
和 event.key
的值。
keyCode值 | code值 | key值 | 描述 |
---|---|---|---|
49 | ‘Digit1’ | ‘1’ | 上方数字键1按下 |
97 | ‘Numpad1’ | ‘1’ | 小键盘数字键1按下 |
16 | ‘ShiftLeft’ | ‘Shift’ | 左侧的Shift键 |
16 | ‘ShiftRight’ | ‘Shift’ | 右侧的Shift键 |
190 | ‘Period’ | ‘.’ | 主键盘中的点符号 |
110 | ‘NumpadDecimal’ | ‘.’ | 数字键盘中的小数点符号 |
229 | ‘Period’ | ‘Process’ | 中文输入法下主键盘中的点符号 |
229 | ‘Minus’ | ‘Process’ | 中文输入法下主键盘中的’-‘符号 |
189 | ‘Minus’ | ‘-‘ | 主键盘中的’-‘符号 |
109 | ‘NumpadSubtract’ | ‘-‘ | 数字键盘中的’-‘符号 |
对于英文场景,只需要使用 event.key
就可以知道键盘输入的内容了。
但是如果是中文场景,情况就变得复杂的多。
在中文输入框开启的场景下,如果按键的内容和非中文输入法下的内容不一样,则 event.key
的返回值是固定的Process,表示输入的字符内容和键盘对应的原始内容进行了处理。
例如主键盘中的字符点默认情况下就是个 .
,但是如果是中文输入框,字符点就是句号 。
,而键盘上完全就没有句号这个字符,说明字符点被输入法给处理了,因此返回的就是Process。
这就导致,在中文输入法场景下,用户或者开发者是无法知道按键应该输入的内容的。
即使配合 event.code
也不行。
有人可能会反驳, event.code
返回’Period’,不就表明按下的是点号键,此时 event.key
是’Process’,不就可以判断输入的是句号了。
理论上可行,实操起来却比预想的麻烦,且不具有可复制性。
- 麻烦在于,如果用户输入的是这个符号
》
,也就是右书名号,event.code
返回的也是’Period’,event.key
也是’Process’。还需要开发者判断event.shiftKey
是否为true,表示Shift键是否按下。
以及,换个其他语言输入法,则按下’Period’键返回的就不一定是句号了。
- 不具有可复制性在于,中文输入法经常会使用空格或者回车表示选中,此时,
event.code
是Space或者Enter,event.key
的值是Process,根本无法判断到底输入的是什么。
所以, event.code
和 event.key
这两个不适合中文输入法下的输入判断。
好在,实际开发中,很少有场景需要提前知道用户是否开启了中文输入法。
更多的是一些功能键的判断。
例如空格、回车、删除、上下左右键、上一页下一页键,home/end键,ESC键等。
因此,接下来给大家罗列以下常见的功能键对应的 event.key
和 event.code
值。
三、常见功能键key值
功能键key值更实用,因此放在前面展示。
详见下表:
按键名称 | event.key | keyCode值 |
---|---|---|
回车 | Enter | 13 |
delete删除 | Delete | 46 |
backspace退格 | Backspace | 8 |
esc取消 | Escape | 27 |
tab索引 | Tab | 9 |
上 | ArrowUp | 38 |
下 | ArrowDown | 40 |
左 | ArrowLeft | 37 |
右 | ArrowRight | 39 |
pageDown下一页 | PageDown | 34 |
pageUp上一页 | PageUp | 33 |
home键 | Home | 36 |
end键 | End | 35 |
shift键 | Shift | 16 |
control键 | Control | 17 |
alt键 | Alt | 18 |
KeyboardEvent.key值兼容性要比KeyboardEvent.code值好一些,如下所示:
IE浏览器勉强支持,返回的值可能和规范中定义的有出入。如果要兼容IE浏览器,兼容可以用keyCode属性撑一会儿。
四、常见功能键的code值
如下表所示,大部分返回值和key值是一样的,因为都是功能键,如果是可打印字符,则code值和key值那就完全是两码事了:
按键名称 | event.code | 说明 |
---|---|---|
回车 | Enter | – |
delete删除 | Delete | Shift+NumpadDecimal也可能是删除 |
backspace退格 | Backspace | – |
esc取消 | Escape | – |
tab索引 | Tab | – |
上 | ArrowUp | 38 |
下 | ArrowDown | 40 |
左 | ArrowLeft | – |
右 | ArrowRight | – |
pageDown下一页 | PageDown | – |
pageUp上一页 | PageUp | – |
home键 | Home | – |
end键 | End | – |
shift键 | ShiftLeft/ShiftRight | – |
control键 | ControlLeft/ControlRight | – |
alt键 | AltLeft/AltRight | – |
兼容性如下截图所示:
五、送你一朵小红花
除了event.keyCode不推荐使用,event.which也不推荐使用了,官方名称为KeyboardEvent.which。
虽然不推荐使用,但是按照我的理解,99%的概率浏览器还会一直保持支持的,因为要是去掉这几个API特性,这世界上至少几百万个网站开发者会炸开锅。
当然,如果条件允许(不用考虑IE浏览器),我们还是优先使用 event.key
或者 event.code
来识别按键。
另外,相比原来的 event.keyCode
或者 eevent.which
, event.key
和 event.code
要更好上手,例如上下左右键的几个数字,我老是记不住,总有run一下看看值是多少,但是如果是 event.key
,则直接使用语义化的英文单词即可。
只需要记住单词规则,首字母大小,每个分词首字母大写就OK了。
OK,以上就是本文全部内容,加深了下我自己对键盘事件的一些了解,整理了几个常用功能键表格,这个回头开发我会用到。MDN上的表格实在是冗长,不适合实战中使用。
这篇文章估计分享的人不会很多。
不管怎样,依然送你一朵小红花,感谢您的阅读与支持!
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址: https://www.zhangxinxu.com/wordpress/?p=9755
(本篇完)