.keyCode与。哪个


228

我以为可以在Stack Overflow的某处得到答案,但是我找不到它。

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

我一直都做以下事情:

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

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


1
仅供参考,这两个现在都已弃用。developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/
哪一个

Answers:


209

注:下面的答案写于2010年在这里很多年以后,无论是keyCodewhich赞成不赞成使用key(对于逻辑密钥)和code(对于关键的物理位置)。但是请注意,IE不支持code,并且它对key规范的支持是基于较早版本的规范,因此不太正确。在我撰写本文时,当前基于EdgeHTML和Chakra的Edge均不支持code,但Microsoft正在为其Edge推出基于BlinkV8的替代产品,据推测可以/将会这样做。


有些浏览器使用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的好奇,强大的||运营商)。


2
谢谢TJ我在哪里可以找到参考呢?不是说我不相信你,我只是好奇!...我看到你刚刚添加了,谢谢。因此,即使对于不使用jquery的用户,。哪个更好的选择?
ScottE 2010年

7
@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.which可以0(可以0吗?),我不太可能在乎我所做的事情。
TJ Crowder 2010年

2
@ScottE,这是一个基本参考:quirksmode.org/js/keys.html(它不包括which,我认为它仅由jQuery提供,但我不确定100%,但这应该可以让您开始了解浏览器的差异)
Mottie 2010年

1
@fudgey:除IE之外的所有浏览器which均提供keypress。而quirksmode在这里不是权威。作为参考,@ TJ Crowder发布的链接要好得多:unixpapa.com/js/key.html
蒂姆·唐

5
@TJ Crowder:是的,事件的which属性可以为零,这对于大多数应用程序来说可以有很大的不同。例如,Firefox中的不可打印键的which属性为零,与的keyCode属性相同keydown。Home键keyCode在Firefox的PC上为36,这是“ $”的字符代码,这使得无法区分用户按下Home键还是使用键入$字符event.which || event.keyCode
蒂姆·唐

32

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

.whichjQuery的另一个好处是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 ) ));
}

2
var key = event.which || event.charCode || event.keyCode
Anne van Rossum 2014年

@ anne-van-rossum,event.wich == null && ...仅测试null或未定义。您的event.wich || ...测试是否存在虚假(未定义,null,false,0,''等)
aMarCruz

@aMarCruz Falsy是故意的。例如具有Webkit报告功能的bugs.webkit.org/show_bug.cgi?id=167350。而且我不认为检查""[]伤害。
安妮·范·罗苏姆

20

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

此功能已从Web标准中删除。尽管某些浏览器可能仍支持它,但是它正在被删除。避免使用它,并尽可能更新现有代码;请参阅此页面底部的兼容性表以指导您做出决定。请注意,此功能可能在任何时间都无法使用

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

而是根据您想要的行为使用:.key.codehttps//developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US / docs / Web / API / KeyboardEvent / key

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


.code对应于键盘上键的物理位置,而.key对应于无论位置如何均由按下的键生成的字符。
Christopher

1
在现代浏览器中,“代码”和“键”都具有怪异之处。在不同的浏览器中使用MDN developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/code上的“尝试一下”示例,表明IE11 / IE Edge没有实现“代码”和“密钥”实现与Chrome / FF / Safari中的实现不匹配(差异似乎主要在于控制字符,例如Escape和Enter)。我认为使用图书馆可能是最简单的方法,除非您愿意自己解决这些变化。我真的希望这是答案,但是IE将这个问题
搞定

嗯...实际上,以跨浏览器的方式实现密钥看起来还不错。常规的字母数字键仅返回其值,并且对于大多数浏览器而言,控制键(转义,输入,制表符等)的实现方式相同,但IE11 / Edge除外,后者实现了规范的较早版本,因此每个浏览器至少只有两个可能的值键。
Akrikos

我建议使用key而不是code。例如,如果您有一个带有媒体控制键的键盘,则按Play / Pause(播放/暂停)输出,“ MediaPlayPause”为key,“”为code
thdoan

6

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

在按键事件中,按键的Unicode值存储在keyCode或charCode属性中,而不是两者都存储。如果按下的键生成一个字符(例如“ a”),则将charCode设置为该字符的代码,同时注意字母大小写。(即charCode考虑是否按住Shift键)。否则,按下的键的代码将存储在keyCode中。keyCode始终在keydown和keyup事件中设置。在这些情况下,永远不会设置charCode。要获取密钥的代码而不管它是存储在keyCode还是charCode中,请查询which属性。通过IME输入的字符不会通过keyCode或charCode注册。


6

event.key目前建议。MDN文档:https//developer.mozilla.org/zh-CN/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 /

对于字母数字键,event.key似乎在所有浏览器中都是完全相同的。对于控制键(制表符,输入,转义等),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/zh-CN/docs/Web/API/KeyboardEvent/码

event.code 在另一种答案中提到它是可能的,但是IE10 / 11 / Edge并未实现它,所以如果您要IE支持,那就来了。


2

强大的Javascript库,用于捕获键盘输入和输入的按键组合。它没有依赖性。

http://jaywcjlove.github.io/hotkeys/

hotkeys('ctrl+a,ctrl+b,r,f', function(event,handler){
    switch(handler.key){
        case "ctrl+a":alert('you pressed ctrl+a!');break;
        case "ctrl+b":alert('you pressed ctrl+b!');break;
        case "r":alert('you pressed r!');break;
        case "f":alert('you pressed f!');break;
    }
});

热键了解以下修饰符:shiftoptionaltctrlcontrolcommand,和

以下特殊键可用于快捷键:backspacetabclearenterreturnescescapespaceupdownleftrighthomeendpageuppagedowndeldeletef1通过f19


但是,它确实使Array.prototype.indexOf产生了填充,因此,如果您在另一个库中使用它,则它可能会不合适,因为它会修改全局范围。它似乎也使用不推荐使用event.keyCode
Akrikos

该库在我的Vaio笔记本电脑上未检测到Fn。
thdoan

0

在Firefox中,keyCode属性在onkeypress事件上不起作用(只会返回0)。对于跨浏览器的解决方案,请结合使用which属性和keyCode,例如:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
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.