October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk3 min

JavaScript Event Bubbling and Delegation, Explained

Event bubbling carries events from nested elements to ancestors; event delegation uses one parent listener to handle many descendants, including controls added later.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Event bubbling lets an event that starts on a nested element travel up through its ancestors. Event delegation uses that behavior: instead of attaching a separate click listener to every button, attach one listener to their shared parent and identify which button was clicked.

What event bubbling means

Browser events are provided by the Web Platform, rather than being a special feature of the JavaScript language. For an event that propagates through the DOM, dispatch has three phases: capture travels down from ancestors toward the target, the target phase runs listeners on the target, and bubbling travels back up through ancestors. MDN’s event bubbling guide illustrates how an ancestor can respond to an event that began on a descendant.

As an Amazon Associate I earn from qualifying purchases.

By default, addEventListener() registers a non-capturing listener. For an event that bubbles, a click on a button inside a list can therefore reach a listener attached to the list. The capture option changes when a listener runs; see MDN’s addEventListener() reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How event delegation works

Delegation is a way to handle interactions from multiple descendants with a listener on their shared ancestor. The handler checks the event’s origin, finds the relevant control, and responds only when that control belongs to the delegated region. It is especially useful for repeated controls and for descendants added after the parent listener is installed, provided the event bubbles to that parent.

const list = document.querySelector(".todo-list");

list.addEventListener("click", (event) => {
  const button = event.target.closest("button[data-action]");

  if (!button || !list.contains(button)) return;

  if (button.dataset.action === "remove") {
    button.closest("li")?.remove();
  }
});

Here, closest() means a click on an icon or span inside the button can still resolve to the button. The containment check keeps the match within this list. The selector and removal behavior should match your own markup and application.

Choose the right event target

event.target is the object where the event originated; it may be a nested icon rather than the button you intend to handle. event.currentTarget is the object whose listener is currently running—in this example, the list. Use the target to locate the intended descendant, and the current target when you need to refer to the delegation root. MDN documents these distinctions in its Event reference.

Delegation or a listener on each element?

Approach Useful when Trade-off
One delegated listener on a shared ancestor Many similar descendants share behavior, or relevant descendants may be added later. The handler must identify the intended descendant correctly, and the event must reach the ancestor.
A listener on each element A control is isolated, or keeping its behavior beside that element makes the code clearer. Each relevant element needs its own listener and lifecycle handling.

Delegation is a code-organization choice, not a guaranteed performance improvement. The cited documentation describes the pattern but does not establish a comparative performance benchmark. Consider the number and lifecycle of the elements, the clarity of the handler, and whether dynamic descendants need to be covered.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Propagation is not the same as a browser default action

stopPropagation() stops an event from continuing to propagate; it does not cancel a default action such as following a link. If the event is cancelable and you need to prevent its default action, call preventDefault(). stopImmediatePropagation() also prevents other listeners on the same element from running. These methods solve different problems, so avoid stopping propagation as a routine way to silence an unwanted handler: doing so may keep unrelated ancestor listeners from seeing the event. See MDN’s stopPropagation() reference and Event reference.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Capture, non-bubbling events, and Shadow DOM

Use capture when timing matters

A capturing listener runs on the path toward the target, before the target phase. For ordinary delegated interactions, the default non-capturing listener is usually the relevant choice; use capture when an ancestor needs to run before the event reaches descendants. The option is documented in MDN’s addEventListener() reference.

Check whether the event bubbles

Delegation depends on the event reaching the ancestor listener. Not every event bubbles, so do not assume a parent listener will see every event from a child. For a custom event, inspect its bubbles setting as well as its other propagation options.

Account for Shadow DOM boundaries

An event crosses a Shadow DOM boundary only if it is composed; ordinary propagation through that boundary also requires bubbles to be true. composedPath() can help inspect the route, but a closed shadow root does not expose its internal nodes in that path. Consult MDN’s documentation for Event.composed and the Event interface when working across component boundaries.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.