JavaScript · The language round
How does event bubbling and delegation work?
Short answer
Events travel through capture, target and bubble phases. Delegation uses one listener on a parent to handle events from many children, relying on bubbling and event.target.
When an event fires, the browser first walks down from the window to the target during capture, then runs listeners on the target, then walks back up during bubbling. Most listeners are registered for the bubble phase by default.
document.querySelector("#list").addEventListener("click", (event) => {
const button = event.target.closest("button[data-id]");
if (!button) return;
console.log("clicked", button.dataset.id);
});The methods you need
event.targetis the element that fired the eventevent.currentTargetis the element whose listener is runningstopPropagation()prevents the event from continuing to other elementspreventDefault()cancels the browser's default action, such as a link navigation{ capture: true }registers a listener for the capture phase
Delegation is valuable for lists that change frequently. Instead of attaching and removing listeners for every row, attach one listener to the container and inspect the target. It also reduces memory usage and avoids leaks from forgotten listeners.
element.addEventListener("scroll", onScroll, { passive: true });preventDefault(), which can improve scrolling performance.stopPropagation() does not prevent other listeners on the same element from running. stopImmediatePropagation() does.Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What are the capture, target and bubble phases?
- 2What is the difference between `target` and `currentTarget`?
- 3When should you use event delegation?
- 4What is a passive event listener?
Say it in the interview
Events move through capture, target and bubble phases. By default listeners run during bubbling, so an event on a child reaches its ancestors. Delegation puts one listener on a parent and uses event.target to find the actual child, which is efficient for dynamic lists. I use stopPropagation to stop bubbling, preventDefault to cancel browser behaviour, and passive listeners for scroll or touch handlers that do not call preventDefault.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live JavaScript mock interview and get scored feedback on depth, clarity and confidence.