Question presented to candidate: "When you click a deeply nested element, in what order do event listeners on its ancestors actually fire — and does it matter whether those listeners were registered for capturing or bubbling?"
What a strong answer should cover:
- 📌 Interview term: the capture phase — the event first travels downward, from
window/documenttoward the actual target element, triggering any listener registered with the thirdaddEventListenerargument set totrue(or{ capture: true }) along the way. - 📌 Interview term: the target phase — the event reaches the actual element it originated on.
- 📌 Interview term: the bubble phase — the event then travels back upward, from the target back out through every ancestor to
document, triggering any listener registered normally (capturefalse, the default). - 📌 Interview term: the real, verified firing order — verified directly with jsdom, registering listeners on both phases on nested outer/inner elements: the real order was
outer-capture -> inner-capture -> inner-bubble -> outer-bubble— capture genuinely goes root-to-target first, then bubble genuinely goes target-to-root. - A precise answer names that
addEventListener's default is bubble-phase (capturefalse) — most application code never explicitly deals with the capture phase, but understanding it correctly explains constructs like event delegation and whystopPropagation()called during capture can prevent a target's own bubble-phase handler from ever running.
Clarifying questions expected:
- None — this is a definitional/technical question; producing the exact real firing order (not just naming the two phases) is the strong signal.
Code / implementation expected: Yes — reproducing the real firing order with listeners on both phases is the most convincing, concrete demonstration.