Key to unlock 'Keyboard Events'
All about Javascript Keyboard and Input events you should know.
You should be good with keyboards if you want to deal with computers. Don't believe me? Look at our movies. Have you ever seen a hacker or a rogue CIA agent, or even a SKYNET cyborg using a mouse or a touchpad? Whether it is about destroying a world or saving it, you must do it through the keyboard. I want you to remember this.
Enough with the fun part. It is really very important to handle keyboard interactions on our web pages for several reasons. Here are a few.
- To accept inputs from users. (Duh!)
- To make our applications ACCESSIBLE by enabling users to navigate through the web pages with the help of just a keyboard. More on the topic
- To handle keyboard shortcuts. More on the topic
Thus it is important to get familiar with different keyboards and input events.
Read all articles from this series
Here is a codepen link I have created. I strongly encourage you to play with the code and observe the changes.
Key concepts and terminology
Before we proceed with the events, there are a few concepts and terms we should see. With help of these, you can get more clarity about the event object shown in the codepen.
Event order
Keyboard and Input events take place in a certain order called an EVENT ORDER. This order is different for different situations.
When the user presses and releases a key, the following events occur in a given order.
- keydown
- beforeinput
- input
- keyup
When the user presses a key for a sustained period, the following events may repeat (only if a key represents a character. For the rest of the keys, this event is fired only once.).
- keydown
- beforeinput
- input
Key mapping
This is the process by which a value is assigned to a key. The result of the key mapping is a combination of several factors such as keyboard layout, operating system, and modifier keys state. e.g. Pressing '2' and 'Shift + 2' have different results.
Modifier keys
There are few properties on a KeyboardEvent object which will tell us if a user has pressed any of the following keys at the time of an event.
- Shift Key (shiftKey)
- Control key (ctrlKey)
- Alt key (altKey)
- Command key for Mac (metaKey)
KeyboardEvent.location (read-only)
This attribute tells us the area of the keyboard from where a key was pressed. e.g. Usually there are 2 shift keys. 1 on the left and 1 on the right. With the location attribute we can tell which one was pressed.
It holds a number as the value. These numbers are mapped to different locations on the keyboard.
- 0: DOM_KEY_LOCATION_STANDARD
- 1: DOM_KEY_LOCATION_LEFT
- 2: DOM_KEY_LOCATION_RIGHT
- 3: DOM_KEY_LOCATION_NUMPAD
KeyboardEvent.code (read-only)
This attribute represents a physical key on the keyboard. Each key has a code value that is the same irrespective of keyboard layout. (yes. there are different keyboard layouts than QWERTY).
e.g. QWERTY layout has key Q in the same place where Dvorak layout has '
This attribute returns the value 'keyQ' for both layouts.
It is different than key in the way that 2 keys can have the same key value (both numbers from the main area and numbers from the Numpad have the same key values) but they can never have the same code value.
KeyboardEvent.key (read-only)
This attribute holds the printable representation of a pressed key. e.g. Enter key is 'Enter' and the down arrow is 'ArrowDown'. We can use this attribute in our logic to capture a keypress and branch accordingly. This is recommended over deprecated keyCode attribute.
We can change the keyboard layout on most operating systems. If you can, set it to US English (Dvorak) on your machine temporarily and try typing your name in the input fields in the codepen link. You would notice in the browser console that the key attribute shows expected results but the code attribute shows fixed values irrespective of the layout chosen.
List of pre-defined key values
KeyboardEvent.repeat (read-only)
This attribute holds a boolean value representing whether a key has been pressed in a sustained manner.
InputEvent.data
This attribute contains the inserted characters. It might be empty or null for some editing actions like delete and cut.
InputEvent.inputType
This attribute contains the type of change made to the input field.
e.g. insertText for adding characters, deleteByCut for performing a cut operation on input content, etc.
Enough with the details. Let's dive into the events.
Classification
There are 2 types of events.
- Keyboard events
- Input events
Keyboard events
keydown
When does it occur?
When any key on the keyboard is pressed (but not released yet), this event is fired. It is fired after a key mapping process so that a key has a value.
In the case of the sustained press, if a key has a character representation then this event is fired at a predefined(depends on the browser) rate. Otherwise, it is fired only once at the beginning.
Event order
None.
Counterpoint
keyup
keyup
When does it occur?
When any key on the keyboard is released this event is fired. It should be fired after the key mapping process. Also, it should be fired after any keydown, beforeinput, and input events in that order.
Event order
keydown -> beforeinput -> input -> keyup
Counterpoint
keydown
Input events
beforeinput
When does it occur?
This event occurs when the value of the input (input, textarea) is about to change.
This event is usually preferred when we want to restrict a particular value from reaching the DOM update. e.g. an input field that does not accept vowels. Calling preventDefault() from the event handler prevents any default action such as printing a character in the input field.
Event order
keydown -> beforeinput
Counterpoint
input
input
When does it occur?
This event occurs when the value of the input (input, textarea) has been changed.
This event fires every time a value is changed.
Event order
keydown -> beforeinput -> input
Counterpoint
beforeinput
This concludes keyboard and input events. We will revisit them when we will see all form elements in detail. We have plenty to chew till then.
References
Finally...
With this, we have covered most of the basic input/output DOM event handling. Kindly refer to this series, if you haven't been following.
It is now time to move onto the more advanced events such as Form events or Drag'N'Drop events. I will be covering a variety of uncommon events in upcoming articles.
Stay tuned and cheers...