Sitemap
Huzaifa

Huzaifa

I am a Frontend Developer working in React js

JavaScript Keyboard event codes

Mini-Project for Beginners

9 min readJan 12, 2021

--

We are going to build a small JavaScript project which will listen to your keyboard keys and will give the code or key associated to it.
So Let’s begin!!!

Press enter or click to view image in full size
Photo by Pankaj Patel on Unsplash

Pre-requisites:

  • Basic Understanding of Html/CSS
  • JavaScript Basics
  • A computer with working keyboard

Topics you will learn…

  • How to manipulate the DOM elements
  • DOM/JavaScript Events to interact with keyboard
  • HTML data attribute
  • Event delegation/Event Bubbling
  • CSS Variables
Press enter or click to view image in full size
Project Photo

A little tip: Instead of coding along, try to understand the concept first and then write by yourself. It will help you to learn fast and effectively.

Here is the Project Demo and Source Code. I will not go into the detail of HTML and CSS code, so you can clone or fork the GitHub repository to start.

HTML Part — 1

In the first div element which have a class name events, which is enclosing the the four main blocks of events which are useful while interacting with the website through keyboard (event.keyCode, event.key, event.code and event.which).

<div class="event">
<div class="e-style event-key">
<p class="event-info">event.key</p>
<p class="event-value">-</p>
</div>
<div class="e-style event-keyCode">
<p class="event-info">event.keyCode</p>
<p id="code" class="event-value">-</p>
</div>
<div class="e-style event-code">
<p class="event-info">event.code</p>
<p class="event-value">-</p>
</div>
<div class="e-style event-which">
<p class="event-info">event.which</p>
<p class="event-value">-</p>
</div>
</div>

Now we will create the second div with the class of special-keys which will include the information of Shift, Ctrl and Alt as if these keys are pressed or not.

<div class="special-keys">
<div class="key key-shift">
<p class="key-info">Shift</p>
<p class="key-status">-</p>
</div>
<div class="key key-ctrl">
<p class="key-info">Ctrl</p>
<p class="key-status">-</p>
</div>
<div class="key key-alt">
<p class="key-info">Alt</p>
<p class="key-status">-</p>
</div>
</div>

CSS Part

We have completed first part of our Html and now will design that part. For this project layout, I have used the CSS flexbox so if any of you do not know about flexbox or do not know how to use it, I will walk you through that.

First of all we will assign variables to the colors which we will use through out this project. Variables have one of the advantage is that if during the project we decide to change the color pattern, we would not have to go through all lines of code and change the color, instead we will change the color in variable and it will change the color in all files where it is applied.

:root{
--color-primary: #1F2833;
--color-secondary: #515466;
--text-primary: #66FCF1;
--text-secondary: #45A29E;
--text-tertiary: #C5C6C7;
--shadow: 10px 15px 27px -10px rgba(0,0,0, 0.11);
--shadow-2: 10px 7px 20px -10px rgba(0,0,0, 0.11);
}

— We create our variables in the :root because we can use our variables in all the elements. They are like the global variable of CSS.

Now we will start to design our page. We will give background-color to our body.

body{
box-sizing: border-box;
font-family: 'Quicksand', sans-serif;
font-size: 1.4rem;
font-weight: 600;
letter-spacing: 1px;
background-color: var(--color-primary);
color: var(--text-primary);
}

After that we will design our event blocks through event class and e-style class.

.event{
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
margin-top: 1.5rem;
}
.e-style{
margin: 1rem;
padding: 1rem;
height: 10rem;
width: 20rem;
background-color: var(--color-secondary);
border-radius: .7rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
box-shadow: var(--shadow), inset var(--shadow);
transition: all 0.3s ease-in-out;
cursor: pointer;
}

Now I will walk you through the CSS flexbox so you can get idea what is happening in this code.
We have given the flex property to display to use the flex features to layout our design. The flex-direction property will decide that in what direction the content should go. By giving it the direction row, now all the content in this div will follow the row direction. While in the .e-style, flex-direction is column, which you can see the content inside the block is following vertical direction.

