There are 2 scripts in a document
// my_script.js goes first
document.onclick = function() {
alert("document clicked");
};
// other_script.js comes after
// this overrides the onclick of my script,
// and alert will NOT be fired
document.onclick = function() {
return false;
};
To make sure my click event does not get overridden by other script, I switched to addEventListener
.
// my_script.js goes first
document.addEventListener("click", function() {
alert("document clicked");
}, false);
// other_script.js comes after
document.addEventListener("click", function() {
return false;
}, false);
Now I got another question. Since return false
in the second code is defined after alert
, how come it does not prevent alert from being called?
What if I want my script to get total control of click event (like return false all the time disregarding events defined in other scripts)?
What if I want my script to get total control of click event (like return false all the time disregarding events defined in other scripts)?
If you can register your handler first, before they do, you can do that, provided the browser you're using correctly implements DOM3 events (which it probably does unless it's IE8 or earlier).
There are (at least) four things involved here:
Preventing the default.
Stopping propagation to ancestor elements.
Stopping other handlers on the same element from being called.
The order in which handlers are called.
In order:
This is what return false
from a DOM0 handler does. (Details: The Story on Return False.) The equivalent in DOM2 and DOM3 is preventDefault
:
document.addEventListener("click", function(e) {
e.preventDefault();
}, false);
Preventing the default may not be all that relevant to what you're doing, but since you were using return false
in your DOM0 handler, and that prevents the default, I'm including it here for completeness.
DOM0 handlers have no way to do this. DOM2 ones do, via stopPropagation
:
document.addEventListener("click", function(e) {
e.stopPropagation();
}, false);
But stopPropagation
doesn't stop other handlers on that same element getting called. From the spec:
The
stopPropagation
method is used prevent further propagation of an event during event flow. If this method is called by anyEventListener
the event will cease propagating through the tree. The event will complete dispatch to all listeners on the currentEventTarget
before event flow stops.
(My emphasis.)
Naturally, this didn't come up for DOM0, because there couldn't be other handlers for the same event on the same element. :-)
As far as I'm aware, there's no way to do this in DOM2, but DOM3 gives us stopImmediatePropagation
:
document.addEventListener("click", function(e) {
e.stopImmediatePropagation();
}, false);
Some libraries offer this feature (even on non-DOM3 systems like IE8) for handlers hooked up via the library, see below.
Again, not something that related to DOM0, because there couldn't be other handlers.
In DOM2, the specification explicitly says that the order in which the handlers attached to an element are called is not guaranteed; but DOM3 changes that, saying that handlers are called in the order in which they're registered.
First, from DOM2 Section 1.2.1:
Although all
EventListeners
on theEventTarget
are guaranteed to be triggered by any event which is received by thatEventTarget
, no specification is made as to the order in which they will receive the event with regards to the otherEventListeners
on theEventTarget
.
But this is superceded by DOM3 Section 3.1:
Next, the implementation must determine the current target's candidate event listeners. This must be the list of all event listeners that have been registered on the current target in their order of registration.
(My emphasis.)
Some libraries guarantee the order, provided you hook up the events with the library.
It's also worth noting that in Microsoft's predecessor to DOM2 (e.g., attachEvent
), it was the opposite of DOM3's order: The handlers were called in reverse order of registration.
So taking #3 and #4 together, if you can register your handler first, it will get called first, and you can use stopImmediatePropagation
to prevent other handlers getting called. Provided the browser implements DOM3 correctly.
All of this (including the fact that IE8 and earlier don't even implement DOM2 events, much less DOM3) is one reason people use libraries like jQuery, some of which do guarantee the order (as long as everything is hooking up their handlers via the library in question) and offer ways to stop even other handlers on the same element getting called. (With jQuery, for instance, the order is the order in which they were attached, and you can use stopImmediatePropagation
to stop calls to other handlers. But I'm not trying to sell jQuery here, just explaining that some libs offer more functionality than the basic DOM stuff.)