Implementing keyboard controls or shortcuts in Javascript
By: Mavi Toktamis-Paker
Tags: Programming, Web Development, JavaScript, Coding, Web Design

If you’re trying to make a game or interactive webapp in Javascript, you’re likely to find yourself wanting to implement keyboard controls.

Event Listeners

To do this, we’re going to use keyboard event listeners. These are keydown (detects when a key is pressed) and keyup (detects when a key is released).

document.addEventListener('keydown', sayHi);



function sayHi(e) {

console.log("Hello!");

}

The above code will print “Hello!” whenever any key is pressed.

Specific Keys

We can access the specific key pressed using the event’s built-in methods. .key will return the key that was pressed:

document.addEventListener('keydown', recordKey);



function recordKey(e) {

console.log("You pressed ${e.key}");

}

Some other useful methods this event has access to:

e.ctrlKey : detects if ctrl is also pressed (boolean)

e.shiftKey : detects if shift is also pressed (boolean)

e.metaKey : detects if the window key / command key is also pressed

(boolean)

e.repeat : detects if the key is being held down (boolean)

e.code : outputs a code unique to each key

.key reports the value given by the key (w, 7, shift, tab) whereas key.code cares about the physical location of the key. So one use of .code might be if you want to implement WASD controls but accommodate those using non-English or non-QWERTY keyboards:

on the other hand, they’re not using Dvorak because they want to be accomodated

Now that we have access to the key being pressed, we can make different keypresses do different things:

switch (e.key) {

case "w":

someUpFunction()

break

case "s":

someDownFunction()

break

case "Up":

case "ArrowUp":

someOtherUpFunction()

break

case "Down":

case "ArrowDown":

someOtherDownFunction()

break

case " ":

case "Spacebar":

someOtherFunction()

break

default:

return

}

You’ll notice that in the case of the spacebar and the arrows, there are two seemingly redundant cases. This is because Internet Explorer (and Edge) use a different naming scheme for the keys, so we cover both naming schemes this way. This might be another reason to use .code.

Simultaneous Inputs

One limitation of Javascript in the browser is that it can only detect one keyboard input at a time; if I’m moving my spaceship with the arrows and want to shoot with the spacebar, the movement will stop when I fire, and not start back up again until I hit an arrow key again. If you want to allow a combination of inputs (other than using shift, control and windows/command), you need to track the lifetime of each keypress by adding keyup to the equation.

The following is my real code from a recent project that takes simultaneous movement input from two users (“p1” and “p2) on one keyboard.

function controlKeydown(event){

if (event.defaultPrevented) {

return

}

switch (event.key) {

case "w":

p1.direction = 1

break

case "s":

p1.direction = -1

break

case "Up":

case "ArrowUp":

p2.direction = 1

break

case "Down":

case "ArrowDown":

p2.direction = -1

break

case " ":

case "Spacebar":

app.paused = !app.paused

break

default:

return

}

event.preventDefault();

}

function controlKeyup(event){

if (event.defaultPrevented) {

return

}

switch (event.key) {

case "w":

case "s":

p1.direction = 0

break

case "Up":

case "ArrowUp":

case "Down":

case "ArrowDown":

p2.direction = 0

break

default:

return

}

event.preventDefault()

}

window.addEventListener("keydown", function (event) {

controlKeydown(event)

}, true)

window.addEventListener("keyup", function (event) {

controlKeyup(event)

}, true)

The actual effects of their inputs are handled elsewhere; the inputs just create a state (“moving up”, “moving down”, “not moving”). This way multiple inputs don’t interrupt one another.

Please share your comments below, or reach out to me privately.