Handling Keyboard Events in JavaScript
Website developers expect readers to interact with their websites in some way. A visitor can either scroll up and down a page, write something inside an input field, click on a link to visit another page, or press a combination of keys to trigger a particular behavior. As a developer, you should be able to capture all these events and provide the desired functionality to users.
In this tutorial, our focus will be on handling keyboard events in JavaScript. We will learn about different types of keyboard events, handling special key events, and getting information about the keys that were pressed or released.
Types of Keyboard Events
There are three types of keyboard events. These are called keydown
, keypress
, and keyup
.
The keydown
event fires whenever a key is pressed. It is fired for all keys. Whether they produce a character value or not is irrelevant. For example, pressing either the A or Alt key on the keyboard will fire the keydown
event.
The keypress
event is deprecated. It only fires when a key that produces a character value is pressed. For example, pressing the A key will fire this event, but pressing the Alt key won't. You should consider using the keydown
event in its place.
The keyup
event fires when a key that the user was pressing is released.
Let's say a user keeps any key on the keyboard pressed continuously. In that case, the keydown
event will be fired repeatedly. The keyup
event will be fired once the user releases the key.
Listening to Keyboard Events
At this point, I would like to mention something fairly obvious. A keyboard is an input device, and it is used to get some input from users. We act based on that input. However, there are other ways for users to send input.
If you want to keep track of any input fields to be filled by users in a form, it makes more sense to use other events such as change
on the said input.
Also, keyboard events are only generated for elements that can receive focus. This includes the <input>
element, <textarea>
element, <summary>
element, and other elements with the contentEditable
or tabindex
attribute.
For example, you won't be able to listen to a keyboard event on paragraph elements unless you set the tabindex
or contentEditable
attribute. However, it will eventually bubble up the DOM tree, so you can still attach a keydown
or keyup
event listener to the document.
Here is an example:
1 |
document.addEventListener("keydown", keyIsDown); |
2 |
|
3 |
function keyIsDown(event) { |
4 |
// Do whatever you want!
|
5 |
}
|
You could also provide your callback as an arrow function:
1 |
document.addEventListener("keydown", (event) => { |
2 |
// Do whatever you want!
|
3 |
});
|
Getting Information From Keyboard Events
In the basic code snippet from the previous section, we defined a callback function. This function accepts an event
object as its parameter. This event
object contains all the information related to the keydown
or keyup
event that you might need to access.
Here are some useful properties that you should know about:
-
key
: This property returns a string that represents the character value of the pressed key. -
code
: This property returns a string that represents the code of the physical key that was pressed. -
repeat
: This property returns a booleantrue
if a key is being held down for a long time, resulting in multiple fires of thekeydown
event. -
altKey
: This property returns a booleantrue
if the user was pressing the Alt key (on Windows) or the Option key (on macOS) when thekeydown
event fired. -
ctrlKey
: This property returns a booleantrue
if the user was pressing the Control key when thekeydown
event fired. -
metaKey
: This property returns a booleantrue
if the user was pressing the Meta key when thekeydown
event fired. -
shiftKey
: This property returns a booleantrue
if the user was pressing the Shift key when thekeydown
event fired.
You will notice that I have included the "when the keydown
event was fired" part in all of the last four property descriptions. What this means is that the value of these properties will be true
for keydown
events for keys such as A or 3 if they are pressed while any of the aforementioned keys were in the pressed state as well.
Try pressing either a single key or a combination of keys after focusing on the following CodePen demo to see the value of different properties change.
If you press the 3 key at the top of your keyboard without the Shift key, the value of the key
property becomes 3 and the value of the code
property becomes Digit3. However, with Shift pressed, the value of the key
property becomes # while the code
property is still Digit3.
You can try the same thing with other key combinations, and you will notice that the value of the key
property changes based on the keys you pressed. However, the value of the code
property stays the same.
Some keys on a keyboard are usually repeated. For example, there are two Shift keys. Pressing the left one will set the value of code
to ShiftLeft
. Pressing the right one will set the value of code
to ShiftRight
. Similarly, there are two sets of numeric keys. The ones above the letters will give you the code as Digit<Number>
, while those on the number pad will give you the code as Numpad<Number>
.
This means that if your code depends on detecting a particular key, it is important to make sure that you are using the code
property to check which key was pressed.
One more important thing that I would like to mention is that not everyone uses QWERTY keyboards, and their keyboard might not even be in English. Using the key
property to check which key was pressed is going to be error-prone in this case.
Reacting to Keyboard Events
Now that we know how to listen to keyboard events and extract information from them, we can write some code that will react to the keydown
and keyup
events of some specific keys. Consider the following code snippet:
1 |
const circle = document.querySelector(".circle"); |
2 |
|
3 |
document.addEventListener("keydown", (event) => { |
4 |
|
5 |
if (event.code == "KeyR" && event.repeat != true) { |
6 |
let rVal = Math.floor(200 + Math.random() * 200); |
7 |
circle.setAttribute("style", `width: ${rVal}px; height: ${rVal}px;`); |
8 |
}
|
9 |
|
10 |
if (event.key == "B" && event.shiftKey == true) { |
11 |
let rVal = Math.floor(10 + Math.random() * 40); |
12 |
circle.setAttribute("style", `border: ${rVal}px solid orangered;`); |
13 |
}
|
14 |
|
15 |
if (event.code == "ArrowUp" && event.repeat != true) { |
16 |
circle.classList.add("animate__animated", "animate__bounce"); |
17 |
}
|
18 |
});
|
19 |
|
20 |
document.addEventListener("keyup", (event) => { |
21 |
if (event.code == "ArrowUp") { |
22 |
setTimeout(() => { |
23 |
circle.classList.remove("animate__animated", "animate__bounce"); |
24 |
}, 4000); |
25 |
}
|
26 |
});
|
We have created a listener for the keydown
event and another for the keyup
event. Both of these events are attached to the document
.
Inside keydown
, we check for three different keys. I have used the event.code
property for the R key to show you that you can press the R key either alone or in combination with any modifier keys, and it will still change the radius of the circle to a random value. On the other hand, we use the event.key
property to check if its value is B. The code inside this block will only execute if you press Shift and B together because that's the combination which causes the event.key
property to be a capital "B".
Inside keyup
, we check for the keyup
event on the ArrowUp
key. Once the key has been lifted, we remove the previously attached classes after a delay of four seconds.
The following CodePen demo shows all this in action:
You should try adding your own logic to the above code so that the circle moves around when users press the keys A, S, W, and D.
Final Thoughts
In this tutorial, we learned the fundamentals of keyboard events in JavaScript. Pressing and releasing keys on a keyboard fires the keydown
and keyup
events respectively. The event
object associated with these events contains all the information necessary for you to determine which key was pressed and take the appropriate action.
Keep in mind that the keyboard is only one of the many possible input devices. Therefore, using keyboards to detect any input might not always work out as expected. You should consider using input-related events in that case.