JavaScript Event Delegation Explained

Subscribe to my newsletter and never miss my upcoming articles

Hello coders! Today, I'll be explaining a useful and powerful event handling concept in JavaScript called Event Delegation. But first, a little background knowledge is needed.

Background Knowledge: Event Capturing & Bubbling

An 'onclick' attribute is usually attached to a <button> element in HTML. This attribute allows the button to run an event (function) when someone clicks on it. Similar to when you add an addEventListener() to a button from a script.

For 'onclick' event handlers, 2 phases occur: Capturing and Bubbling

Event Capturing: browser checks from the topmost element <html> for an onclick handler on it. If it does, it will run it before moving down to the next HTML element and repeat the process until it reaches the target (clicked) element. AKA Top to Target.

On the other hand,

Event Bubbling: browser checks from the target (clicked) element for an onclick handler on it. If it does, it will run it before moving up to the next HTML element and repeat the process until it reaches the topmost element <html>. AKA Target to Top.

Here's the visual explanation of the 2 phases

1.png miro.medium.com/max/1280/1Et5UjVPGLfF1L43T7..

Note: In modern browsers, by default, all event handlers are registered for the bubbling phase. Source: developer.mozilla.org/en-US/docs/Learn/Java..

For this reason, using too much 'onclick' handlers can sometimes get messy, especially when you have an event that runs in an element with a parent element who has an 'onlick' attribute too. The parent element's 'onclick' will be triggered even if you don't want it to.

A solution to this issue is:

  1. Use addEventListener() instead
  2. Add event.stopPropagation() in the event function

Though it might seem that these 2 phases are troublesome, they are not entirely bad. In fact, as a developer, Event Capturing and Bubbling can be used to implement a more efficient way to code event handlers. Yes, this efficient event handling concept is known as Event Delegation.

Event Delegation

A powerful and efficient event handling pattern to use when a lot of elements in a parent will run the same event.

Let's take a look at an example. Say you have a "to-do list" app like this:

2.png

Instead of adding an event handler in each "COMPLETED" button to remove the task when the button is clicked, we can just place one event handler in the parent element.

Here's the HTML:

<div id="task-box">
    <h2>My Tasks</h2>
    <div id="task">
        <button class="done">COMPLETED</button>
        <p>9am-10am</p>
        <p>Walk my dog</p>
    </div>
    <div id="task">
        <button class="done">COMPLETED</button>
        <p>10am-12pm</p>
        <p>Do homework</p>
    </div><div id="task">
        <button class="done">COMPLETED</button>
        <p>12pm-4pm</p>
        <p>Lunch with friends</p>
    </div>
</div>

So instead of an 'onclick' to each <button> element. We have an 'onclick' assigned to <div id="task-box"> element that will check if button was clicked and runs a removeTask() function to delete that button and its task from the to-do list. Let's code that:

// Get the parent div
document.getElementById("task-box").onclick = function(event) {

        //if the clicked element is a button with class = "done"
        if (event.target && event.target.matches("button.done")) {
                   removeTask(event.target.parentNode);  //remove the <div id = "task">
    }
});

And the result worked perfectly:

demo.gif

Explanation

When the button is clicked, the Bubbling phase checks if the button (target element) has an 'onclick'. It does not, so it moves up to <div id = "task"> and checks again. No it doesn't have an 'onclick' too, so it moves up again to <div id="task-box">. Aha! An 'onclick' is found! So it will run the function, which checks the event.target (the clicked element). If it is a button with class = "done", then we shall remove the <div id = "task"> (parentNode of event.target) by calling the function removeTask().

And that's it!

I hope this simple example helps you visualize how Event Delegation works and how it uses Event Bubbling/Capturing to implement its concept. It is very helpful in situations like this to-do list, when elements are constantly being removed and added. It will be a hassle to add an 'onclick' to each button.

There are so many wonderful uses to implementing Event Delegation. I hope you can apply it to your projects. Thank you for reading and if you find it helpful, please leave a 'thumbs up' to let me know~ If you have any questions regarding Event Capturing/Bubbling and Event Delegation, please do not hesitate to ask in the comments. Till next time, cheers!

No Comments Yet