I prepared a little example of the various event registration models, event properties and event orders. Thus you can get a quick overview of the possibilities and restrictions of event handling.
On this page I explain the two advanced event registration models: W3C’s and Microsoft’s. Since neither is cross–browser supported, their use is, for the moment, deprecated.
W3C and Microsoft have both developed their own event registration model to replace Netscape’s traditional model. Though I’m not impressed by the Microsoft model, W3C’s is very good, except for one crucial vagueness. Unfortunately few browsers support it at the moment.
W3C’s DOM Level 2 Event specification pays careful attention to the problems of the traditional model. It offers a simple way to register as many event handlers as you like for the same event on one element.
The key to the W3C event registration model is the method addEventListener()
. You give it three
arguments: the event type, the function to be executed and a boolean
(true
or false
) that I’ll explain later on.
To register our well known doSomething()
function to the onclick
of an element you do:
element.addEventListener('click',doSomething,false)
The beauty of this model is that we can add as many event listeners as we want to the element. If we take our example modules from the traditional model page, we’d register them both as follows:
element.addEventListener('click',startDragDrop,false) element.addEventListener('click',spyOnUser,false)
and both event handlers fire when the user clicks on the element. Please note that the W3C
model does not state which event handler is fired first, so you cannot assume startDragDrop()
is executed before spyOnUser()
.
To remove an event handler, use the removeEventListener()
method. You can choose which
handler to remove, so
element.removeEventListener('click',spyOnUser,false)
removes the second event handler but leaves the first one untouched. Beautiful functionality, and it exactly solves the problem with the traditional model we noted before.
You can also use anonymous functions in the W3C model:
element.addEventListener('click',function () { this.style.backgroundColor = '#cc0000' },false)
As to the true
or false
that is the last argument of addEventListener
,
it is meant to state whether the event handler should be executed
in the capturing or in the bubbling phase.
If you’re not certain whether you want capturing or bubbling, use false
(bubbling).
In JavaScript the this
keyword always refers to the “owner” of
a function. In the case of event handlers it is very useful if this
refers to
the HTML element the event is handled by, so that you have easy access to it.
Unfortunately the this
keyword, though very powerful, is hard to use if you don’t know
exactly how it works. I discuss its use on
another page.
In the W3C model it works the same as in the traditional model: it refers to the HTML element currently handling the event.
element.addEventListener('click',doSomething,false); another_element.addEventListener('click',doSomething,false); function doSomething() { this.style.backgroundColor = '#cc0000'; }
If you register doSomething()
als the click
event handler of any HTML element,
that element gets a red background whenever the user clicks on it.
One problem of the current implementation of W3C’s event registration model is that you can’t find out if any event handlers are already registered to an element. In the traditional model you could do:
alert(element.onclick)
and you see the function that’s registered to it, or undefined
if nothing is registered.
Only in its very recent
DOM Level 3 Events W3C adds an eventListenerList
to store a list of event handlers
that are currently registered on an element. This functionality is not yet supported by any
browser, it’s too new. However, the problem has been addressed.
Fortunately removeEventListener()
doesn’t give any errors if the event listener you want to
remove has not been added to the element, so when in doubt you can always use removeEventListener()
.
At the moment of writing (4/02) the W3C event model is only supported by the Mozilla browser family and by Konqueror. So browser support is a large problem at the moment. Therefore I cannot — yet — in good faith advise you to use it, although it is by far the best overall event model.
For more information about the W3C model, see David Eisenberg’s DOM Design Tricks 2 article on ALA.
Microsoft, too, has developed its own event registration model. It looks similar to W3C’s, but has some important drawbacks.
To register an event handler, attach
it to the element:
element.attachEvent('onclick',doSomething)
or, if you need two event handlers:
element.attachEvent('onclick',startDragDrop) element.attachEvent('onclick',spyOnUser)
Removing one is simple, too:
element.detachEvent('onclick',spyOnUser)
When compared to the W3C model, the Microsoft model has two important drawbacks:
this
keyword
always refers to the window and is completely useless.The result of these two weaknesses is that when an event bubbles up it is impossible to know which HTML element currently handles the event. I explain this problem more fully on the Event order page.
Since the Microsoft event adding model is only supported by Explorer 5 and higher on Windows, it cannot be used for cross–browser scripts. But even for Explorer–on–Windows only applications it’s best not to use it, since the bubbling problem can be quite nasty in complex applications.
If you wish to go through all event pages in order, you should now continue with the Event accessing page.