The simple answer is, add a third argument, true
, when adding your event listener.
document.addEventListener('click', someFunction, true)
This flag (called useCapture
) will call someFunction
on all clicks in a document, even when the user clicked inside an element with a click handler that called event.stopPropagation
.
With options
If you're already passing an object of options as the third argument, simply include capture: true
in them:
document.addEventListener('click', someFunction, { capture: true, ...someMoreOptions })
Why?
Enabling the handler's useCapture
mode like this means the listener listens during the earlier "capture" phase of the event (which starts at the outmost element then trickles down through children), instead of the later "bubble" phase (which starts at the innermost element and bubbles back up through ancestors, and is the one stopPropagation
blocks).
Side effects
That also means that applying this setting changes the timing: your capture phase click event will occur before any click events of either type inside child or descendant elements.
For example, in the above function, if a user clicks on a button on the page, the someFunction
attached to the document
's capture phase will be called before any handlers attached to the button; whereas without setting use capture to true, you'd expect it to be called after.
stopPropagation
should have no effect. See this question for a deeper explanation. – Eislerdocument.addEventListener('click', function(e) {console.log(e);}, true);
– Agrimony