Web Dev Notes
Master DOM event handling — click, submit, keyboard events, event delegation, bubbling and capturing, and building interactive web interfaces.
Introduction
DOM events are the backbone of interactive web pages. Every time a user clicks a button, types in a form, scrolls the page, or hovers over an element, the browser fires an event. JavaScript listens for these events and responds with custom behavior — showing dropdowns, validating forms, animating elements, or fetching data.
This guide covers how DOM events work in the browser, the event propagation model (bubbling and capturing), practical patterns like event delegation, and how to handle common user interactions like clicks, form submissions, and keyboard input.
How DOM Events Work
When something happens in the browser (user interaction, page loading, network response), the browser creates an Event object and dispatches it to the relevant DOM element. Your JavaScript code registers listeners that execute when specific events occur.
// Basic event listener
const button = document.getElementById('submit-btn');
button.addEventListener('click', function(event) {
console.log('Button was clicked!');
console.log('Event type:', event.type); // "click"
console.log('Target element:', event.target); // The button element
console.log('Mouse position:', event.clientX, event.clientY);
});The Event Object
Every event handler receives an Event object containing information about what happened:
| Property | Description | Example |
|---|---|---|
event.type | Type of event | "click", "keydown", "submit" |
event.target | Element that triggered the event | The actual clicked element |
event.currentTarget | Element the listener is attached to | The element with addEventListener |
event.preventDefault() | Stops default browser behavior | Prevent form submission |
event.stopPropagation() | Stops event from bubbling | Prevent parent handlers |
event.timeStamp | When the event occurred | Milliseconds since page load |
Event Propagation: Bubbling and Capturing
When an event fires on a nested element, it doesn't just trigger on that element — it travels through the DOM tree in three phases:
| Phase 1: CAPTURING (top | down) |
| Phase 2 | TARGET (the actual element) |
| Phase 3: BUBBLING (bottom | up) |
| <html> ← Phase 1 | Capturing (down) |
| <button> ← Phase 2 | Target |
| <html> ← Phase 3 | Bubbling (up) |
Bubbling (Default Behavior)
By default, events bubble UP from the target element to the document:
Capturing Phase
To listen during the capturing phase (top-down), pass true as the third argument:
Stopping Propagation
Event Delegation
Event delegation is a powerful pattern where you attach a single listener to a parent element instead of individual listeners on many children. It leverages event bubbling.
Problem: Adding Listeners to Dynamic Elements
Practical Event Delegation Example
Common Event Types
Mouse Events
Keyboard Events
Form Events
Scroll and Resize Events
Performance Patterns
Debouncing
Execute the handler only after the user stops triggering the event:
Throttling
Execute the handler at most once per time interval:
Removing Event Listeners
// Named function — can be removed
function handleClick(event) {
console.log('Clicked');
}
button.addEventListener('click', handleClick);
button.removeEventListener('click', handleClick); // Works!
// AbortController — clean removal of multiple listeners
const controller = new AbortController();
element.addEventListener('click', handleClick, { signal: controller.signal });
element.addEventListener('keydown', handleKey, { signal: controller.signal });
element.addEventListener('scroll', handleScroll, { signal: controller.signal });
// Remove all three at once
controller.abort();
// Once option — auto-removes after first trigger
button.addEventListener('click', handleClick, { once: true });Custom Events
Create and dispatch your own events for component communication:
Interview Questions
Q1: What is the difference between event bubbling and capturing?
Answer: When an event occurs on a nested element, it propagates through the DOM in two directions. Capturing goes from the document root down to the target element (top-down). Bubbling goes from the target element back up to the root (bottom-up). By default, listeners fire during the bubbling phase. Pass true as the third argument to addEventListener to listen during capturing.
Q2: Explain event delegation and why it's useful.
Answer: Event delegation attaches a single listener to a parent element instead of individual listeners on each child. It works because of event bubbling — clicks on children bubble up to the parent. Benefits: (1) Works with dynamically added elements, (2) Uses less memory (one listener vs hundreds), (3) Less setup code. Use event.target.closest(selector) to identify which child was clicked.
Q3: What is the difference between event.target and event.currentTarget?
Answer: event.target is the actual element the user interacted with (where the event originated). event.currentTarget is the element the listener is attached to. With event delegation, if you click a <span> inside a <li> and the listener is on the <ul>, then target is the <span> and currentTarget is the <ul>.
Q4: How do preventDefault() and stopPropagation() differ?
Answer: preventDefault() stops the browser's default action (form submission, link navigation, checkbox toggling) but the event still propagates. stopPropagation() stops the event from traveling to parent elements but doesn't prevent the default action. You might need both: prevent a form from submitting AND prevent a parent handler from running.
Q5: What is debouncing vs throttling?
Answer: Debouncing waits until the user stops triggering an event for a specified delay, then executes once (good for search input — wait until they finish typing). Throttling executes at most once per time interval regardless of how often the event fires (good for scroll/resize — update at a steady rate). Debounce = "wait for silence," Throttle = "limit frequency."
Quick Revision Notes
- addEventListener = Modern way to attach event handlers (supports multiple)
- Bubbling = Events travel UP from target to document (default)
- Capturing = Events travel DOWN from document to target (use
trueflag) - event.target = Element that was actually clicked/triggered
- event.currentTarget = Element the listener is attached to
- Event Delegation = One parent listener for many children (uses bubbling)
- preventDefault() = Stop default behavior (form submit, link navigate)
- stopPropagation() = Stop event from reaching parent elements
- Debounce = Wait for pause → then execute once
- Throttle = Execute at most once per interval
- passive: true = Tells browser you won't call preventDefault (scroll perf)
- { once: true } = Auto-removes listener after first fire
Summary
DOM events are how JavaScript makes web pages interactive. Understanding event propagation (bubbling up, capturing down) enables powerful patterns like event delegation — where a single listener on a parent handles interactions for hundreds of children, including dynamically added ones. Combined with debouncing, throttling, and proper cleanup, these patterns create performant, maintainable interactive interfaces.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for JavaScript DOM Events.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Web Development topic.
Search Terms
web-development, web development, web, development, javascript, events, javascript dom events
Related Web Development Topics