2 min read

Event Delegation

Event delegation is a technique involving adding a single event listener to a parent element to manage events for all of its children (even those that don't exist yet).

1. How it Works

It relies on Event Bubbling. When an event occurs on an element (like a button click), it bubbles up to its parent, then the grandparent, and so on. By listening on a common ancestor, you can catch events from any descendant.

2. The Problem: Many Listeners

Imagine a list with 100 items.

<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <!-- ... -->
  <li>Item 100</li>
</ul>

Adding an event listener to each <li> is inefficient.

// Inefficient
const items = document.querySelectorAll('li');
items.forEach(item => {
  item.addEventListener('click', () => {
    console.log('Clicked!');
  });
});

3. The Solution: Delegation

Add one listener to the <ul>.

document.getElementById('list').addEventListener('click', function(e) {
  // e.target is the actual element clicked (the <li>)
  // e.currentTarget is the element listening (the <ul>)

  if (e.target && e.target.nodeName === "LI") {
    console.log("List item clicked!", e.target.textContent);
  }
});

4. Benefits

  1. Memory Usage: Significantly fewer event listeners consume less memory.
  2. Dynamic Elements: If you add a new <li> to the list later via JavaScript, the parent listener automatically handles it. You don't need to attach a new listener to the new item.

5. Limitations

  • Some events like focus, blur, and load do not bubble (though focusin/focusout do).
  • You must be careful with e.target if the clickable element contains other elements (like an icon inside a button). You might need to use e.target.closest('button').

programming/javascript/vanilla/javascript programming/javascript/vanilla/events programming/javascript/vanilla/event-bubbling-vs-capturing