How do I detect keypresses in Javascript?
Asked Answered
O

6

110

After looking around on the internet, I've seen a lot of suggestions (use window.onkeypress, use jQuery, etc.) but for almost every option there's a counterargument. How can I detect a keypress in Javascript?

Osteogenesis answered 18/4, 2013 at 17:24 Comment(4)
I'd suggest just listening for the keypress event, or possibly one of it's counterparts (keydown or keyup)Assertive
start here - api.jquery.com/keypressCernuous
jQuery is JavaScript; the only difference is that jQuery is a library that abstracts away cross-browser differences, to make it easier (but not necessarily more efficient) to write cross-browser code.Noiseless
I suggest this: github.com/madrobby/keymasterAustro
U
131

With plain Javascript, the simplest is:

document.onkeypress = function (e) {
    e = e || window.event;
    // use e.keyCode
};

But with this, you can only bind one handler for the event.

In addition, you could use the following to be able to potentially bind multiple handlers to the same event:

addEvent(document, "keypress", function (e) {
    e = e || window.event;
    // use e.keyCode
});

function addEvent(element, eventName, callback) {
    if (element.addEventListener) {
        element.addEventListener(eventName, callback, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + eventName, callback);
    } else {
        element["on" + eventName] = callback;
    }
}

In either case, keyCode isn't consistent across browsers, so there's more to check for and figure out. Notice the e = e || window.event - that's a normal problem with Internet Explorer, putting the event in window.event instead of passing it to the callback.

References:

With jQuery:

$(document).on("keypress", function (e) {
    // use e.which
});

Reference:

Other than jQuery being a "large" library, jQuery really helps with inconsistencies between browsers, especially with window events...and that can't be denied. Hopefully it's obvious that the jQuery code I provided for your example is much more elegant and shorter, yet accomplishes what you want in a consistent way. You should be able to trust that e (the event) and e.which (the key code, for knowing which key was pressed) are accurate. In plain Javascript, it's a little harder to know unless you do everything that the jQuery library internally does.

Note there is a keydown event, that is different than keypress. You can learn more about them here: onKeyPress Vs. onKeyUp and onKeyDown

As for suggesting what to use, I would definitely suggest using jQuery if you're up for learning the framework. At the same time, I would say that you should learn Javascript's syntax, methods, features, and how to interact with the DOM. Once you understand how it works and what's happening, you should be more comfortable working with jQuery. To me, jQuery makes things more consistent and is more concise. In the end, it's Javascript, and wraps the language.

Another example of jQuery being very useful is with AJAX. Browsers are inconsistent with how AJAX requests are handled, so jQuery abstracts that so you don't have to worry.

Here's something that might help decide:

Urushiol answered 18/4, 2013 at 17:26 Comment(9)
If you're going for cross-browser compatibility, you might need to touch on attachEvent() as well (and not my down-vote, by the way).Noiseless
@DavidThomas Yes, I'm not there yet :)Urushiol
@DavidThomas I'm not worried about downvotes, I'd rather get the right point across. Is the answer any better? I'd be happy to add/change anythingUrushiol
Looks solid, thanks for the explanation! I think I will go with jQuery, I've been looking into it some more and I guess it'll benefit me anyway if I learn to work with it.Osteogenesis
I think it's worth noting that keypress didn't work in my case, so i had to use keydown.Wylde
@WilliamJones That's because it's deprecated! I just checked the docs and was presented with that surprise: developer.mozilla.org/en-US/docs/Web/API/Document/….Overnight
About document.onkeypress = function (e): OK, but why can't I "trap" the [Esc] key?Kaiserdom
It would be better supported with jQuery: $(document).keydown(function(e){ /*e.which*/ });Plains
Now you should use e.code instead of e.keyCode because the latter is now deprecated.Guenon
L
56

NOTE: JS's keypress is deprecated:

https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event

The jQuery solutions in this answer may still be relevant.


KEYPRESS (enter key)
Click inside the snippet and press Enter key.

Vanilla

document.addEventListener("keypress", function(event) {
  if (event.keyCode == 13) {
    alert('hi.');
  }
});

Vanilla shorthand (Arrow Function, ES6)

this.addEventListener('keypress', event => {
  if (event.keyCode == 13) {
    alert('hi.')
  }
})

jQuery

