Detecting arrow key presses in JavaScript
Solution 1
Arrow keys are only triggered by onkeydown
, not onkeypress
.
The keycodes are:
- left = 37
- up = 38
- right = 39
- down = 40
Solution 2
On key up and down call function. There are different codes for each key.
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
}
else if (e.keyCode == '40') {
// down arrow
}
else if (e.keyCode == '37') {
// left arrow
}
else if (e.keyCode == '39') {
// right arrow
}
}
Solution 3
event.key === "ArrowRight"...
More recent and much cleaner: use event.key
. No more arbitrary number codes! If you are transpiling or know your users are all on modern browsers, use this!
node.addEventListener('keydown', function(event) {
const key = event.key; // "ArrowRight", "ArrowLeft", "ArrowUp", or "ArrowDown"
});
Verbose Handling:
switch (event.key) {
case "ArrowLeft":
// Left pressed
break;
case "ArrowRight":
// Right pressed
break;
case "ArrowUp":
// Up pressed
break;
case "ArrowDown":
// Down pressed
break;
}
Modern Switch Handling:
const callback = {
"ArrowLeft" : leftHandler,
"ArrowRight" : rightHandler,
"ArrowUp" : upHandler,
"ArrowDown" : downHandler,
}[event.key]
callback?.()
NOTE: The old properties (
.keyCode
and.which
) are Deprecated.
"w", "a", "s", "d"
for direction, use event.code
To support users who are using non-qwerty/English keyboard layouts, you should instead use event.code
. This will preserve physical key location, even if resulting character changes.
event.key
would be , on Dvorak and z on Azerty, making your game unplayable.
const {code} = event
if (code === "KeyW") // KeyA, KeyS, KeyD
Optimally, you also allow key remapping, which benefits the player regardless of their situation.
P.S. event.code
is the same for arrows
Solution 4
Possibly the tersest formulation:
document.onkeydown = function(e) {
switch (e.keyCode) {
case 37:
alert('left');
break;
case 38:
alert('up');
break;
case 39:
alert('right');
break;
case 40:
alert('down');
break;
}
};
Demo (thanks to user Angus Grant): http://jsfiddle.net/angusgrant/E3tE6/
This should work cross-browser. Leave a comment if there is a browser where it does not work.
There are other ways to get the key code (e.which, e.charCode, and window.event instead of e), but they should not be necessary. You can try most of them out at http://www.asquare.net/javascript/tests/KeyCode.html. Note that event.keycode does not work with onkeypress in Firefox, but it does work with onkeydown.
Solution 5
Use keydown
, not keypress
for non-printable keys such as arrow keys:
function checkKey(e) {
e = e || window.event;
alert(e.keyCode);
}
document.onkeydown = checkKey;
The best JavaScript key event reference I've found (beating the pants off quirksmode, for example) is here: http://unixpapa.com/js/key.html
mihsathe
Updated on July 19, 2022Comments
-
mihsathe almost 2 years
How do I detect when one of the arrow keys are pressed? I used this to find out:
function checkKey(e) { var event = window.event ? window.event : e; console.log(event.keyCode) }
Though it worked for every other key, it didn't for arrow keys (maybe because the browser is supposed to scroll on these keys by default).
-
Tim Down about 13 yearsSome browsers do trigger
keypress
events for arrow keys, but you're right thatkeydown
always works for arrow keys. -
eshellborn almost 11 yearsWhat does the second line do?
-
eshellborn almost 11 years'e = e || window.event;'
-
ketan almost 11 yearsIt will get the event
-
xorcus over 10 yearsIf you press %, you also get keyCode 37
-
None over 10 years@xorcus -- No, you get
53
with akeydown
event. You get37
withkeypress
, which is a different thing -
Michael Calvin over 10 yearsTo clarify, 'e || window.event' means that if 'e' is a defined value, it will be the result of the '||' expression. If 'e' is not defined, 'window.event' will be the result of the '||' expression. So it's basically shorthand for:
e = e ? e : window.event;
Or:if (typeof(e) === "undefined") { e = window.event; }
-
Mark Rhodes over 10 yearsIt's to make it work on old versions of IE (pre IE9) where the event was not passed into the handler function.
-
alexrogers about 9 yearsJust to note keyCode is a number and === should ideally be used
-
ketan about 9 years@alexrogins have you checked? jsfiddle.net/AjKjU/86 and jsfiddle.net/AjKjU/87.
-
alexrogers about 9 yearsSorry, I don't understand your what your fiddle is showing. Have I checked what? I have edited your answer, please can you approve it as it is correct? Should be jsfiddle.net/AjKjU/88
-
Joel Peltonen about 9 years@ketan the point was that keyCode is a number and should be checked like
keyCode === 32
, notkeyCode == '32'
orkeyCode === '32'
. -
animaacija almost 9 yearsshort is good:
if ([37,38,39,40].indexOf(e.keyCode)!=-1){ console.log('arrow pressed') }
-
pmrotule almost 9 years@1nfiniti onkeyup won't consider the repeated call of the keydown event when you hold the arrow down.
-
Juribiyan over 8 years
keypress
won't work with arrow keys. You have to use$(document).on('keydown', function() {...})
instead -
Grief over 8 yearsDoesn't it worth to put
arrs
outside of the function? No need to recreate it every call -
papo over 7 yearsI am getting $0 is not defined
var targetElement = typeof $0 !== 'undefined' ? $0 : document.body;
or just:var targetElement = document.body;
is ok -
MrCroft over 7 years:( arrow key presses not being visible on "keypress" puts serious limitations. You practically can't do things like "if (evt.which === 40) { itemIndex +=1; scrollToFunction(...);" on "keypress" - which should keep scrolling as long as you don't take your finger off the arrow key. If we are forced to do that on keydown or keyup, then it will only triger the event ONCE, and we'd have to keep stroking the keydown arrow to scroll to a newly marked element in a list, instead of just holding down the arrow key.
-
None over 7 years@MrCroft - or also listen to
onkeyup
and stop the event there. Realistically you shouldn't be modifying UI behavior with Javascript, however. -
MrCroft over 7 years@MarkKahn yeah, it's just that you have to listen to 2 events to be able to accomplish functionality that should have been accessible through 1 event alone, in my opinion. It is possible though, yeah... Nothing's really impossible, there are always ways to do it. I just think it should have been accessible altogether through the keypress event alone. Unfortunately, it's not.
-
v010dya almost 7 yearsThank you for using
key
and notkeyCode
, that was deprecated. -
Simon almost 6 yearsNote from MDN: Internet Explorer, Edge (16 and earlier), and Firefox (36 and earlier) use "Left", "Right", "Up", and "Down" instead of "ArrowLeft", "ArrowRight", "ArrowUp", and "ArrowDown".
-
ecoe almost 5 yearsuseful tool for confirming keycodes: blog.pothoven.net/2008/05/…
-
ashleedawg over 4 years
-
The Fool over 4 yearskeyup is most of the time what you want
-
CTS_AE about 4 yearsIf you care about quick response then key up is "slow" for example if you made a game, you wouldn't want to act upon when the key is let go, you want to act as soon as the key registers, so you would want to do it on key down, but make sure not to repeat the key being held down until the key triggers it's associated key up and then you can reset it ready for another key down.
-
relief.melone over 3 yearsas event.keyCode is deprecated this should be the accepted answer
-
Dmitry Koroliov about 3 yearsNow
keypress
has been marked as deprecated -
Boogie about 2 yearskeyCode is deprecated. Please see developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode Use key instead ie e.key === 'ArrowDown'
-
Iglesias Leonardo about 2 yearsI just loved the modern switch handling