The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

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);
}
}
}