Skip to content
intermediatePhase 33 · Advanced JavaScript

Event Capturing

Learn the capture phase of event propagation and when to use it.

30m
0 problems
Topic Progress0%

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

0/3solved
Build Event Capturing Component

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 needed
Event Capturing Testing

Write 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 tests
Event Capturing Performance

Optimize 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 analysis

Quiz

1. In which phase does capturing happen?

Question 1 options

2. How do you enable capturing in addEventListener?

Question 2 options

3. Why use capturing over bubbling?

Question 3 options

4. What does the { once: true } option do?

Question 4 options

Flashcards

Question

What is the capturing phase?

Answer

The first phase of event propagation where the event travels from window down to the target element.

Question

How to enable capturing?

Answer

Pass true as third argument to addEventListener: element.addEventListener('click', handler, true)

Question

When should you use capturing?

Answer

When you need to intercept events before they reach the target or before child handlers run.

Question

What is the { once: true } option?

Answer

Automatically removes the event listener after it's called once.

Question

What is Event Capturing?

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

  1. Capturing (window → target)
  2. Target
  3. Bubbling (target → window)

Use Cases

  • Global event tracking
  • Intercepting before child handlers
  • Debugging event flow

Options

  • capture: Listen in capturing phase
  • once: Auto-remove after first call
  • passive: Can't call preventDefault()