views:

2268

answers:

2

Before I get into the details of this problem, I'd like to make the situation clear. Our web analytics company works as a consultant for large sites, and (other than adding a single SCRIPT tag) we have no control over the pages themselves.

Our existing script installs handlers using "old" way (a fancy version of element.onclick = blah; that also executes the original handler) which is completely unaware of "new" (addEventListener or attachEvent) handlers on the page. We'd like to fix this to make our script able to run on more sites without requiring as much custom development.

The initial thought here was to have our own script use addEventListener/attachEvent, but this presents a problem: of the client's site sets a handler using the "old" way, it would wipe out the handler we installed the "new" way. Quick and dirty testing shows this happens in both IE7 and FF3, although I didn't test the whole range of browsers. There's also a risk that if we use the "new" way after the page's event handlers are already set, we could erase their handlers.

So my question is: what safe technique can I use to add an event handler in Javascript using addEventListener/attachEvent that works regardless of how other event handlers on the page are installed?

Please remember: we have no way of modifying the site that our script is installed on. (I have to emphasize that because the default answer to questions like this is always, "just rewrite the page to do everything the same way.")

+1  A: 

addEventListener/attachEvent is safe in a sense you ask. They add a new event handler to a Node without altering any handlers previously added to it (even once assigned through a property onxxx). For a company that bring some to a foreign page using addEventListener/attachEvent must be the only practice. Assigning onxxx handler via properties indeed would break hosting pages scipts (that have been previously assigned the same way)

Sergey Ilinsky
Yes, but the problem here is that if the page then uses element.onclick=""; after we've used addEventListener, it'll erase our listener.Our existing way of installing handlers works with element.onclick="" because we save the previous contents of the handler and 'simulate' it when ours triggers.
blakeyrat
read my text again - just corrected. element.onclick will indeed not erase your handlers added with addEventListener/attachEvent Also: "simulating" events is one of the worse evils, please do not do that.
Sergey Ilinsky
Re: Simulating events, you have to remember that this is quite an "old" (in Internet terms) product, and there was simply no other way to do it that was compatible with IE 5 and 5.5.
blakeyrat
I bet there is almost no functional difference between IE5, IE5.5 and IE6 (indeed, in newer versions new features added, like CSS expressions or HTC etc)
Sergey Ilinsky
+2  A: 

Can you try your quick-and-dirty testing again? This doesn't happen for me in FF3.

elem.onclick = function() { alert("foo"); };
elem.addEventListener("click", function() { alert("bar"); }, false);

Both handlers fire for me when I click on the element.

I'm guessing you forgot the final boolean argument in addEventListener (whether to use the capture phase). I'm also guessing you forgot that IE's attachEvent needs onclick, not click.

savetheclocktower
And this is not a problem in IE or any other browsers, because if the behavior "guessed" by the person who asks was in reality, this would lead to sever problems for any client-side code
Sergey Ilinsky
Argh, you appear to be right. Apologies for the question, obviously the fault was a crappy test-case and not any specific bugs in the browser. (At least IE7 and FF3.) Thanks for pointing me in the right direction.
blakeyrat