Capturing Phase
The capturing phase is the first phase of event propagation, where the event travels from the window down to the target element.
How Capturing Works
<div id="a">
<div id="b">
<div id="c">Click me</div>
</div>
</div>
<script>
// Capturing listeners (third arg = true)
document.getElementById('a').addEventListener('click', () => {
console.log('A capturing');
}, true);
document.getElementById('b').addEventListener('click', () => {
console.log('B capturing');
}, true);
// Bubble listener (third arg = false)
document.getElementById('c').addEventListener('click', () => {
console.log('C'); // Target phase
});
// Bubbling listeners
document.getElementById('a').addEventListener('click', () => {
console.log('A bubbling');
});
document.getElementById('b').addEventListener('click', () => {
console.log('B bubbling');
});
</script>
Output:
A capturing
B capturing
C
B bubbling
A bubbling
Visual Flow
Window (capturing starts)
↓
Document
↓
HTML
↓
Body
↓
Div A (capturing)
↓
Div B (capturing)
↓
Div C (target)
↑
Div B (bubbling)
↑
Div A (bubbling)
↑
Body
↑
Document
Window
addEventListener Options
The addEventListener method accepts options to control its behavior.
Third Argument (Legacy)
// Bubble phase (default)
element.addEventListener('click', handler, false);
element.addEventListener('click', handler); // Same as above
// Capture phase
element.addEventListener('click', handler, true);
Options Object (Modern)
element.addEventListener('click', handler, {
capture: true, // Listen in capturing phase
once: true, // Remove after first call
passive: true, // Never calls preventDefault()
signal: controller.signal // AbortController signal
});
Practical Options Examples
// Once - auto-remove after first trigger
element.addEventListener('click', () => {
console.log('Clicked once!');
}, { once: true });
// Passive - for scroll performance (can't prevent default)
document.addEventListener('touchmove', (e) => {
console.log('Scrolling...');
// e.preventDefault() would log warning
}, { passive: true });
// Signal - abort controller integration
const controller = new AbortController();
element.addEventListener('click', handler, {
signal: controller.signal
});
// Later: controller.abort(); // Removes listener
Checking Listener Options
// Not directly possible to check existing listener options
// But you can manage listeners manually
function addManagedListener(element, type, handler, options) {
element.addEventListener(type, handler, options);
return () => {
element.removeEventListener(type, handler, options);
};
}
// Usage
const removeListener = addManagedListener(
element, 'click', handler, { capture: true }
);
// Later: removeListener();
When to Use Capturing
Capturing is less commonly used than bubbling, but has specific use cases.
Use Cases for Capturing
1. Intercepting Events Early
// Global click tracking - capture ALL clicks
document.addEventListener('click', (e) => {
trackClick(e.target, e.clientX, e.clientY);
}, true); // Capture phase ensures we see it first
2. Preventing Event Handling
// Disable all clicks in a section during loading
document.getElementById('content').addEventListener('click', (e) => {
e.stopPropagation();
e.preventDefault();
}, true); // Capture phase blocks before handlers run
3. Event Delegation with Capture
// Handle clicks on dynamic content
document.addEventListener('click', (e) => {
const button = e.target.closest('.dynamic-button');
if (button) {
handleButtonClick(button);
}
}, true); // Capture ensures we catch it early
4. Debugging
// Log all events for debugging
document.addEventListener('click', (e) => {
console.log('Click captured at:', e.target);
}, true);
When NOT to Use Capturing
- Most UI interactions (use bubbling)
- When you want child handlers to run first
- When you need stopPropagation to work from child to parent
Decision Guide
Need to intercept before child handlers? → Capturing
Need to track all events globally? → Capturing
Need default child behavior? → Bubbling
Practice Problems
Create a reusable React component implementing Event Capturing. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Event Capturing using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Event Capturing for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. In which phase does capturing happen?
2. How do you enable capturing in addEventListener?
3. Why use capturing over bubbling?
4. What does the { once: true } option do?
Flashcards
Question
What is the capturing phase?
Click to reveal answer
Answer
The first phase of event propagation where the event travels from window down to the target element.
Question
How to enable capturing?
Click to reveal answer
Answer
Pass true as third argument to addEventListener: element.addEventListener('click', handler, true)
Question
When should you use capturing?
Click to reveal answer
Answer
When you need to intercept events before they reach the target or before child handlers run.
Question
What is the { once: true } option?
Click to reveal answer
Answer
Automatically removes the event listener after it's called once.
Question
What is Event Capturing?
Click to reveal answer
Answer
Event Capturing is a key concept in frontend development.
Revision Notes
Key Takeaways
- 1.Capturing is the first phase of event propagation
- 2.Events travel from window down to target during capturing
- 3.Use true as third argument to enable capturing
- 4.Capturing is useful for intercepting events early
- 5.Most UI code uses bubbling, not capturing
Interview Tips
- •Explain the three phases of event propagation
- •Show how to add a capturing phase listener
- •Discuss when to use capturing vs bubbling
- •Explain practical use cases for capturing
Cheat Sheet
Event Capturing Cheat Sheet
What is it?
First phase of event propagation. Event travels from window down to target.
Enabling Capturing
// Third argument
addEventListener('click', handler, true);
// Options object
addEventListener('click', handler, { capture: true });
Event Flow Order
- Capturing (window → target)
- Target
- Bubbling (target → window)
Use Cases
- Global event tracking
- Intercepting before child handlers
- Debugging event flow
Options
capture: Listen in capturing phaseonce: Auto-remove after first callpassive: Can't call preventDefault()