Browser Event Handling
The problem
A page needs to react to user actions — clicks, key presses, scrolls — happening on arbitrary, often deeply nested elements, without wiring up a separate listener for every single element that might be interacted with.
Why now
The DOM as a tree already established parent/child structure; event handling is where that structure becomes directly useful for user interaction — events travel through the tree in a defined order, and the JavaScript event loop already covered is exactly what schedules an event handler's execution once triggered.
Mental model
An event doesn't just fire on the element it happened on — it travels down the tree to that element (capturing), then back up (bubbling), passing through every ancestor along the way. This is why one listener on a parent can handle clicks on any current or future child (event delegation) — you're catching the event during its bubble phase instead of listening on every child individually.
Requires
- The DOM as a TreeBrowser Internals
Event propagation (capturing and bubbling) is defined entirely in terms of the DOM tree's ancestor path; you need the tree structure before 'travels up through ancestors' has a path to travel.
- The Event LoopJavaScript Runtime
An event handler's execution is scheduled through the same task-queue mechanism the event loop describes; a click doesn't run its handler synchronously mid-instruction, it queues a task the loop later picks up.
Used in
- addEventListener and all interactive behavior on the web
- Event delegation, a common performance and simplicity pattern for lists and dynamic content
- React's synthetic event system, built on top of this same bubbling model
- Debugging 'why did my click handler fire twice' bugs caused by misunderstanding propagation
Projects
- Attach one click listener to a parent list element and use event delegation to handle clicks on any current or future child <li>, without attaching a listener to each item
- Demonstrate the capturing and bubbling phases explicitly by logging from listeners at three nested levels with both phase options
Examples
- A single listener on <ul> using event.target can handle clicks on any <li>, including ones added to the list after the listener was attached
- event.stopPropagation() prevents an event from continuing its bubble past the current handler, which can silently break outer listeners if overused
Resources
Mastery checklist
- I can explain the capturing and bubbling phases of event propagation
- I can implement event delegation using a single listener on a parent element
- I can explain what stopPropagation and preventDefault each do, and how they differ
- I can debug a duplicate-handler bug caused by misunderstanding event propagation