添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

According to MDN, we should most definitely not be using the .keyCode property. It is deprecated:

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

On W3 school, this fact is played down and there is only a side note saying that .keyCode is provided for compatibility only and that the latest version of the DOM Events Specification recommend using the .key property instead.

The problem is that .key is not supported by browsers, so what should we using? Is there something I'm missing?

.key is supported in every major browser developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/… sbolel Jun 18, 2018 at 23:24 This question doesn't seem particularly useful anymore since all modern browsers support event.key . Herohtar Aug 20, 2022 at 4:16 In the light of the "in practice" part of the question, this should be the accepted answer. Eduardo Pignatelli Dec 26, 2020 at 14:33 For non-ASCII composing letters, the key event fires twice. Each are { key: 'Enter', keyCode: 13 }, { key: 'Enter', keyCode: 229 }. How can I avoid second event without keyCode? khcpietro Jul 22, 2021 at 2:14 The list of all possible values of event.key: developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/… Christopher K. Oct 29, 2021 at 10:11 keep in mind that changing from event.keyCode === 13 to event.key === 'Enter' drops support for numpad keys. To support both, check both: event.key === 'Enter' || event.key === 'NumpadEnter' or better yet: ['Enter', 'NumpadEnter'].includes(event.key) Austin Arnett Mar 7, 2022 at 15:22

You have three ways to handle it, as it's written on the link you shared.

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

you should contemplate them, that's the right way if you want cross browser support.

It could be easier if you implement something like this.

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);
                I did read that that but it seemed to be a lot of extra code for no other reason than MDN have said something is deprecated, when it actually works fine in all major browsers. But if that's the correct way then thanks!
– Jason210
                Feb 14, 2016 at 18:14
                Wow look a this. caniuse.com/#search=keyCode (This KeyboardEvent property is supported in effectively all browsers (since IE6+, Firefox 2+, Chrome 1+ etc "talking about .keyCode)
– Miguel Lattuada
                Feb 14, 2016 at 18:25
                That's what is so annoying about all this. All major browsers support keyCode, but try do a check for the .key property, which is the recommended one, and hardly any use it!
– Jason210
                Feb 14, 2016 at 18:32
                Yeah, we're up to late May 2016, and chrome finally implemented the KeyboardEvent.key property. Safari along with every mobile browser has yet to join the "16.5% of all users" party. Also, sadly, Microsoft Edge and Gecko encode quite a few of the events differently for example: the key event for the up arrow is encoded as "Up" instead of "ArrowUp".
– Joshua Dawson
                May 31, 2016 at 5:05
                But event.key is a string, whereas event.keyCode is a number, right? Given that they don't even have the same type, have can they have the same semantics? Or do you mean event.code?
– bluenote10
                Dec 7, 2020 at 14:06

TLDR: I'd suggest that you should use the new event.key and event.code properties instead of the legacy ones. IE and Edge have support for these properties, but don't support the new key names yet. For them, there is a small polyfill which makes them output the standard key/code names:

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

I came to this question searching for the reason of the same MDN warning as OP. After searching some more, the issue with keyCode becomes more clear:

The problem with using keyCode is that non-English keyboards can produce different outputs and even keyboards with different layouts can produce inconsistent results. Plus, there was the case of

If you read the W3C spec: https://www.w3.org/TR/uievents/#interface-keyboardevent

In practice, keyCode and charCode are inconsistent across platforms and even the same implementation on different operating systems or using different localizations.

It goes into some depth describing what was wrong with keyCode: https://www.w3.org/TR/uievents/#legacy-key-attributes

These features were never formally specified and the current browser implementations vary in significant ways. The large amount of legacy content, including script libraries, that relies upon detecting the user agent and acting accordingly means that any attempt to formalize these legacy attributes and events would risk breaking as much content as it would fix or enable. Additionally, these attributes are not suitable for international usage, nor do they address accessibility concerns.

