AJAX In Action [75]
The Controller in an Ajax application
141
First, we write a constructor for the object, which in JavaScript is simply a function. (Appendix B contains a primer on the syntax of JavaScript objects. Take a look if any of the following code looks strange or confusing.)
jsEvent.EventRouter=function(el,eventType){
this.lsnrs=new Array();
this.el=el;
el.eventRouter=this;
el[eventType]=jsEvent.EventRouter.callback;
}
We define the array of listener functions, which is initially empty, take a reference to the DOM element, and give it a reference to this object, using the pattern we described in section 3.5.1. We then assign a static method of the EventRouter class, simply called callback, as the event handler. Remember that in JavaScript, the square bracket and dot notations are equivalent, which means
el.onmouseover
is the same as
el['onmouseover']
We use this to our advantage here, passing in the name of a property as an argument. This is similar to reflection in Java or the .NET languages. Let’s have a look at the callback then:
jsEvent.EventRouter.callback=function(event){
var e=event || window.event;
var router=this.eventRouter;
router.notify(e)
}
Because this is a callback, the function context is the DOM node that fired the event, not the router object. We retrieve the EventRouter reference that we had attached to the DOM node, using the backing object pattern that we saw earlier. We then call the notify() method of the router, passing the event object in as an argument.
The full code for the Event Router object is shown in listing 4.8. Listing 4.8 EventRouter.js
var jsEvent=new Array();
jsEvent.EventRouter=function(el,eventType){
this.lsnrs=new Array();
this.el=el;
el.eventRouter=this;
Licensed to jonathan zheng 142 CHAPTER 4 The page as an application el[eventType]=jsEvent.EventRouter.callback; } jsEvent.EventRouter.prototype.addListener=function(lsnr){ this.lsnrs.append(lsnr,true); } jsEvent.EventRouter.prototype.removeListener=function(lsnr){ this.lsnrs.remove(lsnr); } jsEvent.EventRouter.prototype.notify=function(e){ var lsnrs=this.lsnrs; for(var i=0;i lsnr.call(this,e); } } jsEvent.EventRouter.callback=function(event){ var e=event || window.event; var router=this.eventRouter; router.notify(e) } Note that some of the methods of the array are not standard JavaScript but have been defined by our extended array definition, which is discussed in appendix B. Notably, addListener() and removeListener() are simple to implement using the append() and remove() methods. Listener functions are invoked using the Function.call() method, whose first argument is the function context, and subsequent arguments (in this case the event) are passed through to the callee. The revised mousemat example is shown in listing 4.9. Listing 4.9 Revised mousemat.html, using EventRouter