Event Delegation

Event Delegation

Capturing and bubbling allow us to implement one of the most powerful event-handling patterns called event delegation. Event delegation is a technique in JavaScript that allows you to add a single event listener to a parent element, rather than adding event listeners to multiple child elements. This can be useful when you have a large number of elements that need to handle the same event, as it can reduce the amount of code you need to write and improve the performance of your application.

How it's done

Here's an example of how event delegation works:

we have a ul element with three li elements inside it. We've added a single-click event listener to the ul element. When any of the li elements are clicked, the event bubbles up to the ul element and is handled by the event listener.

Using event delegation, we can handle events for multiple elements with a single event listener, rather than having to add an event listener to each element individually. This can be more efficient and easier to maintain.

<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
 document.getElementById('list').addEventListener('click', function(event) {
    // Check if the clicked element is a list item
    if (event.target.tagName === 'LI') {
      // Do something with the list item
      console.log('You clicked on a list item!');
    }
  });

A Real Example

Let’s say, we want to make a menu with buttons “Save”, “Load”, “Search” and so on. And there’s an object with methods save, load, search… How to match them?

The first idea may be to assign a separate handler to each button. But there’s a more elegant solution. We can add a handler for the whole menu and data-action attributes for button that has the method to call:

<div id="menu">
  <button data-action="save">Save</button>
  <button data-action="load">Load</button>
  <button data-action="search">Search</button>
</div>
class Menu {
    constructor(elem) {
      this._elem = elem;
      elem.onclick = this.onClick.bind(this); // (*)
    }

    save() {
      alert('saving');
    }

    load() {
      alert('loading');
    }

    search() {
      alert('searching');
    }

    onClick(event) {
      let action = event.target.dataset.action;
      if (action) {
        this[action]();
      }
    };
  }

  new Menu(menu);

Use Cases

Event delegation can be useful in a number of situations when working with JavaScript:

  1. When you have a large number of elements that need to handle the same event: Instead of adding an event listener to each element individually, you can use event delegation to handle the event for all of the elements at once.

  2. When you need to add event listeners to elements that are dynamically added to the page: If you add an event listener to an element that doesn't exist yet, it won't work. With event delegation, you can add the event listener to a parent element that does exist, and it will work for any child elements that are added later.

  3. When you want to improve the performance of your application: Adding a large number of event listeners can impact the performance of your application, especially if the listeners are attached to elements that are high up in the DOM tree. By using event delegation, you can reduce the number of event listeners you need to add, which can improve the performance of your application.

  4. When you want to simplify the code for your application: Event delegation allows you to add a single event listener to a parent element, rather than adding multiple event listeners to child elements. This can make your code easier to read and maintain.

Limitations

  1. Event delegation only works for events that bubble up the DOM tree: Not all events bubble up the DOM tree. For example, the focus and blur events do not bubble. If you want to use event delegation with these types of events, you'll need to use a different technique, such as attaching the event listener to the document object.

  2. Event delegation can make it harder to debug events: When you use event delegation, the event listener is attached to a parent element, rather than the element that actually generated the event. This can make it harder to determine which element caused the event to be triggered, as the event.target property will refer to the parent element, rather than the element that was actually clicked.

  3. Event delegation can be confusing for beginners: Event delegation can be a bit confusing for developers who are new to JavaScript, as it involves adding event listeners to parent elements rather than the elements themselves. It can take some time to get used to this concept and understand how it works.

  4. Event delegation may not be the best choice for every situation: While event delegation can be a useful technique in some cases, it's not always the best choice. For example, if you only have a few elements that need to handle the same event, it may be simpler to just add event listeners to each element individually.

Summary

  1. Event delegation allows you to add a single event listener to a parent element, rather than adding event listeners to multiple child elements.

  2. It’s often used to add the same handling for many similar elements, but not only for that.

  3. The algorithm:

    1. Put a single handler on the container.

    2. In the handler – check the source element event.target.

    3. If the event happened inside an element that interests us, then handle the event.

Useful Links:

https://javascript.info/event-delegation

https://www.geeksforgeeks.org/event-delegation-in-javascript/

https://www.freecodecamp.org/news/event-delegation-javascript/

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events

Did you find this article valuable?

Support Divij Sehgal by becoming a sponsor. Any amount is appreciated!