Facebook Pixel
Step-by-Step Guide

How to do Event Delegation in JavaScript

A step-by-step guide on how event bubbling enables event delegation to efficiently handle events on dynamic lists and large numbers of elements.

Understand Event Propagation Phases

When you click on a DOM element, the event does not just trigger on that element. It travels through three phases. First the capture phase where the event travels from the document root down to the target element. Then the target phase where the event reaches the element that was clicked. Then the bubbling phase where the event travels back up from the target to the document root.

Understand Event Bubbling

During the bubbling phase, the event triggers on the target element first, then on its parent, then on the grandparent, continuing up through every ancestor until it reaches the document. This means if you click a button inside a div inside a section, the click event fires on the button, then on the div, then on the section, then on the body, then on the document.

Understand the Problem Event Delegation Solves

If you have a list with a thousand items and attach a click listener to every single item, you create a thousand event listener objects in memory. If items are added dynamically after the initial render, you must manually attach listeners to each new item. Both problems are solved by event delegation, which attaches a single listener to the parent and handles clicks for all children.

Implement Event Delegation on a Parent Element

Attach a single event listener to the parent container instead of to each individual child. When any child is clicked, the event bubbles up to the parent and triggers the listener. Inside the callback, use the event object's target property to determine which specific child was clicked. This one listener handles clicks for all existing and future children.

Use event.target to Identify the Clicked Element

The event.target property refers to the exact element that was originally clicked, regardless of where the listener is attached. Inside a delegated event handler on a parent, read event.target to get the actual clicked element. Check its tag name, class, ID, or data attributes to determine what action to take. This allows one handler to respond differently based on which child was clicked.

Use event.target.closest for Nested Structures

When list items contain nested child elements like icons or spans, clicking the icon sets event.target to the icon, not the list item. Use event.target.closest with a CSS selector to find the nearest ancestor matching that selector. For example, event.target.closest('li') finds the nearest li ancestor of the clicked element, correctly identifying the list item even when an inner element was clicked.

Stop Propagation When Necessary

Sometimes you need to prevent an event from bubbling further up the DOM. Call event.stopPropagation inside a handler to stop the event from traveling to parent elements. Use this carefully and only when necessary because it can break event delegation that relies on bubbling. Also avoid using stopPropagation in library code or shared utilities as it silently prevents other code from responding to the event.

Understand the Performance Benefits

Event delegation reduces memory usage by replacing many individual event listeners with a single listener on the parent. It simplifies dynamic content management because you never need to add or remove listeners when items are added or removed from the DOM. It also reduces the risk of memory leaks from forgotten listeners on removed elements. These benefits make event delegation the preferred pattern for handling events on lists, tables, and dynamically generated content.

Ready to master this completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.