So, after establishing the reason why the legacy keyCode was replaced, let's look at what you need to do today:

  • All modern browsers support the new properties (key and code).
  • IE and Edge support an older version of the spec, which has different names for some keys. You can use a shim for it: https://github.com/shvaikalesh/shim-keyboard-event-key (or roll your own - it's rather small anyways)
  • Edge has fixed this bug in the latest release (probably will be released in Apr 2018) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
  • Refer to the list of event keys you can use: https://www.w3.org/TR/uievents-key/
  • According to the MDN, neither Internet Explorer nor Edge support KeyboardEvent.code. Also, the values for key and code are browser dependent. Both issues making key and code not practical to use in real life applications. – John Slegers Apr 18, 2018 at 19:33 If I want to test the arrow keys, page up/down, home & end, should I use key or code? It's generally a physical key, but can depend on Num Lock and layout too... What's the best practice? – Jake Nov 4, 2018 at 22:54 It being a string also makes it a lot more readable, so it is advisable to use it for all new code. For maintaining legacy, it will depend on how much you depend on it being a number. Just be aware that when you hit a printable key, event.key "a" and "A" are different while event.code will be "keyA" for both. For non printable, you can have event.code being "ShiftLeft" or "ShiftRight" while event.key will be "Shift" for both. – Guilherme Taffarel Bergamin Jan 25, 2021 at 17:41

    In addition that all of keyCode, which, charCode and keyIdentifier are deprecated :
    charCode and keyIdentifier are non-standard features.
    keyIdentifier is removed as of Chrome 54 and Opera 41.0
    keyCode returns 0, on keypress event with normal characters on FF.

    The key property :

     readonly attribute DOMString key
      

    Holds a key attribute value corresponding to the key pressed

    As of the time of this writing, the key property is supported by all major browsers as of : Firefox 52, Chrome 55, Safari 10.1, Opera 46. Except Internet Explorer 11 which has : non-standard key identifiers and incorrect behavior with AltGraph. More info
    If that is important and/or backward compatibility is, then you can use feature detection as in the following code :

    Notice that the keyvalue is different from keyCode or which properties in that : it contains the name of the key not its code. If your program needs characters' codes then you can make use of charCodeAt(). For single printable characters you can use charCodeAt(), if you're dealing with keys whose values contains multiple characters like ArrowUp chances are : you are testing for special keys and take actions accordingly. So try implementing a table of keys' values and their corresponding codes charCodeArr["ArrowUp"]=38, charCodeArr["Enter"]=13,charCodeArr[Escape]=27... and so on, please take a look at Key Values and their corresponding codes

    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  */  
    

    May be you want to consider forward compatibility i.e use the legacy properties while they're available, and only when dropped switch to the new ones :

    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;
    

    See also : the KeyboardEvent.code property docs and some more details in this answer.

    You solution doesn't work in my browser (Windows 10, Chrome 60, Belgian keyboard). First of all, the charCodeArr function does not exist. Also, charCodeAt doesn't work for all values of e.key. For example, for the Enter / Return key, the value of e.key property is "Enter", and executing charCodeArr for that string returns the value 69 (which is the ASCII code for the character E). – John Slegers Aug 24, 2017 at 11:06 @JohnSlegers, yes that was a typo, I meant a user built array. Please, see my updated answer for more details. – user10089632 Aug 24, 2017 at 12:37

    MDN has already provided a solution:

    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);
                    Unfortunately, key is a browser-specific string value like "Enter" or "ArrowUp" and there's no standardized way to convert it to the corresponding code. so you're going to need even more boilerplate code to convert between key & code.
    – John Slegers
                    Aug 24, 2017 at 11:27
    

    Here was proposed to use key value instead of keyCode and if it fails then use keyCode. Though this is not enough, because values in this attributes are not compatible. Thing is new key contains the string for control keys, like: ArrowUp, but keyCode will contain just code which with trivial

    String.fromCharCode(event.keyCode)
    

    will result in a non-printable char. Here the solution for printable chars:

    element.keydown((event) => {
        var symbolPressed;
        //cross browser
        if (event.key !== undefined) {
            symbolPressed = event.key; //Here control characters represented as String like: ArrowUp
            if (symbolPressed.length > 1) return; //filter out control characters
        } else if (event.keyCode !== undefined) {
            symbolPressed = String.fromCharCode(event.keyCode); //Here control chars represented as one char string
        //Update this regex if you need other characters
        if (!symbolPressed.match(/[A-z0-9\s]/)) return;
        console.log(symbolPressed);
    

    And in case of you need non-printable control characters, you have to update conditions and regex accordingly.

     function myKey(event){
      var keycode = event.keyCode;  //key code variant 1, not recomendate
      var keywhic = event.which;    //key code variant 2, nice worked 
      var unicode = event.key;      //string name code, nice worked  
      var chacode = event.charCode; //works onkeypress="myKey(event)"
      var metakey = event.metaKey;  //true false, winKey or macComand
      document.getElementById("demo").innerHTML = keycode+" "+keywhic+" "+unicode+" "+chacode+" "+metakey;
    
    <!DOCTYPE html>
    <body onkeydown="myKey(event)"> <!--onkeypress="myKey(event)"-->
    <h1 id="demo">Keyboard Buttons click me and test the keyboard</h1>
    <script>
     //function myKey(event){
     //paste code
    </script>
    </body>
    </html>
    Please don't post only code as an answer, but also provide an explanation of what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes – Ran Marciano Dec 8, 2020 at 6:34

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.