.keyCode 与 .which

IT技术 javascript jquery
2021-01-12 22:31:28

我以为这会在 Stack Overflow 的某个地方得到解答,但我找不到。

如果我正在监听按键事件,我应该使用.keyCode还是.which确定是否按下了 Enter 键?

我一直在做类似以下的事情:

$("#someid").keypress(function(e) {
  if (e.keyCode === 13) {
    e.preventDefault();
    // do something
  }
});

但我看到使用.which而不是.keyCode. 有什么不同?一个比另一个更跨浏览器友好吗?

6个回答

注意:下面的答案是在 2010 年写的。多年后,这里keyCodewhich都被弃用,以支持key(对于逻辑键)和code(对于的物理位置)。但请注意,IE 不支持code,并且其支持key基于旧版本的规范,因此不太正确。在我写这篇文章时,当前基于 EdgeHTML 和 Chakra 的 Edge 都不支持code,但微软正在推出基于BlinkV8的 Edge 替代品,这可能会/将会。


一些浏览器使用keyCode,其他浏览器使用which.

如果你使用 jQuery,你可以可靠地使用whichjQuery标准化的东西更多在这里。

如果你不使用 jQuery,你可以这样做:

var key = 'which' in e ? e.which : e.keyCode;

或者:

var key = e.which || e.keyCode || 0;

...它处理e.which可能存在的可能性0(通过0在最后恢复它,使用JavaScript 的异常强大的||operator)。

@ScottE,这是一个基本参考:quirksmode.org/js/keys.html(它不包括which,我认为它仅由 jQuery 提供,但我不是 100% 确定,但它应该让你开始看到浏览器的差异)
2021-03-13 22:31:28
谢谢 TJ 我在哪里可以找到这方面的参考资料?不是我不相信你,我只是好奇!...我看到你刚刚添加了,谢谢。那么,即使对于那些不使用 jquery 的人来说,.哪个是更好的选择?
2021-03-26 22:31:28
@TJ Crowder:是的,事件的which属性可以为零,这对大多数应用程序都有很大的不同。例如,在Firefox不可打印键有一个which的零属性和相同keyCode属性作为keydownkeyCode在我的 Firefox 电脑上,Home 键的值为 36,这是“$”的字符代码,这使得用户无法区分按下 Home 键的用户和使用event.which || event.keyCode.
2021-03-28 22:31:28
@fudgey:由除 IE 之外的所有浏览器which提供keypress而且 quirksmode 在这里没有权威性。作为参考,@TJ Crowder 发布的链接要好得多:unixpapa.com/js/key.html
2021-04-01 22:31:28
@ScottE:如果不使用 jQuery,您必须自己明确处理。我通常不喜欢这样var key = event.which || event.keyCode;,将使用event.which,如果它的定义,而不是falsey,或者event.keyCode如果which未定义或falsey。从技术上讲,我可能应该这样做,var key = typeof event.which === "undefined" ? event.keyCode : event.which;但如果event.which0(可以0吗?),我不太可能关心我所做的事情。
2021-04-07 22:31:28

jQuery的正常化event.which取决于是否event.whichevent.keyCode或者event.charCode是由浏览器的支持:

// Add which for key events
if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
   event.which = event.charCode != null ? event.charCode : event.keyCode;
}

一个额外的好处.which是 jQuery 也可以用于鼠标点击:

// Add which for click: 1 === left; 2 === middle; 3 === right
// Note: button is not normalized, so don't use it
if ( !event.which && event.button !== undefined ) {
    event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
}
@anne-van-rossum,event.wich == null && ...仅测试 null 或 undefined。event.wich || ...测试(未定义、空、假、0、''等)
2021-04-04 22:31:28
@aMarCruz Falsy 故意的。例如,带有 Webkit 报告的bugs.webkit.org/show_bug.cgi?id=167350我不认为检查""[]伤害。
2021-04-05 22:31:28
var key = event.which || event.charCode || event.keyCode
2021-04-09 22:31:28

如果您使用的是 vanilla Javascript,请注意 keyCode 现在已弃用并将被删除:

此功能已从 Web 标准中删除。虽然一些浏览器可能仍然支持它,但它正在被删除。尽可能避免使用它并更新现有代码;请参阅本页底部的兼容性表以指导您的决定。请注意,此功能可能随时停止工作

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

而是使用:.key.code,具体取决于您想要的行为:https : //developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US/docs/Web/API/KeyboardEvent/key

两者都在现代浏览器上实现。

.code对应于键盘上按键的物理位置,而.key对应于由按下的键生成的字符,而不管位置如何。
2021-03-15 22:31:28
嗯...实际上以跨浏览器的方式实现 key 看起来并不太糟糕。常规的字母数字键只返回它们的值,控制键(escape、enter、tab 等)在大多数浏览器中实现相同钥匙。
2021-03-15 22:31:28
IMO 不会从浏览器实现中删除任何内容,因为这会破坏许多现有的站点和库。
2021-04-01 22:31:28
我建议使用key而不是code. 例如,如果您有一个带有媒体控制键的键盘,按播放/暂停会输出 "MediaPlayPause" forkey和 "" for code
2021-04-07 22:31:28
'code' 和 'key' 在现代浏览器中都有怪癖。在不同浏览器中使用 MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code上的“试用”示例表明 IE11/IE Edge 没有实现“代码”和“密钥”实现与 Chrome/FF/Safari 中的实现不匹配(差异似乎主要在于 Escape 和 Enter 等控制字符)。我认为使用库可能是最简单的,除非您愿意自己解决这些变幻莫测的问题。我真的希望这是答案,但 IE 把这个搞砸了 :-(
2021-04-09 22:31:28

我建议event.key目前。MDN 文档:https : //developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCode并且event.which它们的 MDN 页面顶部都有令人讨厌的弃用警告:
https : //developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode https://developer.mozilla.org/en-US /docs/Web/API/KeyboardEvent/which

对于字母数字键,event.key似乎在所有浏览器中实现相同。对于控制键(tab、enter、escape 等),event.key在 Chrome/FF/Safari/Opera 中具有相同的值,但在 IE10/11/Edge 中具有不同的值(IE 显然使用旧版本的规范,但彼此匹配2018 年 1 月 14 日)。

对于字母数字键,检查将类似于:

event.key === 'a'

对于控制字符,您需要执行以下操作:

event.key === 'Esc' || event.key === 'Escape'

我使用这里的示例在多个浏览器上进行测试(我必须在 codepen 中打开并进行编辑才能使其与 IE10 一起使用):https : //developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/代码

event.code 在一个不同的答案中提到了一种可能性,但 IE10/11/Edge 没有实现它,所以如果你想要 IE 支持它就不行了。

看看这个:https : //developer.mozilla.org/en-US/docs/Web/API/event.keyCode

在 keypress 事件中,按下的键的 Unicode 值存储在 keyCode 或 charCode 属性中,不能同时存储两者。如果按下的键生成一个字符(例如'a'),则 charCode 被设置为该字符的代码,尊重字母大小写。(即 charCode 考虑是否按住 shift 键)。否则,按下键的代码存储在 keyCode 中。keyCode 总是在 keydown 和 keyup 事件中设置。在这些情况下,永远不会设置 charCode。无论是存储在 keyCode 还是 charCode 中,要获取密钥的代码,请查询 which 属性。通过 IME 输入的字符不会通过 keyCode 或 charCode 注册。