1

Is there a way to have a global event capture so that if an element has a click event, and stopPropagation is used, the global event capture still fires and runs its own code.

The global event capture is for a jquery plugin that knows nothing about any other jquery/javascript on the page.

Thank you.

1 Answers1

0

This method will not be possible if a similar listener has been added to document before your code has had a chance to run, and that listener calls stopImmediatePropagation, but luckily, such things are quite rare.

All you need to do is add a click listener to document in the capturing phase, so that your listener runs as soon as it possibly can (it will run before any bubbling listeners fire, and will run before any capturing listeners, except capturing listeners on document):

document.addEventListener(
  'click',
  () => {
    console.log('global click detected');
  },
  true // <-- very important: trigger listener in capturing phase
);

document.querySelector('#foo').addEventListener('click', (e) => {
  e.stopPropagation();
  console.log('foo clicked, stopPropagation called');
});
<div id="foo">click</div>

Example snippet where the "global click detected" wouldn't work, due to a capturing listener on document that calls stopImmediatePropagation:

document.addEventListener(
  'click',
  (e) => {
    e.stopImmediatePropagation();
    e.stopPropagation();
  },
  true
);

// cannot intercept click now, due to stopImmediatePropagation
document.addEventListener(
  'click',
  () => {
    console.log('global click detected');
  },
  true
);
<div id="foo">click</div>

Note that adding listeners in the capturing phase cannot be done with jQuery - have to use standard Javascript for that.

This sort of technique is very handy for intercepting events when you can't control other code on the page.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320