Elaine (6) [Avatar] Offline
#1
Thanks for the handy Object you define in listing 4.8. I have been able to understand and use it successfully. However, I have 3 questions:

1. Why do you make this jsEvent an Array? I changed the first line to
var jsEvent = new Object();
instead, and it works fine.

2. Why do you have the jsEvent in there at all? All the attributes and functions you attach to jsEvent, you actually attach to jsEvent.EventRouter. I would think it would be more simple to just define EventRouter and forget about jsEvent.

3. I think there is a typo on page 141, paragraph 4 sentence 2: capitalization "EventRouter" is wrong, should be:

"We retrieve the eventRouter reference that we had attached..."

Thanks,
Elaine
davecrane (149) [Avatar] Offline
#2
Re: jsEvent.EventRouter questions
Hi Elaine,

> 1. Why do you make this jsEvent an Array? I changed
> the first line to
> var jsEvent = new Object();
> instead, and it works fine.
>
Yes, an Object will do the job. In JavaScript, every Object is effectively an associative array. I must have had 'array' on my mind while I typed that line, and, as it isn't actually breaking anything, it didn't get picked up until now.

> 2. Why do you have the jsEvent in there at all? All
> the attributes and functions you attach to jsEvent,
> you actually attach to jsEvent.EventRouter. I would
> think it would be more simple to just define
> EventRouter and forget about jsEvent.
>
I was having a rigorous day as far as namespacing went. Think of jsEvent as being like a package name (I'm showing my Java developer roots here) - if I'd developed any other event helpers, I could group them in there too, but as it turned out, I didn't. So yes, we could dispense with the jsEvent namespace.

> 3. I think there is a typo on page 141, paragraph 4
> sentence 2: capitalization "EventRouter" is wrong,
> should be:
>
> "We retrieve the eventRouter reference that we had
> attached..."
>
Well spotted!
Elaine (6) [Avatar] Offline
#3
Re: jsEvent.EventRouter questions
I am respectfully submitting an improved version of EventRouter. I simplified the code by taking out the Array and namespace, and Lawrence Ching modified it to work for IE also:

/*
event router object for robust cross-browser implementation of Observer pattern
for the 'classic' javascript event model (the newer addEventListener() and attachEvent()
does a similar job, but is somewhat flaky - see Quirskmode for a discussion [http://www.quirksmode.org/js/events_advanced.html].

requires extras-array.js

Dave Crane 2005
*/

/* namespacing object */
var EventRouter=new Object();

/*
constructor function, specifying DOM element (or other object) to listen to,
and event type, which should be a valid browser event e.g. 'onmouseover' 'onclick' for DOM
elements
*/
EventRouter=function(el,eventType){
this.lsnrs=new Array();
this.el=el;
el.eventRouter=this;
el[eventType]=EventRouter.callback;
}

/*
convenience method for adding a listener
*/
EventRouter.prototype.addListener=function(lsnr){
this.lsnrs.append(lsnr,true);
}

/*
convenience method for removing a listener
*/
EventRouter.prototype.removeListener=function(lsnr){
this.lsnrs.remove(lsnr);
}


/* notify all listeners of an event - this is called by the callback, don't need
to invoke it yourself for DOM nodes, but if using bespoke events it is the
easiest way in */
EventRouter.prototype.notify=function(e){
var lsnrs=this.lsnrs;
for(var i=0;i<lsnrs.length;i++){ >
var lsnr=lsnrs[i];
lsnr.call(this,e);
}
}


//jsEvent.EventRouter.callback=function(anevent){
// Modified by Lawrence Ching per suggestions at
// http://developer.apple.com/internet/webcontent/eventmodels.html

function getTargetElement(evt) {
// Identifies element that created the event. Source:
// http://developer.apple.com/internet/webcontent/eventmodels.html
var elem
if (evt.target) {
elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target
} else {
elem = evt.srcElement // For Internet Explorer, which doesn't recognize window.event.target
}
return elem

}

EventRouter.callback=function(evt) {
// This version works on IE 7 on Windows XP, as well as Firefox on
// Mac and PC, and Safari on Mac. Based on suggestions at
// http://developer.apple.com/internet/webcontent/eventmodels.html
evt = (evt) ? evt : ((window.event) ? window.event : "")
if (evt) {
var elem = getTargetElement(evt)
if (elem == this.eventRouter.el) {
this.eventRouter.notify(evt);
}
}
}