DOM Event Flow and Delegation
Walk me through capture, the target phase, and bubbling for a DOM event. How would you control propagation and use that model for event delegation?
what they're testing: The interviewer is probing whether you can reason about browser event flow and turn that model into maintainable UI code.
A DOM event first travels from the outer ancestors toward its target, where capture listeners use { capture: true }. At the target, both capture and non-capture listeners run. If the event bubbles, it then travels back through the ancestors and runs their non-capture listeners. event.target identifies where the event was dispatched, while event.currentTarget is the object whose listener is running. Shadow DOM can retarget target across a boundary.
Propagation and browser behavior have separate controls. stopPropagation() keeps the event from reaching other objects on the path, but later listeners on the same object can still run. stopImmediatePropagation() stops those listeners as well. preventDefault() cancels a cancelable browser action, such as following a link, without stopping propagation.
Delegation uses that bubble path. Put one listener on the nearest stable container instead of one on every row or button. In the handler, first check that event.target is an Element, then use closest("[data-action]"). Ignore a missing match and confirm container.contains(match) before acting. That handles nested icons and matching children added later. It also reduces listener setup and cleanup, but requires an event that bubbles and has not been stopped below the container.
Why it lands
what makes the answer strong
- Explains the full event path in execution order
- Separates propagation control from default browser behavior
- Shows a robust delegation pattern for nested and dynamic content
Where people slip
answers that sound right but are wrong
- Says events start at the target and only bubble upward
- Treats `target` and `currentTarget` as interchangeable
- Claims `preventDefault()` also stops bubbling
- Checks only `event.target` and misses clicks on nested markup
If they push further
How would you delegate an event that does not bubble?
For `focus`, put a capture listener on the ancestor, or use the bubbling `focusin` event if its semantics fit. The same choice depends on the specific non-bubbling event.
What is the difference between `stopPropagation()` and `stopImmediatePropagation()`?
Both stop further travel along the event path. The immediate form also prevents later listeners on the current element from running.
Why delegate to a nearby container instead of `document`?
A nearby stable ancestor keeps selector checks and ownership local. It also reduces accidental coupling with unrelated parts of the page.
Sources
- MDN: Event bubbling ↗developer.mozilla.org
- WHATWG DOM Standard: Dispatching Events ↗dom.spec.whatwg.org
- MDN: Event.stopPropagation() ↗developer.mozilla.org
- MDN: Event.preventDefault() ↗developer.mozilla.org
- MDN: Element.closest() ↗developer.mozilla.org
- MDN: Element focusin Event ↗developer.mozilla.org
Now answer it yourself.
Reading a strong answer is easy. Producing one under pressure is the skill the interview tests. Gapmap grades your answer against the same bar an interviewer would.
beta
The interviewer part is in the works.
The diagnostic, personal maps, and AI mock interviews are being finished right now. The notes stay free either way. Leave an email and you'll get the first-cohort invite, plus a month of Pro when it opens.