sajad torkamani

In a nutshell

Event capture is like event bubbling but the order is reversed. Instead of the events firing first on the most nested element targeted, and then bubbling up to parent elements, the event fires first on the outermost element, and then successively on nested elements.

Event capturing is disabled by default but you can enable it by passing the capture option to Event.addEventListener():

someEl.addEventListener('click', handleClick, { capture: true })

So if you have this HTML:

<main>
  <section>
    <button>Click me</button>
  </section>
</main>

And this JavaScript:

const mainEl = document.querySelector('main')
const sectionEl = document.querySelector('section')
const buttonEl = document.querySelector('button')
const outputEl = document.querySelector('#output')

mainEl.addEventListener('click', handleClick, { capture: true })
sectionEl.addEventListener('click', handleClick, { capture: true })
buttonEl.addEventListener('click', handleClick)

function handleClick(event) {
  outputEl.innerHTML += `You clicked on a ${event.currentTarget.tagName}<br>`
}

Then clicking on <button> will:

  • Trigger the click handler for <main> first.
  • Followed by the click handler for <section>.
  • Followed the click handler for <button>.
Event capture

If you didn’t pass the { capture: true } option to enable event capturing, the order above would be reversed so that a click on <button> would:

  • Trigger the click handler for <button> first.
  • Followed by the click handler for <section>.
  • Followed by the click handler for <main>.

See CodeSandbox for example.

Sources / related

Tagged: JavaScript