Advanced event registration models

See section 7C of the book.

The W3C model is supported by Mozilla, Safari, Konqueror, and iCab.

The Microsoft model is supported by Explorer 5+ on Windows.

Opera supports both models.

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

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.

Anonymous functions

You can also use anonymous functions in the W3C model:

element.addEventListener('click',function () {
	this.style.backgroundColor = '#cc0000'
},false)

true or 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).

this

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() as the click event handler of any HTML element, that element gets a red background whenever the user clicks on it.

Which event handlers are registered?

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().

Microsoft

Microsoft, too, has developed an 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)

Drawbacks

When compared to the W3C model, the Microsoft model has two important drawbacks:

  1. Events always bubble, no capturing possibility.
  2. The event handling function is referenced, not copied, so the 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.

Continue

If you wish to go through all event pages in order, you should now continue with the Event accessing page.