← Back to JavaScript Course | Chapter 10: DOM Advanced | Lesson 1 of 8

JS Event Delegation

Event delegation means putting one listener on a parent instead of one on every child, like a single doorbell for a whole apartment building. It also works for items added later.
Syntax
javascript
parent.addEventListener("click", function(event) {
  if (event.target.matches("selector")) {
    // handle child click
  }
});

What Is Event Delegation?

Event delegation lets one parent handle events from many child elements. It uses event bubbling.

Because bubbling carries the event up through every ancestor, a single listener on a shared parent can inspect event.target to figure out which specific child was actually interacted with.

Example: What Is Event Delegation?

javascript
<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
</ul>
<script>
  document.getElementById("list").addEventListener("click", (e) => {
    // Print `"Clicked:", e.target.textContent` to the console
    console.log("Clicked:", e.target.textContent);
  });
</script>

Why Use Event Delegation?

Delegation reduces the number of event listeners. It is useful for lists and other dynamic content.

Attaching one listener to a container instead of one per child item scales better and uses less memory, especially for long or frequently-changing lists.

Example: Why Use Event Delegation?

javascript
<ul id="list">
  <li>A</li><li>B</li><li>C</li>
</ul>
<script>
  // Listen for the `click` event on `document.getElementById("list")` and run the handler when it fires
  document.getElementById("list").addEventListener("click", (e) => console.log(e.target.textContent));
</script>

Handling Dynamic Elements

A delegated listener also works for elements added after the listener was created. This is one of delegation's biggest practical advantages: you don't need to re-attach listeners every time new elements are inserted into the delegated container.

Example: Handling Dynamic Elements

javascript
<ul id="list"><li>Old Item</li></ul>
<script>
  const list = document.getElementById("list");
  list.addEventListener("click", (e) => console.log("Clicked:", e.target.textContent));
  const newItem = document.createElement("li");
  newItem.textContent = "New Item";
  list.appendChild(newItem); // still handled by the same listener
</script>

Using closest()

The closest method helps find the nearest matching ancestor when an event starts on a nested element.

Since the actual click target might be a nested element rather than the item itself, closest() reliably walks up to find the enclosing element you actually care about.

Example: Using closest()

javascript
<ul id="list">
  <li><span>Item</span></li>
</ul>
<script>
  document.getElementById("list").addEventListener("click", (e) => {
    // Declare the constant `item`, set to `e.target.closest("li")`
    const item = e.target.closest("li");
    // Print `item.textContent` to the console
    console.log(item.textContent);
  });
</script>

Practical Delegation

Event delegation is a good choice when many similar elements need the same event behavior. Delegation is the standard approach for things like a to-do list where items are added and removed dynamically, avoiding constant listener management.

Example: Practical Delegation

javascript
<ul id="todo-list">
  <li>Buy milk</li>
  <li>Walk dog</li>
</ul>
<script>
  document.getElementById("todo-list").addEventListener("click", (e) => {
    // Print `"Task clicked:", e.target.textContent` to the console
    console.log("Task clicked:", e.target.textContent);
  });
</script>
Live Example
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using event.target directly when the click lands on a child element, such as an icon inside a button; use closest().
  2. Attaching the listener to each item instead of the parent, so new elements do not get it.
  3. Using an event that does not bubble, such as focus, so delegation does not work.
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.