Press enter or click to view image in full size
flex direction of flexbox
Blocks are in horizontal direction while the content in it has vertical

The align-items property will align the content on the y-axis, if the flex-direction is row and vice versa. We are using the center to center the content on y-axis depending upon the height of .event div. The justify-content will align the content on the x-axis, if the direction is row and vice versa. And the flex-wrap is wrapping the elements in .event, it means that if the screen width is less than the width of whole element, it will automatically manage the inner elements to make the page responsive. Just play around these properties and you will get to know about them.

JavaScript Part — 1

We are done with the CSS part, all the code revolves around these properties which are discussed above, now we will move toward the JavaScript part.

Get Huzaifa’s stories in your inbox

Join Medium for free to get updates from this writer.

First, we will assign the DOM elements to the variables to manipulate these elements through JavaScript.

const keyEvent = document.querySelector(".event-key .event-value");
const keyCodeEvent = document.querySelector(".event-keyCode .event-value");
const CodeEvent = document.querySelector(".event-code .event-value");
const whichEvent = document.querySelector(".event-which .event-value");
const shiftKey = document.querySelector(".key-shift .key-status");
const ctrlKey = document.querySelector(".key-ctrl .key-status");
const altKey = document.querySelector(".key-alt .key-status");

All of these variables are the p elements, in which the values will be assigned. If you do not know about querySelector or querySelectorAll yet. Then don’t worry, I have got your hands and I will walk you through it. The querySelector and querySelectorAll are basically fetching the Html elements with that class. They can be used to fetch elements through classes, ids, or tags. The basic difference between the querySelector and querySelectorAll is that querySelectorAll will return the NodeList with the same classes while the querySelector will give you the single element with that class. If you have more than one element with same class or tags, then it will fetch only the first element.

//Try to console.log this.
console.log(keyEvent); //p element
console.log(keyRow); // NodeList []
//NodeList is not array and it has not all methods of array on it.
//But you can convert it to array
//Array.from(keyRow)

Now, we will move forward to apply our functionalities and add event listener to the elements.

//Function
function keyboardEvents(e) {
e.preventDefault();
keyEvent.textContent = e.key;
keyCodeEvent.textContent = e.keyCode;
CodeEvent.textContent = e.code;
whichEvent.textContent = e.which;
}
// Event Handler
window.addEventListener("keydown", keyboardEvents);

Let’s see what is going on in this function. keyboardEvents is taking one argument which is e or event, this argument will be object which will contain all the properties that the event contains. This code will update the values in DOM.

  1. e.preventDefault() will prevent the default behavior of the browser. For example: pressing the function keys.
  2. All the elements fetched from DOM have some properties attacted to it, textContent is one of those. It will update the content of element.
  3. As I said, e has some properties and e.keyCode, e.key are one of that properties that are attached to keyboard events. While the other events like ‘click’, ‘dblclick’, ‘change’ etc. will contain different properties.
  4. We are attaching event listner to window, because this is the global element and event will delegate (we will discuss about that shortly) to all the elements under window.
  5. ‘keydown’ event will be fired when the keyboard key will be down/pressed.

Now we will work on the special keys like Shift, Ctrl and Alt.

function specialKeys(e) {
shiftKey.textContent = e.shiftKey;
ctrlKey.textContent = e.ctrlKey;
altKey.textContent = e.altKey;
}
window.addEventListener("keydown", specialKeys);
// by key release, special keys will come to original form
window.addEventListener("keyup", specialKeys);

e.shiftKey, e.ctrlKey and e.altKey will return the Boolean true or false depending upon the key is pressed or not respectively. And This function is assigned to two event listener because on key down, it will update the value and as the key is up, it will return false.
Well, the first part of this project is complete now. You will see the updation on the page as you will press any key.

HTML — Last Part

Now, let’s come back to our html and complete the code structure here.

