Explain Event Delegation in JavaScript

HighIntermediateJavascript
Preparing for interviews?

Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.

Quick Answer

Event delegation is a technique where a single event listener on a parent element handles events for multiple child elements by using event bubbling and checking the event target. Edge cases include stopPropagation and nested targets; test performance in large lists.

Answer

The Core Idea

Event delegation lets you attach one event listener to a common ancestor instead of multiple listeners to each child. When an event occurs, it bubbles up the DOM, and you check which child element triggered it using event.target.

JAVASCRIPT
// Example: Without delegation
const items = document.querySelectorAll('li');
items.forEach(item => item.addEventListener('click', () => {
  console.log('Clicked:', item.textContent);
}));
                  
JAVASCRIPT
// Example: With event delegation
const list = document.querySelector('ul');
list.addEventListener('click', (event) => {
  if (event.target.tagName === 'LI') {
    console.log('Clicked:', event.target.textContent);
  }
});
                  

Concept

Explanation

Example / Note

Event Bubbling

Events start from the target element and bubble up to its ancestors.

click on li → bubbles to ul

event.target

The original element that triggered the event.

Used to identify which child was clicked

event.currentTarget

The element that the event listener is attached to.

Usually the parent in delegation

How event delegation uses bubbling and target references.

Why Use Event Delegation?

  • Better performance — fewer event listeners in the DOM.
  • Handles dynamic elements added later (since the listener is on a stable ancestor).
  • Cleaner, more maintainable code for lists, tables, or repeated components.
JAVASCRIPT
// Example: Dynamic content
const container = document.querySelector('#buttons');

container.addEventListener('click', (e) => {
  if (e.target.matches('button.delete')) {
    e.target.remove();
  }
});

// Works even if buttons are added later!
                  

Common Pitfalls

  • Forgetting to check event.target → all clicks bubble and trigger the handler.
  • Relying on event.target when nested elements are inside clickable items (use .closest() to handle this safely).
JAVASCRIPT
// Example: Using closest() for nested targets
list.addEventListener('click', (event) => {
  const li = event.target.closest('li');
  if (!li) return; // click outside any li
  console.log('Clicked item:', li.textContent);
});
                  

Practical scenario
A long, dynamic list of comments can be handled with a single click listener on the list container.

Common pitfalls

      • Using event.target directly instead of closest() to find the intended item.
      • Forgetting that stopPropagation can block delegation.
      • Not handling keyboard events, so accessibility suffers.
Trade-off or test tip
Delegation saves memory but adds selector logic. Test by adding/removing items dynamically and ensuring handlers still work.

Still so complicated?

Imagine a restaurant. Instead of each waiter (child) taking orders, there’s one manager (parent) who hears all requests and decides who called — that’s event delegation!

Summary
  • Attach listener on parent, not each child.
  • Use event bubbling + event.target (or closest()) to detect the real source.
  • Improves performance and works for dynamically added elements.
Similar questions
Guides
4 / 61