$(this).on('keypress', function(event) {
  if (event.keyCode == 13) {
    alert('hi.')
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

jQuery classic

$(this).keypress(function(event) {
  if (event.keyCode == 13) {
    alert('hi.')
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

jQuery shorthand (Arrow Function, ES6)

$(this).keypress((e) => {
  if (e.keyCode == 13)
    alert('hi.')
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Even shorter (ES6, ECMAScript 2021)

$(this).keypress(e=>
  e.which==13&&alert`☺`
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Due to some requests, here is an explanation:

I rewrote this answer as things have become deprecated over time so I updated it. Just for info, it is not about "keydown", it's about "keypress". So some non-character keys like "Esc" aren't supposed to work like that but I'll explain.

I used this to focus on the window scope inside the results when document is ready and for the sake of brevity but it's not necessary.

Deprecated:
The .which and .keyCode methods are actually considered deprecated so I would recommend .code but I personally still use keyCode as the performance is much faster and only that counts for me. The jQuery classic version .keypress() is not officially deprecated as some people say but they are no more preferred like .on('keypress') as it has a lot more functionality(live state, multiple handlers, etc.). The 'keypress' event in the Vanilla version is also deprecated. People should prefer beforeinput or keydown, keyup today.

Performance:
The faster the better. This is why I prefer .keyCode even if it's considered deprecated(in most cases). It's all up to you though (Commited 2020).

Performance Test

Liana answered 10/9, 2016 at 23:20 Comment(7)
About document.addEventListener("keypress", function(event): OK, but why can't I "trap" the [Esc] key?Kaiserdom
Because the [Esc] key should rather be used with "keydown". Reason why I said it's deprecated ... read carefully. Best is to use keypress for ASCII characters (D,L,%,1,Ä etc..) and keydown for non-character keys (arrow keys, Esc, Alt, Ctrl, Page up/down etc). Things are subject to change as the time goes by...Liana
Thank you, @ Thielicious. I think I already did. But I don't see my last reply to you either! At least not here, And I certainly didn't delete it! It seems that either someone else does that or I I can't see them (as strangely as this may sound) ! (Besides, if I delete my messages, hoe comes that you answer to them?. Whatever, thanks again! (And I hope this gets across!)Kaiserdom
@Kalnode Not sure why you edited my answer with info about keypress being deprecated when I already had it explained in the text below the code years ago.Liana
Why? The explanation wasn't clear enough, and at the bottom of the long post. Instead I put a convenient note at the top so people set their mind right before spending time on the answer.Carree
You could have asked me to do it and I'd have composed/fixed the answer by myself, very simple. And I'll plan to rewrite the entire text and may put it at the top by myself anyway. But it's still not gonna matter much. Imagine someone editing all your answers the way you don't like.Liana
Finally someone else who uses KeyboardEvent.keyCode. For some reason the modern standard feels very finnicky across keyboards so I don't like to use them.Floorage
O
42

Use event.key and modern JS!

No number codes anymore. You can use "Enter", "ArrowLeft", "r", or any key name directly, making your code far more readable.

NOTE: The old alternatives (.keyCode and .which) are Deprecated.

document.addEventListener("keypress", function onEvent(event) {
    if (event.key === "ArrowLeft") {
        // Move Left
    }
    else if (event.key === "Enter") {
        // Open Menu...
    }
});

Mozilla Docs

Supported Browsers

Outer answered 18/2, 2018 at 19:17 Comment(3)
Arrow keys are actually, "ArrowUp", "ArrowDown", "ArrowRight", "ArrowLeft"Consistent
Why can't I "trap" these arrow keys or the [Esc] key?Kaiserdom
To 'capture' the press: https://mcmap.net/q/86971/-prevent-form-submission-on-enter-key-pressOuter
G
7

Don't over complicate.

  document.addEventListener('keydown', logKey);
    function logKey(e) {
      if (`${e.code}` == "ArrowRight") {
        //code here
      }
          if (`${e.code}` == "ArrowLeft") {
        //code here
      }
          if (`${e.code}` == "ArrowDown") {
        //code here
      }
          if (`${e.code}` == "ArrowUp") {
        //code here
      }
    }
Grogram answered 25/4, 2020 at 19:15 Comment(3)
Congrats! This answer should get all the credits! Besides being the only one that can "capture" arrow keys and the [Esc] key, where all earlier code failed (at least for me), if actually captures ALL the keyboard keys, even the status keys!!Kaiserdom
One more thing: How do I remove this event listener? I tried with document.removeEventListener(), but it doesn't work: the listener continues to be active, i.e. the keyboard continues to be monitored!Kaiserdom
While this answer may not be what the OP is looking for as it's about keypress only (even though keypress in general becomes deprecated and new events like keydown/keyup/beforeinput come in handy and the question is 8 years old), yet I still might add that keydown keeps firing the event while you hold down the key which is not always great. So instead, add event.repeat = false in order to prevent that.Liana
W
6

There are a few ways to handle that; Vanilla JavaScript can do it quite nicely:

function code(e) {
    e = e || window.event;
    return(e.keyCode || e.which);
}
window.onload = function(){
    document.onkeypress = function(e){
        var key = code(e);
        // do something with key
    };
};

Or a more structured way of handling it:

(function(d){
    var modern = (d.addEventListener), event = function(obj, evt, fn){
        if(modern) {
            obj.addEventListener(evt, fn, false);
        } else {
            obj.attachEvent("on" + evt, fn);
        }
    }, code = function(e){
        e = e || window.event;
        return(e.keyCode || e.which);
    }, init = function(){
        event(d, "keypress", function(e){
            var key = code(e);
            // do stuff with key here
        });
    };
    if(modern) {
        d.addEventListener("DOMContentLoaded", init, false);
    } else {
        d.attachEvent("onreadystatechange", function(){
            if(d.readyState === "complete") {
                init();
            }
        });
    }
})(document);
Weightless answered 18/4, 2013 at 17:38 Comment(1)
OK, but why can't I "trap" the [Esc] key?Kaiserdom
P
0

Catching the event on keydown is very stable,I have used the code before no several occasion with positive result.

This link will show you keycodes, as you hit the key. Find keycode

$("#your_input_id").keydown(function(event) {
if(event.keyCode == 189) {
    alert('Dexter');
}
});
Pyrostat answered 25/12, 2022 at 0:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.