<div class="keyboard rows">
<div class="row row-1">
<div data-key="27" class="row-key large-text-2">Esc</div>
<div data-key="112" class="row-key">F1</div>
<div data-key="113" class="row-key">F2</div>
<div data-key="114" class="row-key">F3</div>
<div data-key="115" class="row-key">F4</div>
<div data-key="116" class="row-key">F5</div>
<div data-key="117" class="row-key">F6</div>
<div data-key="118" class="row-key">F7</div>
<div data-key="119" class="row-key">F8</div>
<div data-key="120" class="row-key">F9</div>
<div data-key="121" class="row-key">F10</div>
<div data-key="122" class="row-key">F11</div>
<div data-key="123" class="row-key">F12</div>
<div data-key="45" class="row-key large-text">Insert</div>
</div>
.....
.....
</div>

Data Attribute in Html

The data-* attribute is used to store custom data private to the page or application. The data-* attribute gives us the ability to embed custom data attributes on all HTML elements. The stored (custom) data can then be used in the page’s JavaScript to create a more engaging user experience (without any Ajax calls or server-side database queries). — w3school

We will use data attribute with name key to store the key values and then compare it with the pressed key code to add class to the on-screen keyboard key which was pressed. We have created the two data attributes, one for simple keys data-key and second one for special keys data-spkey . Simple keys attribute will contain the keyCode while the special key attribute will contain the code.

JavaScript — Last Part

In this part, we will add and remove class from the on-screen keyboard to light it up when that specific key will be pressed.

First add this code on the top of file.

....
const keyboard = document.querySelector(".keyboard");
const keyRow = keyboard.querySelectorAll(".row-key");

Now add this code below your file.

//It will find the keys with the same data-key or data-spkey(super keys) and will add class to that key
function activeKey(e) {
keyRow.forEach((key) => {
if (e.code === key.dataset.spkey) {
key.classList.add("active");
} else if (e.keyCode == key.dataset.key) {
key.classList.add("active");
}
})
}

Now add this code to keyBoardEvent function.

function keyboardEvents(e) {
...
activeKey(e);
...
}

Now I will walk you through, what all of code is doing.

  1. In activeKey(e), we are looping through keyRow NodeList by its method forEach.
  2. In if condition, we are comparing the event code with the spkey data attribute. If they are equal, it will add class to the keyRow’s key.
  3. If that condition is false, it will check the next condition that if e.keyCode is equal to data-key.
  4. Now, we want this code to run, when any key is pressed. So we are adding it to keyBoardEvent(e) and passing the same argument as keyBoardEvent.

Now, we will make function that will remove class when the key is up or released.

function removeClass() {
// this will remove the class from element if it contains
keyRow.forEach((key) => {
if (key.classList.contains("active")) {
key.classList.remove("active");
}
});
}
// When you will release the key, it will remove class
window.addEventListener("keyup", removeClass);

As the keyup event will be fired, it will execute the removeClass() which will again loop through keyRow and if that key will contains the class .active and it will remove the class.

Event Bubbling

There is a great concept in JavaScript of event bubbling or event delegation. When ever an event is fired on some element, it will bubble up to its parent element until the first parent or first element like Html is reached. JavaScript developers take advantage of that beautiful concept to manipulate the complex data on DOM.

keyboard.addEventListener("click", function (e) {
console.log(e.target) //it will log the target element which was clicked.
});

If you run that code and click on any on-screen keys, you will see the element on console which was clicked. This is because the that fired event will bubble up to its parent keyboard.

This is useful because we do not have to loop over all the elements in keyboard. It will result in good performance of the website. Suppose we have 1000 or more element to apply event listener, it will jam the website. It can also be useful for the dynamic content to add event listener.

You can find more about event delegation on javascript.info.

keyboard.addEventListener("click", function (e) {
if (e.target.dataset.key) {
keyCodeEvent.textContent = e.target.dataset.key;
whichEvent.textContent = e.target.dataset.key;
keyEvent.textContent = e.target.innerText;
}
});

Now this function will see if the data-key attribute is available on targeted element and if it contains, then that data will be stored in textContent.

And our project is complete now. You can modify or extend this on your own if you want to

You can find the Project Demo and Source Code Here.

If you liked this article and find it helpful, then please follow me here and on GitHub and Twitter

--

--

Huzaifa
Huzaifa

Written by Huzaifa

0 followers

I am a Frontend Developer working in React js