不推荐使用KeyboardEvent.keyCode。实际上这是什么意思?


91

根据MDN,我们绝对应该使用该.keyCode属性。不推荐使用:

https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/keyCode

在W3学校中,这个事实被淡化了,只有一个旁注,.keyCode即提供该注释仅是为了兼容性,并且最新版本的DOM Events Specification建议使用该.key属性。

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


Answers:


31

您可以通过三种方式来处理它,因为它写在您共享的链接上。

if (event.key !== undefined) {

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

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

}

您应该考虑一下它们,如果您想要跨浏览器支持,那是正确的方法。

如果您实现这样的事情,可能会更容易。

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);
};

13
我确实读过这一点,但似乎没有很多其他代码,除了MDN所说的某些东西已被弃用,而实际上它在所有主流浏览器中都可以正常使用时。但是,如果那是正确的方法,那就谢谢!
Jason210 '16

3
哇,看这个。caniuse.com/#search=keyCode(有效的所有浏览器都支持此KeyboardEvent属性(因为IE6 +,Firefox 2 +,Chrome 1+等“谈论.keyCode”)
Miguel Lattuada

2
这就是所有这些令人讨厌的地方。所有主要的浏览器都支持keyCode,但是请尝试检查.key属性,这是推荐的属性,几乎没有使用它!
Jason210 '16

4
是的,我们要到2016年5月下旬,而chrome终于实现了KeyboardEvent.key属性。Safari和所有移动浏览器尚未加入“所有用户的16.5%”聚会。同样,令人遗憾的是,Microsoft Edge和Gecko对许多事件进行了不同的编码,例如:向上箭头的键事件编码为“ Up”而不是“ ArrowUp”。
约书亚·道森


26

此外,所有的键代码其中则charCodekeyIdentifier被弃用:
charCodekeyIdentifier是非标准的特性。
keyIdentifier从Chrome 54开始被删除,Opera 41.0
keyCode在FF事件上在FF上具有正常字符的情况下返回0。

关键属性

 readonly attribute DOMString key

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

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

请注意,该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  */  

可能是您想考虑向前兼容性,即在可用的旧属性中使用旧属性,并且仅在将其切换到新属性时使用:

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;
    }

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


您的解决方案在我的浏览器(Windows 10,Chrome 60,比利时键盘)中不起作用。首先,该charCodeArr功能不存在。同样,charCodeAt不适用于的所有值e.key。例如,对于Enter/ Return键,e.keyproperty的值为"Enter",并且charCodeArr对该字符串执行将返回该值69(这是该字符的ASCII代码E)。
John Slegers '17

@JohnSlegers,是的,这是一个错字,我的意思是用户构建数组。请查看我更新后的答案以获取更多详细信息。
user10089632

19

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 在平台之间甚至在不同操作系统或使用不同本地化的相同实现上都是不一致的

它深入描述了问题所在keyCodehttps : //www.w3.org/TR/uievents/#legacy-key-attributes

从未正式指定这些功能,当前的浏览器实现方式有很大不同。依赖于检测用户代理并采取相应行动的大量遗留内容(包括脚本库)意味着,将这些遗留属性和事件形式化的任何尝试都将有可能破坏其将要修复或启用的内容。此外,这些属性不适合国际使用,也不能解决可访问性问题。

因此,在确定了替换旧版keyCode的原因之后,让我们看看您今天需要做什么:

  1. 所有现代的浏览器都支持新的属性(keycode)。
  2. IE和Edge支持该规范的较旧版本,其中某些键的名称不同。您可以为其使用垫片:https : //github.com/shvaikalesh/shim-keyboard-event-key(或滚动自己的垫片-无论如何它都很小)
  3. Edge已在最新版本(可能于2018年4月发布)中修复了此错误-https: //developer.microsoft.com/zh-cn/microsoft-edge/platform/issues/8860571/
  4. 请参阅您可以使用的事件键列表:https : //www.w3.org/TR/uievents-key/

根据MDN,Internet Explorer和Edge均不支持KeyboardEvent.code。此外,对于价值观keycode是依赖于浏览器。使得这两个问题keycode没有实际的现实生活中的应用程序使用。
John Slegers


如果要测试箭头键,上/下,首页和尾页,应该使用key还是code?它通常是物理键,但也可能取决于Num Lock和布局...最佳实践是什么?
杰克

12

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

https://developer.mozilla.org/zh-CN/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);

3
不幸的是,它key是特定于浏览器的字符串值,例如"Enter"or,"ArrowUp"并且没有标准化的方式将其转换为相应的代码。因此您将需要更多样板代码来在键和代码之间进行转换。
John Slegers '17

5

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

代替

event.keyCode === 13

做喜欢

event.key === 'Enter'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.