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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:40:21  来源:igfitidea点击:

KeyboardEvent.keyCode deprecated. What does this mean in practice?

javascriptkeydeprecatedkeycode

提问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 .keyCodeis provided for compatibility only and that the latest version of the DOM Events Specification recommend using the .keyproperty instead.

在 W3 学校,这个事实被淡化了,只有一个旁注说这.keyCode只是为了兼容性而提供的,最新版本的 DOM 事件规范建议使用该.key属性。

The problem is that .keyis 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 :
charCodeand keyIdentifierare non-standard features.
keyIdentifieris removed as of Chrome 54 and Opera 41.0
keyCodereturns 0, on keypress event with normal characters on FF.

此外,所有keyCodewhichcharCodekeyIdentifier都已弃用:
charCode并且keyIdentifier是非标准功能。
keyIdentifier从 Chrome 54 开始删除,Opera 41.0
keyCode在按键事件上返回 0,在 FF 上使用正常字符。

The key property:

关键属性

 readonly attribute DOMString key

Holds a key attribute value corresponding to the key pressed

持有与按下的键对应的键属性值

As of the time of this writing, the keyproperty 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 keyvalue is different from keyCodeor whichproperties 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值与keyCodewhich属性的不同之处在于:它包含键的名称而不是其代码。如果您的程序需要字符代码,那么您可以使用charCodeAt(). 对于可以使用的单个可打印字符charCodeAt(),如果您正在处理其值包含多个字符的键,例如ArrowUp:您正在测试特殊键并采取相应的措施。因此,尝试推行键的值的表和它们对应的代码charCodeArr["ArrowUp"]=38charCodeArr["Enter"]=13charCodeArr[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.codeproperty docsand some more details in this answer.

另请参阅:此答案中KeyboardEvent.code属性文档和更多详细信息。

回答by kumarharsh

TLDR: I'd suggest that you shoulduse the new event.keyand event.codeproperties 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.keyevent.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 keyCodebecomes more clear:

我来到这个问题是为了寻找与 OP 相同的 MDN 警告的原因。搜索更多之后,问题keyCode变得更加清晰:

The problem with using keyCodeis 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

它深入描述了以下问题keyCodehttps: //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 被替换的原因之后,让我们来看看你今天需要做的事情:

  1. All modern browsers support the new properties (keyand code).
  2. 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)
  3. 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/
  4. Refer to the list of event keys you can use: https://www.w3.org/TR/uievents-key/
  1. 所有现代浏览器都支持新属性(keycode)。
  2. IE 和 Edge 支持旧版本的规范,其中某些键的名称不同。您可以为它使用垫片:https: //github.com/shvaikalesh/shim-keyboard-event-key(或推出您自己的 - 反正它相当小)
  3. Edge 在最新版本中修复了这个错误(可能会在 2018 年 4 月发布) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
  4. 请参阅您可以使用的事件键列表: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'