An important feature of using a listener object is that the function value of it’s handleEvent property is only looked up when the event is fired. This means that if the function value of the handleEvent property changes between events then it is always the current value of the handleEvent property that is called. This is late binding. For example,

Cross-Browser Libraries

Our cross-browser applications should not be cluttered with repetitive code to work with the different APIs provided by the different browsers, so we’ve abstracted the different APIs away in event libraries. This has been a very good choice.

Different libraries have different APIs but every library has something like the following.

The JavaScript this Wrinkle

A common problem with these library abstractions is when we want a method of an view object to be called when the event is fired. For example, in the following code, the value of this in the handleClick method is the global window object. The alert will show undefined when we may have expected to see the alert show "alpha".

The workaround the libraries have given us (so that we can also still easily remove event listeners) is to specify the object we want as this when the handler is called as an extra argument to the event library function. For example, the alert in this example will show "alpha".

One problem with this API is that the listener function is bound when LIB_addEventListener is called. This causes trouble when the function value of handleClick is changed and then also when an attempt is made to remove the listener.

var vo = new ViewObject();
// click on the body and see alert "alpha"
vo.handleClick = function() {
alert('beta');
};
// click on the body and still see "alpha"
vo.destroy();
// click on the body and still see "alpha"!

Another problem is that we are writing the program in an object-oriented style but we are focusing on listener functions rather than listener objects. This mismatch is a clue to find a better solution.

A Library API for Listener Objects

Since we are frequently writing our programs in an object-oriented style, it makes sense to write LIB_addEventListener so that it can accept listener objects (as well as listener functions.)