12: Working wth the Event object

Using the event object to identify which web page object or keyboard character the user has interacted with.

Learning Goals

At the end of this Lesson, you will be able to:

  • Use the id and the className properties of the event object to identify user clicking/tapping actions.
  • Use the key property of the event object to identify user keyboard actions.

In your javascript/exercises folder, create a new sub-folder named event-object.

Save the exercise file below to this new javascript/exercises/event-object sub-folder.

Event Object: Exercises

About the event(e) object

Sometimes you will want to know information about the button or other web page element the user has interacted with. In particular, you will want to know:

  • The id of the element.
  • The class of the element.

In the example below, you can see that the HTML button element has both an id and a class.

<!-- Button with id and class -->
<button id="myBtn" class="btn-green">Click me</button>

You could capture a user click on this button with the addEventlistener() method as follows.

// Get button from web page
const btn_1 = document.getElementById('myBtn');
			
// Attach 'click' listener arrow function to button
btn_1.addEventListener('click', () => {
    console.log(`You clicked a button`);
});

To discover details about the button clicked, you can use the built-in event object as follows.

// Attach 'click' listener arrow function to button
btn_1.addEventListener('click', (event) => {
    console.log(`You clicked the button with an id of: ${event.target.id}`);
    console.log(`You clicked the button with a class of: ${event.target.className}`);
});

In modern JavaScript the event object is usually represented by the single letter e See below.

// Attach 'click' listener arrow function to button
btn_1.addEventListener('click', (e) => {
    console.log(`You clicked the button with an id of: ${e.target.id}`);
    console.log(`You clicked the button with a class of: ${e.target.className}`);
});

And finally, because e is the only parameter of the arrow function, you need not type the parenthesis ().

// Attach 'click' listener arrow function to button
btn_1.addEventListener('click', e => {
    console.log(`You clicked the button with an id of: ${e.target.id}`);
    console.log(`You clicked the button with a class of: ${e.target.className}`);
});

Multiple buttons, a single event listener

You can use the event object to process multiple buttons on a web page with just a single event listener.

Consider the example of the four HTML buttons below on a web page. (Assume the web page contains no other buttons.) There are also two elements to hold the inputs and one to display the result.

<!-- Two input numbers -->
<p>First Number <span id="num_1">10</span></p>
<p>Second Number <span id="num_2">4</span></p>

<!-- Four buttons to perform arithmetic -->
<button id="btn_1">+</button>
<button id="btn_2">-</button>
<button id="btn_3">*</button>
<button id="btn_4">/</button>

<!-- Calculation result -->
<p>Result: <span id="num_result"></span></p>

Follow these steps to process all four buttons with just one event listener.

  1. Select all four buttons with the getElementsByTagName() method.
    // Get all web page buttons and place in a nodelist
    const nodeListButtons = document.getElementsByTagName('button');
      JavaScript places all four buttons in a nodelist which is similar to an array.
  2. Convert the nodelist to an array.
    // Convert nodelist to an array
    const arrButtons = Array.from(nodeListButtons);
  3. Loop through the array with the forEach() method.
    // Loop through array 
    arrButtons.forEach(button => {
       ...	
    }); // ends forEach loop
  4. On each loop iteration, attach an event lister with an arrow function that responds to button click event.
    Attach 'click' listener to each button
    button.addEventListener('click', e => {
        // Arrow function that responds to click event
        console.log(`You clicked the button with an id of: ${e.target.id}`);
    }); // ends adding listeners with arrow function

That's it.

Here is the complete code

// Get all web page buttons and place in a nodelist
const nodeListButtons = document.getElementsByTagName('button');

// Convert nodelist to an array
const arrButtons = Array.from(nodeListButtons);

// Loop through array 
arrButtons.forEach(button => {
    // Attach 'click' listener to each button
    button.addEventListener('click', e => {
        // Arrow function that responds to click event
        console.log(`You clicked the button with an id of: ${e.target.id}`);
    }) // ends adding listeners with arrow function
}); // ends forEach loop

Passing event details to an external function

You can now pass the id of the clicked button from the event listener as an argument to an external function that will perform the arithmetic.

In your code replace the console.log statement with a function call as follows.

// External function called by 'click' event.
doOperation(e.target.id);

Now create a function declaration with four branches that accepts an input parameter named op.

// Function to perform arithmetic and display result.
function doOperation(op) {
    // Get numbers from web page and convert string to integer
    const num_1 = parseInt(document.getElementById('num_1').textContent);
    const num_2 = parseInt(document.getElementById('num_2').textContent);
    let num_result;
    //  Get only number character from string passed as argument	
    op = op.replace("btn_", "");
    //  Convert number character to numeric variable
    op = parseInt(op);

    //  Branch according to passed argument with strict equality operator	
    if (op === 1) { num_result = num_1 + num_2 } 
    else if (op === 2) { num_result = num_1 - num_2 } 
    else if (op === 3) { num_result = num_1 * num_2 } 
    else if (op === 4) { num_result = num_1 / num_2 }

    //  Display result	
    document.getElementById('num_result').textContent = num_result;
}

Working with classes of web page elements

In the next example you will work with the className instead of the id property of the event object. The captured className to determine which branch the response code will follow.

Begin by copying the following to your web page.

<!-- Increment and decrement elements -->
<p><a href="#" class="btn-link link-increment">Increase</a></p>
<p><a href="#" class="btn-link link-decrement">Decrease</a></p>
<p>Output: <span id="output">0</span></p>

You can see that both hyperlinks have two class names:

  • Both hyperlinks share the same classs name of btn-link.
  • The first hyperlink also has a class name of link-increment.
  • The second hyperlink also has a class name of link-decrement.

Start your JavaScript code by capturing all the hyperlinks on the web page with a class of btn-link and then converting the nodelist to an array.

// Get all hyperkinks with this class name
const nodeListLinks = document.querySelectorAll('.btn-link');

// Convert nodelist to an array
const arrLinks = Array.from(nodeListLinks);

Next, add code that loops through the array and branches according to the classList property.

// Loop through array
arrLinks.forEach(link => {
    // Attach 'click' listener to each link
    link.addEventListener('click', e => {
        // Arrow function that responds to click event
        if (e.target.className.includes("increment")) {
            document.getElementById('output').textContent = parseInt(document.getElementById('output').textContent) + 1;
        } 
        else if (e.target.className.includes("decrement")) {
            document.getElementById('output').textContent = parseInt(document.getElementById('output').textContent) - 1;
        }
    }); // ends adding listeners with arrow function
}); // ends forEach loop

The includes() method determines whether a string includes a certain substring among its entries, returning true or false as appropriate.

Working with keypress events

You can capture user keyboard actions with the following two-step process:

  • Use the addEventListener() method with the keypress event to capture the user action.
  • Find the key pressed from the key property of the event object.

Here is a simple example.

// Listen for any key being pressed
document.addEventListener('keypress', e => {
if (event.key === 'r') {
    document.body.style.backgroundColor = 'red';
    } else if (event.key === 'g') {
        document.body.style.backgroundColor = 'green';
    } else if (event.key === 'b') {
        document.body.style.backgroundColor = 'blue';
    }
});

In this the event.key property identifies which key was pressed, and the background color of the page is changed accordingly.