[snip]
else if (obj.attachEvent)
obj.attachEvent('on' + evt, handler);
else
{
var old_handler = obj['on' + evt];
if (null == old_handler)
obj['on' + evt] = handler;
else obj['on' + evt] = function()
{
old_handler();
handler();
}
}
Whilst simple and functional, it does have a problem. The three methods
(two, above) produce a varying, and sometimes deficient, environment for
the listeners.
A conforming implementation of addEventListener will result in two things:
1) Each listener will be passed an event object as its only argument.
2) The this operator will refer to the current target of the event.
This, I think you'll agree, is a nice situation as it replicates what
you'll find if you add your listeners directly with HTML.
IE's attachEvent does neither, and the only way to make it is to add a
function on every call which, itself, calls the listener providing the
missing information. It's not a nice solution, so I tend to avoid
attachEvent altogether.
Your on<event> solution adds uncertainty. On an initial call where the
first branch is taken, listeners will experience something close to what
they would find with addEventListener (except with IE, where the event
object would still be global). However on subsequent calls, this no longer
happens and the situation becomes much like it would with attachEvent.
The quickest fix is:
var old_handler = obj['on' + evt];
if (null == old_handler)
obj['on' + evt] = handler;
else obj['on' + evt] = function(e)
{
old_handler.call(this, e);
handler.call(this, e);
};
It doesn't guarantee that the listener will be passed an event object, but
at least the this operator will be reliable.
Another improvement would be to perform the concatenation of the 'on'
prefix only once:
if(obj.addEventListener) {
/* ... */
} else {
evt = 'on' + evt;
/* ... */
}
as string operations are relatively expensive.
[snip]
R. Cornford has a smashing example of multiple assignment, somewhat over
my head (short trip).
Mind pointing to it (message id or subject)?
Mike