document.getElementById('parent').addEventListener('click', () => console.log('parent clicked'));
document.getElementById('child').addEventListener('click', () => console.log('child clicked'));
// clicking child logs 'child clicked' then 'parent clicked'
Topics
37
ArrayBuffer, TypedArrays & Binary Data
Arrays & Array Methods
Async Iterators & Streams
Browser Storage & Web APIs
Classes & Class Syntax
Date, Time & Internationalization (Intl API)
Debugging, Testing & Tooling
Design Patterns in JavaScript
Destructuring, Spread & Rest
DOM & Events
Error Handling
ES Modules
Event Loop & Concurrency
Functional Programming
Iterators & Generators
JSON & Data Serialization
Map, Set, WeakMap & WeakSet
Memory Management & Garbage Collection
Networking: Fetch, XHR, WebSockets & CORS
Numbers, Math & BigInt
Objects, Property Descriptors & Immutability
Optional Chaining & Nullish Coalescing
Package Management, Bundlers & Transpilation (npm, Webpack/Vite, Babel)
Performance Optimization: Debouncing, Throttling & Memoization
Promises & async/await
Prototypes & Inheritance
Proxy & Reflect
Regular Expressions
Scope, Hoisting & Closures
Security: XSS, CSRF & Content Security Policy
Service Workers & Progressive Web Apps
Strings & Template Literals
Symbols & Well-Known Symbols
this & Binding
Types & Coercion
Web Components & Custom Elements
Web Workers & Multithreading
DOM & Events
10 questions found
Event bubbling means an event fired on an element propagates upward through its ancestors in the DOM tree, triggering any matching event listeners on parents after the target element's own listeners run.
Real-world example
A single click listener on a <ul> catching clicks from any <li> inside it, instead of attaching a listener to every item.
Design Patterns in JavaScript
It cancels the browser's default action for that event — like following a link's href, submitting a form, or checking a checkbox — while still allowing the event to bubble unless you also stop propagation.
form.addEventListener('submit', (e) => {
e.preventDefault();
validateAndSubmitViaFetch();
});
Real-world example
Intercepting a form submission to send data via fetch() instead of a full page reload.
Networking: Fetch
XHR
WebSockets & CORS
Use document.querySelector() (or similar) to find the element, then set its textContent property to update the text safely without interpreting it as HTML.
const el = document.querySelector('#status');
el.textContent = 'Saved successfully';
Real-world example
Updating a status message on screen after a save action completes.
Security: XSS
CSRF & Content Security Policy
Event delegation attaches a single listener to a common ancestor and uses event.target to determine which child triggered it, instead of attaching a separate listener to every child — this uses far less memory and automatically works for dynamically added children.
document.getElementById('list').addEventListener('click', (e) => {
if (e.target.matches('li')) {
console.log('Clicked item:', e.target.textContent);
}
});
Real-world example
Handling clicks on rows of a dynamically loaded, potentially thousands-of-items-long table.
Performance Optimization: Debouncing
Throttling & Memoization
event.target is the actual element that originated the event (e.g., the specific <li> clicked); event.currentTarget is the element the listener is currently attached to and executing on (e.g., the parent <ul> during bubbling).
list.addEventListener('click', (e) => {
console.log(e.target); // the <li> clicked
console.log(e.currentTarget); // the <ul> the listener is on
});
Real-world example
Using target to identify which specific button in a toolbar was clicked, while currentTarget stays constant.
Design Patterns in JavaScript
Construct a CustomEvent with an optional detail payload, then call dispatchEvent() on a target element; other code can listen for it exactly like a native event.
const event = new CustomEvent('itemAdded', { detail: { id: 42 } });
el.addEventListener('itemAdded', (e) => console.log(e.detail.id));
el.dispatchEvent(event); // logs 42
Real-world example
Decoupling a cart component from a header badge by having them communicate via a custom 'cartUpdated' event.
Design Patterns in JavaScript
Events actually travel in three phases: capturing (top-down, from window to the target), target phase, then bubbling (bottom-up, target back to window). Listeners default to the bubbling phase; pass { capture: true } to react during the capturing phase instead.
el.addEventListener('click', handler, { capture: true }); // fires during capture (top-down)
el.addEventListener('click', handler); // fires during bubble (bottom-up), the default
Real-world example
Intercepting a click at a top-level container BEFORE it reaches a deeply nested element that might call stopPropagation().
Design Patterns in JavaScript
Call removeEventListener() with the exact same function reference and options used in addEventListener() — anonymous inline functions can't be removed this way, so store a named reference if you'll need to detach it later.
function handleClick() { console.log('clicked'); }
el.addEventListener('click', handleClick);
// later:
el.removeEventListener('click', handleClick);
Real-world example
Removing listeners in a React useEffect cleanup function or when a component/widget is destroyed.
Memory Management & Garbage Collection
What is the difference between passive and non-passive event listeners for scroll performance?
AdvancedA passive listener ({ passive: true }) tells the browser up front that it will never call preventDefault(), letting the browser start scrolling immediately without waiting for the handler to finish — significantly improving scroll smoothness for touch/wheel events.
el.addEventListener('touchstart', handleTouch, { passive: true });
Real-world example
Fixing janky scrolling on mobile caused by a touchstart/touchmove listener that doesn't actually need to block scrolling.
Performance Optimization: Debouncing
Throttling & Memoization
MutationObserver watches a target node (and optionally its subtree) for changes like added/removed children, attribute changes, or text changes, and asynchronously batches callbacks — useful for reacting to DOM mutations from third-party scripts you don't control.
const observer = new MutationObserver((mutations) => {
mutations.forEach(m => console.log(m.type, m.target));
});
observer.observe(document.body, { childList: true, subtree: true });
Real-world example
Detecting when a third-party widget injects new DOM nodes so your code can style or enhance them.
Design Patterns in JavaScript