如何处理不同浏览器上的不同keyCode?

20
我看到一些关于不同浏览器报告不同keyCode的论坛帖子,但每个人似乎都回避了“为什么”。
我试图捕获冒号(:)的keyCode,并意识到Firefox返回的是e.keyCode 56。而Chrome返回的是186(我想是这个)。
是否有一种在所有浏览器中获取正确keyCode的通用方法?
如果它们是相同的按键,为什么它们会不同?
我更想知道是否有一种国际通用的方式来获取相同的按键。

http://www.quirksmode.org/js/keys.html - gblazex
1
@galambalazs,这张图表没有考虑冒号和分号。这让我很惊讶。PPK通常对这种事情非常在行。 - Senica Gonzalez
http://unixpapa.com/js/key.html 包含冒号和分号,看起来非常详尽。 - ruffin
1
KeyEvent(以及其中的keyCodes)基本上已被弃用,并被KeyboardEvent替代。这并不是回答为什么不同的浏览器报告不同的keyCodes,但希望指出在未来可能会成为一个好的解决方案的地方。可能的。 - Marc Durdin
7个回答

18

这取决于你是想知道用户按下了哪个物理键,还是输入了哪个字符。如果你需要的是字符,那么在所有主流浏览器中可以可靠地获取它(在大多数浏览器中使用 keypress 事件的 which 属性或 keyCode 在 IE <= 8 中),但只能在 keypress 事件中获取。如果你想要获得键值,则使用 keydownkeyup 事件并检查 keyCode 属性,尽管确切的键码映射在不同浏览器之间略有不同。

关于所有 JavaScript 键相关事件的详细解释和参考资料,请访问 http://unixpapa.com/js/key.html

要可靠地检测用户在所有主要浏览器中输入冒号字符,可以执行以下操作:

document.onkeypress = function(e) {
    e = e || window.event;
    var charCode = (typeof e.which == "number") ? e.which : e.keyCode;
    if (charCode && String.fromCharCode(charCode) == ":") {
        alert("Colon!");
    }
};

charCode != keyCode,除了 /[A-Z 0-9]/。 - Nathan Bubna
@NathanBubna: 我知道。然而,在旧版IE的keypress事件中,keyCode令人困惑地字符代码,而不是键代码,所有其他主流浏览器都支持which,因此keyCode仅用于旧版IE。请在http://unixpapa.com/js/key.html(链接到我的答案)中阅读有关此问题的所有信息。 - Tim Down
糟糕,又是老旧的IE浏览器出问题了。感谢您的解释! - Nathan Bubna

13

1
我所包含的链接中的结论部分包含了一些信息,可能会帮助您实现通用解决方案 - 这取决于您的具体情况。 - Plaudit Design
你给我提供的那篇文章很棒。 - Senica Gonzalez
这是一个只有链接的回答。链接仍然有效,但你能否在这里提供一个摘要(用你自己的话)? - undefined
好的,OP已经离开了这个场所:"最后一次出现是在8年前"。 - undefined

3

这是一个老问题。现代的做法是使用event.key。请参阅MDN Key


