Javascript 不推荐使用 KeyboardEvent.keyCode。这在实践中意味着什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35394937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
KeyboardEvent.keyCode deprecated. What does this mean in practice?
提问by Jason210
According to MDN, we should most definitely notbe using the .keyCode property. It is deprecated:
根据 MDN,我们绝对不应该使用 .keyCode 属性。它已被弃用:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
On W3 school, this fact is played down and there is only a side note saying that .keyCode
is provided for compatibility only and that the latest version of the DOM Events Specification recommend using the .key
property instead.
在 W3 学校,这个事实被淡化了,只有一个旁注说这.keyCode
只是为了兼容性而提供的,最新版本的 DOM 事件规范建议使用该.key
属性。
The problem is that .key
is not supported by browsers, so what should we using? Is there something I'm missing?
问题是.key
浏览器不支持,那我们应该用什么?有什么我想念的吗?
采纳答案by Miguel Lattuada
You have three ways to handle it, as it's written on the link you shared.
您可以通过三种方式来处理它,因为它写在您共享的链接上。
if (event.key !== undefined) {
} else if (event.keyIdentifier !== undefined) {
} else if (event.keyCode !== undefined) {
}
you should contemplate them, that's the right way if you want cross browser support.
你应该考虑它们,如果你想要跨浏览器支持,这是正确的方法。
It could be easier if you implement something like this.
如果你实现这样的东西可能会更容易。
var dispatchForCode = function(event, callback) {
var code;
if (event.key !== undefined) {
code = event.key;
} else if (event.keyIdentifier !== undefined) {
code = event.keyIdentifier;
} else if (event.keyCode !== undefined) {
code = event.keyCode;
}
callback(code);
};
回答by user10089632
In addition that all of keyCode, which, charCodeand keyIdentifierare deprecated :charCode
and keyIdentifier
are non-standard features.keyIdentifier
is removed as of Chrome 54 and Opera 41.0keyCode
returns 0, on keypress event with normal characters on FF.
此外,所有keyCode、which、charCode和keyIdentifier都已弃用:charCode
并且keyIdentifier
是非标准功能。keyIdentifier
从 Chrome 54 开始删除,Opera 41.0keyCode
在按键事件上返回 0,在 FF 上使用正常字符。
关键属性:
readonly attribute DOMString key
Holds a key attribute value corresponding to the key pressed
持有与按下的键对应的键属性值
As of the time of this writing, the key
property is supported by all major browsers as of : Firefox 52, Chrome 55, Safari 10.1, Opera 46. Except Internet Explorer 11 which has :
non-standard key identifiers and incorrect behavior with AltGraph. More info
If that is important and/or backward compatibility is, then you can use feature detection as in the following code :
在撰写本文时,key
所有主要浏览器都支持该属性:Firefox 52、Chrome 55、Safari 10.1、Opera 46。 Internet Explorer 11 除外,它具有:
非标准密钥标识符和 AltGraph 的错误行为。更多信息
如果这很重要和/或向后兼容,那么您可以使用以下代码中的功能检测:
Notice that the key
value is different from keyCode
or which
properties in that : it contains the name of the key not its code. If your program needs characters' codes then you can make use of charCodeAt()
.
For single printable characters you can use charCodeAt()
, if you're dealing with keys whose values contains multiple characters like ArrowUpchances are : you are testing for special keys and take actions accordingly. So try implementing a table of keys' values and their corresponding
codes charCodeArr["ArrowUp"]=38
, charCodeArr["Enter"]=13
,charCodeArr[Escape]=27
... and so on, please take a look at Key Valuesand their corresponding codes
请注意,该key
值与keyCode
或which
属性的不同之处在于:它包含键的名称而不是其代码。如果您的程序需要字符代码,那么您可以使用charCodeAt()
. 对于可以使用的单个可打印字符charCodeAt()
,如果您正在处理其值包含多个字符的键,例如ArrowUp:您正在测试特殊键并采取相应的措施。因此,尝试推行键的值的表和它们对应的代码charCodeArr["ArrowUp"]=38
,charCodeArr["Enter"]=13
,charCodeArr[Escape]=27
...等,请看一看核心价值及其对应的代码
if(e.key!=undefined){
var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
}else{
/* As @Leonid suggeted */
var characterCode = e.which || e.charCode || e.keyCode || 0;
}
/* ... code making use of characterCode variable */
May be you want to consider forward compatibility i.e use the legacy properties while they're available, and only when dropped switch to the new ones :
可能您想考虑向前兼容性,即在旧属性可用时使用它们,并且仅在删除时才切换到新属性:
if(e.which || e.charCode || e.keyCode ){
var characterCode = e.which || e.charCode || e.keyCode;
}else if (e.key!=undefined){
var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
}else{
var characterCode = 0;
}
See also : the KeyboardEvent.code
property docsand some more details in this answer.
回答by kumarharsh
TLDR: I'd suggest that you shoulduse the new event.key
and event.code
properties instead of the legacy ones. IE and Edge have support for these properties, but don't support the new key names yet. For them, there is a small polyfill which makes them output the standard key/code names:
TLDR:我建议您应该使用新的event.key
和event.code
属性而不是旧的。IE 和 Edge 支持这些属性,但尚不支持新的键名。对于他们来说,有一个小的 polyfill 可以让他们输出标准的密钥/代码名称:
https://github.com/shvaikalesh/shim-keyboard-event-key
https://github.com/shvaikalesh/shim-keyboard-event-key
I came to this question searching for the reason of the same MDN warning as OP. After searching some more, the issue with keyCode
becomes more clear:
我来到这个问题是为了寻找与 OP 相同的 MDN 警告的原因。搜索更多之后,问题keyCode
变得更加清晰:
The problem with using keyCode
is that non-English keyboards can produce different outputs and even keyboards with different layouts can produce inconsistent results. Plus, there was the case of
使用的问题keyCode
是非英文键盘会产生不同的输出,甚至不同布局的键盘也会产生不一致的结果。另外,还有一个案例
If you read the W3C spec: https://www.w3.org/TR/uievents/#interface-keyboardevent
如果您阅读 W3C 规范:https: //www.w3.org/TR/uievents/#interface-keyboardevent
In practice, keyCode and charCode are inconsistentacross platforms and even the same implementation on different operating systems or using different localizations.
在实践中,keyCode 和 charCode跨平台不一致,甚至在不同操作系统上或使用不同本地化的相同实现。
It goes into some depth describing what was wrong with keyCode
:
https://www.w3.org/TR/uievents/#legacy-key-attributes
它深入描述了以下问题keyCode
:https:
//www.w3.org/TR/uievents/#legacy-key-attributes
These features were never formally specified and the current browser implementations vary in significant ways. The large amount of legacy content, including script libraries, that relies upon detecting the user agent and acting accordingly means that any attempt to formalize these legacy attributes and events would risk breaking as much content as it would fix or enable. Additionally, these attributes are not suitable for international usage, nor do they address accessibility concerns.
这些功能从未被正式指定,当前的浏览器实现有很大的不同。大量遗留内容(包括脚本库)依赖于检测用户代理并相应地采取行动,这意味着任何将这些遗留属性和事件形式化的尝试都可能破坏与修复或启用一样多的内容。此外,这些属性不适合国际使用,也不能解决可访问性问题。
So, after establishing the reason why the legacy keyCode was replaced, let's look at what you need to do today:
那么,在确定了遗留 keyCode 被替换的原因之后,让我们来看看你今天需要做的事情:
- All modern browsers support the new properties (
key
andcode
). - IE and Edge support an older version of the spec, which has different names for some keys. You can use a shim for it: https://github.com/shvaikalesh/shim-keyboard-event-key(or roll your own - it's rather small anyways)
- Edge has fixed this bug in the latest release (probably will be released in Apr 2018) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
- Refer to the list of event keys you can use: https://www.w3.org/TR/uievents-key/
- 所有现代浏览器都支持新属性(
key
和code
)。 - IE 和 Edge 支持旧版本的规范,其中某些键的名称不同。您可以为它使用垫片:https: //github.com/shvaikalesh/shim-keyboard-event-key(或推出您自己的 - 反正它相当小)
- Edge 在最新版本中修复了这个错误(可能会在 2018 年 4 月发布) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
- 请参阅您可以使用的事件键列表:https: //www.w3.org/TR/uievents-key/
回答by Vicky Gonsalves
MDN has already provided a solution:
MDN已经提供了解决方案:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
window.addEventListener("keydown", function (event) {
if (event.defaultPrevented) {
return; // Should do nothing if the default action has been cancelled
}
var handled = false;
if (event.key !== undefined) {
// Handle the event with KeyboardEvent.key and set handled true.
} else if (event.keyIdentifier !== undefined) {
// Handle the event with KeyboardEvent.keyIdentifier and set handled true.
} else if (event.keyCode !== undefined) {
// Handle the event with KeyboardEvent.keyCode and set handled true.
}
if (handled) {
// Suppress "double action" if event handled
event.preventDefault();
}
}, true);
回答by Thomas Gotwig
For instance if you want to detect whether the "Enter"-key was clicked or not:
例如,如果您想检测是否单击了“Enter”键:
Instead of
代替
event.keyCode === 13
Do it like
做喜欢
event.key === 'Enter'