不推荐使用KeyboardEvent.keyCode.这在实践中意味着什么?

Jas*_*210 76 javascript key keycode deprecated

根据MDN,我们绝对应该使用.keyCode属性.它已被弃用:

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

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

问题是.key浏览器不支持,那么我们应该使用什么?有什么我想念的吗?

Tho*_*wig 54

例如,如果您想检测是否单击了“Enter”键:

代替

event.keyCode === 13
Run Code Online (Sandbox Code Playgroud)

做喜欢

event.key === 'Enter'
Run Code Online (Sandbox Code Playgroud)

  • 请记住,从 `event.keyCode === 13` 更改为 `event.key === 'Enter'` 会删除对数字键盘键的支持。要支持两者,请选中两者: `event.key === 'Enter' || event.key === 'NumpadEnter'` 或更好:`['Enter', 'NumpadEnter'].includes(event.key)` (18认同)
  • `event.keyCode === 27` 变为:`event.key === 'Escape'` (5认同)
  • 根据问题的“实践”部分,这应该是公认的答案。 (4认同)
  • event.key 所有可能值的列表:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values (4认同)
  • 对于非 ASCII 组合字母,按键事件会触发两次。每个都是 { key: 'Enter', keyCode: 13 }, { key: 'Enter', keyCode: 229 }。如果没有 keyCode,如何避免第二次事件? (3认同)
  • @AustinArnett `.key==="Enter"` 对于两个键。但`.code`也可以是“NumpadEnter”。 (2认同)

use*_*632 23

此外,所有的键代码,其中,则charCodekeyIdentifier被弃用:
charCodekeyIdentifier是非标准的特性.
keyIdentifier从Chrome 54开始删除,Opera 41.0
keyCode在FF上使用普通字符的按键事件时返回0.

关键属性:

 readonly attribute DOMString key
Run Code Online (Sandbox Code Playgroud)

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

截至撰写本文时,该key属性受到以下所有主流浏览器的支持:Firefox 52,Chrome 55,Safari 10.1,Opera 46. Internet Explorer 11除外,它具有: 非标准密钥标识符和AltGraph的错误行为.更多信息
如果这是重要的和/或向后兼容性,那么您可以使用功能检测,如下面的代码所示:

请注意,该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  */  
Run Code Online (Sandbox Code Playgroud)

您可能想要考虑向前兼容性,即在可用时使用旧版属性,并且只有在删除切换到新属性时:

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;
    }
Run Code Online (Sandbox Code Playgroud)

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


Mig*_*ada 22

您有三种方法可以处理它,因为它是在您共享的链接上编写的.

if (event.key !== undefined) {

} else if (event.keyIdentifier !== undefined) {

} else if (event.keyCode !== undefined) {

}
Run Code Online (Sandbox Code Playgroud)

你应该考虑它们,如果你想要跨浏览器支持,这是正确的方法.

如果你实现这样的东西可能会更容易.

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);
};
Run Code Online (Sandbox Code Playgroud)

  • 我确实读到了这一点,但似乎有很多额外的代码,除了MDN之外没有其他原因说过某些东西已被弃用,当它在所有主流浏览器中都能正常工作时.但如果这是正确的方式,那么谢谢! (7认同)
  • 是的,我们到2016年5月下旬,chrome终于实现了KeyboardEvent.key属性.Safari以及每个移动浏览器尚未加入"16.5%的所有用户"派对.另外,遗憾的是,Microsoft Edge和Gecko对不同的事件进行了不同的编码,例如:向上箭头的关键事件编码为"Up"而不是"ArrowUp". (4认同)
  • 哇,看这个。http://caniuse.com/#search=keyCode(实际上,所有浏览器均支持此KeyboardEvent属性(因为IE6 +,Firefox 2 +,Chrome 1+等“谈论.keyCode”) (3认同)
  • 但是`event.key`是一个字符串,而`event.keyCode`是一个数字,对吧?鉴于它们甚至没有相同的类型,它们是否可以具有相同的语义?或者你的意思是“event.code”? (3认同)
  • 截至目前,所有主流浏览器都支持“event.key”和“event.code”(查看@kumarharsh的答案)。它是一个“字符串”也使它更具可读性,所以我建议将它用于所有新代码。为了维护遗产,这将取决于你对它作为“数字”的依赖程度。请注意,当您按下可打印的键时,“event.key”“a”和“A”是不同的,而“event.code”对于两者来说都是“keyA”。对于不可打印的情况,您可以将“event.code”设置为“ShiftLeft”或“ShiftRight”,而“event.key”则为“Shift”。 (3认同)
  • 这就是所有这些令人讨厌的事情.所有主流浏览器都支持keyCode,但是请尝试检查.key属性,这是推荐的属性,几乎没有任何使用它! (2认同)

kum*_*rsh 15

TLDR:我建议你应该使用new event.keyevent.code属性而不是遗留属性.IE和Edge支持这些属性,但尚不支持新的密钥名称.对于他们来说,有一个小的polyfill,使他们输出标准的键/代码名称:

https://github.com/shvaikalesh/shim-keyboard-event-key


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

使用的问题keyCode是非英语键盘可以产生不同的输出,甚至具有不同布局的键盘也会产生不一致的结果.另外,有的情况是

如果您阅读W3C规范:https: //www.w3.org/TR/uievents/#interface-keyboardevent

实际上,keyCode和charCode在不同平台之间是不一致的,甚至在不同操作系统上使用相同的实现或使用不同的本地化.

它深入描述了错误keyCode:https: //www.w3.org/TR/uievents/#legacy-key-attributes

这些功能从未正式指定,当前的浏览器实现方式也有很大差异.依赖于检测用户代理并相应地执行操作的大量遗留内容(包括脚本库)意味着任何将这些遗留属性和事件正式化的尝试都有可能破坏尽可能多的内容以及修复或启用的内容.此外,这些属性不适合国际使用,也不涉及可访问性问题.

因此,在确定替换旧密钥代码的原因之后,让我们看看您今天需要做什么:

  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/

  • 它是一个“字符串”也使其更具可读性,因此建议将它用于所有新代码。为了维护遗产,这将取决于你对它作为“数字”的依赖程度。请注意,当您按下可打印的键时,“event.key”“a”和“A”是不同的,而“event.code”对于两者来说都是“keyA”。对于不可打印的情况,您可以将“event.code”设置为“ShiftLeft”或“ShiftRight”,而“event.key”则为“Shift”。 (2认同)

Vic*_*ves 11

MDN已经提供了一个解决方案:

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);
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,“ key”是浏览器特定的字符串值,例如“ Enter”或“ ArrowUp”,并且没有标准化的方式将其转换为相应的代码。因此您将需要更多样板代码来在键和代码之间进行转换。 (3认同)

Ala*_*lan 7

e.charCode已被弃用:

<input
  onChange={(e) => setToken(e.target.value)}
  type="text"
  value={token}
  onKeyPress={(e) => {
    if (e.charCode === 13) {
      verifyLoginF()
    }
  }}
/>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

你现在应该使用:e.key === 'Enter'

在此输入图像描述