这篇文章发布于 2021年01月4日,星期一,23:29,归类于 JS API。 阅读 31076 次, 今日 3 次 25 条评论
by zhangxinxu 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,根本就没法继续玩了。
补充于2023-02-08
最近发现,中文输入法开启时候keyCode值是229还是有用的。
当我们希望监听输入框是否按下Enter键触发submit行为的时候,使用event.keyCode
可以避免输入法回车(使用英文)不小心触发submit事件的问题。
如果使用event.code或event.key,无论输入法是否开启,返回的都是 ‘Enter’,就会导致中文输入场景下,内容还没写入就被提交的情况出现。
或许是因为上面指出的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
(本篇完)
- 奇了怪了,输入法和JS Enter回车提交冲突 (0.645)
- HTML kbd、var、samp元素你使用过没? (0.346)
- 网页制作辅助工具-jQuery标尺参考线插件 (0.230)
- HTML tabindex属性与web网页键盘无障碍访问 (0.069)
- HTML accesskey属性与web自定义键盘快捷访问 (0.069)
- 借助HTML5 details,summary无JS实现各种交互效果 (0.069)
- 是时候好好安利下LuLu UI框架了! (0.069)
- 实力科普:为什么浮层或弹框一定要有叉叉关闭按钮? (0.069)
- CSS :focus-visible伪类让我感动哭了 (0.069)
- HTML enterkeyhint设置iOS/Android键盘enter键 (0.069)
- HTML5 placeholder实际应用经验分享及拓展 (RANDOM - 0.009)
应该说的是不同键盘布局上同样的 keyCode 对应的字符是不一样的。不过这个对中文用户没啥影响(大家都是 qwerty 布局)。倒是很多网页应用会判断 Esc 的 keydown 事件,然后我输入法打错字了要撤销呢,结果网页应用把我正在进行的编辑也给撤销了……
很蛋疼的是中文输入法在打字的时候,按下回车也会直接触发Enter,而不是确认
这就导致用户可能会误操作
还是得用keyCode来判断
恰恰相反,我是看到有人用 Google Chrome 结果输入法里回车网页也回车,才找到这篇文章的。输入法在打字的时候按回车,你网页抢个啥啊……
我最近在做类似的开发,遇到了即使都是Chrome,win和macOs下输入中文句号的表现是不一样的。
在win下会返回“Process”,而在mac下返回的就是原有的标点。想要靠这种方法实现中文标点监控几乎不可能。
有兴趣的可以去看这篇文章,里面有讲到 vscode 是如何解决键盘快捷键问题的。
张大湿,能否把图中那个键盘洗干净了再拍照,?,强迫症了
值在前侧,不在上面
前些天vscode报错提示说keyCode被放弃,还一头雾水,但看Chrome还能用,就没在意了~今天就看到这个了,学习了
刚刚有人遇到了个输入法按回车相关的 bug,就 Google Chrome(以及各种基于 Electron 的应用)里有 bug,火狐好好的,哈哈。
在使用Reeder订阅rss阅读会出现以下文字
//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=9755(作者张鑫旭)
最近正好做了一个交互式的键码对照表,按什么键,就显示对应的 event.code, event.key 等信息,请大佬检阅 https://www.dute.org/keycodes
赞~
其实一直都是用keyCode判断的,接触过的场景里大多是监听回车而已~~
测试了一些,中文输入法下「,。()——」等字符的 event.key 和 event.code 跟英文输入法下没区别,效果如下。
https://pic4.zhimg.com/v2-d3e2a1732c6e9b6b617f278a4fd06609.png
复现环境:https://432bq.csb.app/
什么输入法,我用的搜狗。
mac自带的中文输入法测试了一些中文符号也没区别~
我用的也是搜狗,Mac 下
清楚keyCode的问题,才能解决输入监听的问题。学到了,赞。
中文场景……如果用`compositionend`呢?
conpositionend,好东西。However,有一些诡异浏览器与输入法的组合会干一些莫名其妙的事情。
有什么场景是需要判断中文符号的吗。。
貌似以前在Excel中公式用中文括号,Excel是认的。
这键帽可以
哈哈,我来阅读一番。
大早上吃着早餐看着文章, 别有一番风味~~?
学到了