event = addEvent(
addEvent
doesn't return anything; you're assigning the undefined
lack-of-return-value to a global variable event
(since you've not said var event
in the function). This will cause an exception in IE, which uses the global event
as a special object to pass event details to handlers, and consequently doesn't allow you to assign something else to it.
if (typeof obj.addEventListener != undefined)
typeof
always returns a string, which will never test equal to the undefined
unvalue, so IE will always take the non-IE fork and fail. You meant if (typeof obj.addEventListener !== 'undefined')
, with a string.
obj.detachEvent("on" + type, obj[type + fn]);
Since you've not written a property with the name of type
and fn
stuck together in the addEvent
function, this will fail to retrieve anything.
As Crescent says, it looks like you're using Resig's removeEvent
function, paired with a different addEvent
that doesn't match. If you use his removeEvent
you will need to use his addEvent
to go with it.
However, I wouldn't use these functions anyway: they're pretty dodgy. I know it was 2005 when this ill-conceived code ‘won’ quirksmode's addEvent contest, but even then we should have known a lot better. The problem is it creates a string from the event name and the textual serialisation of the function code (type+fn
), and uses it as a key to store a callback. This key will look something like 'mouseoverfunction changeText() {...code...}'
.
But relying on function serialisation is a terrible idea. The format is not standardised by ECMAScript (“An implementation-dependent representation of the function is returned.”); there are many browser quirks; and not least, two different functions can easily return the same string for browsers' current serialisation methods:
var f1= function() {};
var f2= function() {};
f1
and f2
will have the same string serialisation, but they're not the same object. If you did an addEvent
for f1
on IE, and then another one for f2
, the second property would use the same serialised string and overwrite the first property. Then calling removeEvent
for f1
would retrieve the function for f2
, try to detachEvent
it and fail because it's not the same function. This example may look contrived, but it's actually extremely easy to do accidentally when you're using generic closures, as modern JavaScript does more and more these days. For this reason I'd recommend avoiding Resig's addEvent
in all circumstances.
(jQuery users: don't worry, for all its problems jQuery does not fall into the trap of using this code.)
This hack is there to preserve the this
value when your changeText
function is called back by IE, whose attachEvent
doesn't set this
. But you don't even use the this
value, so you could have got away with a much simpler version, such as the original addEvent it was created to replace.
At least the shortcomings of that addEvent are well-known and show up immediately when you test on IE using this
, instead of only going wrong in a particular case that, when it affects you, is likely to be extremely confusing and hard to debug.
Then again, you aren't currently using even multiple listeners for the same event, so you could easily get away with a old-fashioned DOM Level 0 event handler, something like:
window.onload= function() {
var changed= false;
document.getElementById('contactButton').onmouseover= function() {
if (!changed) {
alert('changing text');
}
changed= true;
};
};