1
这仍然是当前的方式,因为Key仍处于草案状态,并且在大多数移动浏览器上不被支持。 http://caniuse.com/#feat=keyboardevent-key - Nicu Surdu
随你便,它并不是很遥远。值得注意的是,迄今为止最受欢迎的移动浏览器Chrome for Android已经完全支持。最大的问题在于iOS和Safari,尽管Safari的支持将在下一个版本中推出。我建议使用众多可用的polyfills之一。 - kidconcept
实际上你可以使用它。它支持大多数常用的浏览器。(http://caniuse.com/#feat=keyboardevent-key) 如果该属性未定义,您仍然可以使用一个小型回退函数。 - CodeBrauer
请注意,某些现代浏览器存在差异。例如,在启用数字键锁定的情况下按下小数点键(. / Del)时,在Edge中报告事件键为“Del”,但在Chrome中报告为“.”。人们一直建议Safari是新的Internet Explorer。最近我想知道Edge是否真的是新的Internet Explorer。哦,等等。 - Dale Harris

1

2022 - event.key给出"逻辑"按键,event.code给出"物理"按键

在MacOS Firefox、Windows Edge和Windows Chrome上测试了一些示例:

event.key event.code
"Enter" "Enter"
"Enter" "NumpadEnter"
"8" "Digit8"
"8" "Numpad8"
"/" "Slash"
"/" "NumpadDivide"

极端情况

  • 在Windows Chrome/Edge上,当按下ctrl+Enter时,event.key"\n"

0

我是2023,我已经使用了一种不同的解决方案很长时间了。

它涉及使用隐藏的文本区域来获取键入的字符。这有点像黑客行为,但在所有主要浏览器中都可以完美运行,并且可以避免使用e.key或e.keyCode等带来的麻烦。

我将在此处发布代码。它相当自我解释。如果您想让它在包括Opera Mini在内的所有移动浏览器中工作,则必须将固定位置更改为绝对位置,并确保文本区域始终位于页面可见部分的中间,以避免每次键入字符时滚动。

基本上,创建一个隐藏的文本区域,将keydown事件添加到窗口对象以聚焦文本区域,获取文本区域的值,清除文本区域,再次聚焦先前聚焦的元素……然后选择性地在先前聚焦的元素中生成键入的字符。

    /*create a hidden textarea*/
    var keyGrabber = document.createElement('textarea');
    keyGrabber.style.border = '0';
    keyGrabber.style.margin = '0';
    keyGrabber.style.padding = '0';
    keyGrabber.style.outline = 'none';
    keyGrabber.style.position = 'fixed';
    keyGrabber.style.top = '0';
    keyGrabber.tabIndex = '-1';
            
    document.body.appendChild(keyGrabber);
    
    /*Avoid confusion for screen readers*/
    keyGrabber.setAttribute('aria-hidden','true');
    
    /*Init the variables here so they are global and easy to access*/
    var oldActiveElement = document.activeElement;
    var oldStart = 0;
    var oldEnd = 0;
    
    /*Catch the keydown event and store the active elements selection start and end in case you still want the character to be typed*/
    window.addEventListener('keydown',function(e){
        oldActiveElement = document.activeElement;
        oldStart = oldActiveElement.selectionStart;
        oldEnd = oldActiveElement.selectionEnd;
        keyGrabber.focus();
        /*If you need to capture keys that don't generate written characters, you'll have to do that here using e.key || e.keyCode */
    });
    
    keyGrabber.addEventListener('input',function(){
        var character = keyGrabber.value;
        if(character == ':'){
            alert('You typed a colon!');
            /*replace alert with whatever code you want to execute when a colon is typed*/
        }
        keyGrabber.value = '';
        oldActiveElement.focus();
        /*This part is optional, in case you want to still have the typed character generate in an input and also fire the event. You would then also replace "window.addEventListener..." with "yourInput.addEventListener..."*/
        var part1 = oldActiveElement.value.slice(0,oldStart);
        var part2 = oldActiveElement.value.slice(oldEnd,oldActiveElement.value.length);
        oldActiveElement.value = part1 + character + part2;
        oldActiveElement.selectionStart = oldStart + 1;
        oldActiveElement.selectionEnd = oldActiveElement.selectionStart;
    });

请不要复制/粘贴此代码并期望它完美运行。我是凭记忆打字的,而不是从工作文件中复制。我记不得将tabIndex设置为-1是否会阻止.focus()的工作。我认为没问题,但请再次确认一下。

0

我认为你应该使用JavaScript获取“:”字符的键码,这样脚本就能在特定环境中知道它是什么。类似的问题已经在stackoverflow上提出。


0

同时也可以查看这个GitHub文件:https://github.com/bpeacock/key-to-charCode/blob/master/jQuery.getChar.js,了解如何使用keyDown事件而不是keyPress事件。

我在移动设备上使用它来扫描带有键盘楔的条形码扫描器,该设备在扫描连字符时返回(keyPress)数据存在错误。效果还不错。但是当我在具有常规键盘的浏览器中测试应用程序时,我注意到连字符在Chrome上有效,但在Firefox上无效。奇怪但却是事实。通过在上述JS文件中添加代码173以及代码189进行修复。

这让我想知道键盘实际上发送了什么。按下连字符键(- _)的keydown代码显然不是由键盘本身发送的,而是由浏览器创建并将keyDown事件发送到我的JavaScript应用程序。



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接