addEvent() recoding contest

My recent entry addEvent() considered harmful generated many interesting comments and technical pointers. It's clear that the original addEvent() function doesn't quite cut the cake any more, and it's equally clear that we badly need a function such as this to keep our scripts simple.

Hence I'd like to take the opportunity to launch an addEvent() recoding contest. Write your own version of addEvent() and removeEvent(), submit it by adding a comment to this page, and win JavaScript fame.

Entries will be judged by a panel consisting of Scott Andrew LePera, Dean Edwards and myself on script quality, simplicity and portability, and the clarity of your explanation.

The prize will consist of eternal and undying fame. Scott, Dean and I will do everything in our power to spread the winning entry as the new standard addEvent() script. Your script might be used by a new generation of web developers, and your name could become a household name.

The contest

Create your entry as follows:

  1. Download the contest page.
  2. Write your own addEvent() and removeEvent() functions that obey the guidelines below. Add an English explanation of your script.
  3. Add your name and your email address to the page, and put it somewhere on a web server.
  4. Add a comment with a link to your entry. You have now officially entered your script.
  5. Comments to this page (and thus entries) will be closed on 22 September.


Any entry to the contest must obey the following guidelines:

  1. Your entry should exhibit the same behaviour as this example page, which uses Scott Andrew's old functions. The example page doesn't work in Explorer, but your entry should. The mouseout functions on the example page don't work perfectly, but for the contest that doesn't matter.
  2. You are only allowed to change the functions addEvent() and removeEvent(). You may not change the rest of the JavaScript.
  3. Your entry must work in Explorer 5+ Windows, Mozilla, Opera, and Safari.
  4. Your functions should be as short and simple as possible.
  5. Your entry page must contain a simple, readable explanation of your scripts. Remember that you're writing the new standard script: future generations of web developers must be able to understand it.
  6. Note that the event handling functions extensively use the this keyword. Making sure that it works in Explorer Windows is a major part of the contest.
  7. Note that the contest page sets two mouseover and two mouseout event handlers on every <li>, one pair for the foldout/in, and one pair for setting and removing the borders. Your functions must therefore be able to set several event handlers for the same event on the same element.
  8. Note that the contest page contains a link that removes the border change functions. removeEvent() must be able to remove one event handler but leave the other one one intact.
  9. You are allowed to add style to your entry page.

Comment policy

In this entry I allow only comments that link to an entry for the contest. All other comments will be removed.

This is the blog of Peter-Paul Koch, web developer, consultant, and trainer. You can also follow him on Twitter or Mastodon.
Atom RSS

If you like this blog, why not donate a little bit of money to help me pay my bills?



Comments are closed.

1 Posted by Gellért Gyuris on 8 September 2005 | Permalink

2 Posted by Carlos R. L. Rodrigues on 8 September 2005 | Permalink

3 Posted by John Resig on 8 September 2005 | Permalink

My submission into the contest can be found here:

I've provided detailed information concerning the 'sticky' parts of the code along with links to more detailed information concerning Javascript Events, in general.

4 Posted by Peter Siewert on 8 September 2005 | Permalink

If this is too similar to #2 then I'll let him win.

5 Posted by Mike Howard on 9 September 2005 | Permalink

I think that John Resig's entry is hard to beat. All I've done is add to it really.

6 Posted by Daniel Rucareanu on 9 September 2005 | Permalink

7 Posted by Tino Zijdel on 9 September 2005 | Permalink

My entry:

8 Posted by Jonas Galvez on 9 September 2005 | Permalink

9 Posted by Lachlan Hunt on 9 September 2005 | Permalink

For this entry, rather than implementing most of the functionality in the attachEvent and removeEvent functions, this implements much of the DOM2 Events interfaces including, among other things, .addEventListener() and .removeEventListener() for both the document object and Element interface. Works in Firefox, Opera and IE6. Unfortunately, I could only test on Windows, though, it should work in any standards compliant browser compliant browser.

10 Posted by Kelly on 10 September 2005 | Permalink

My entry:

Similar to John Resig 's but it also fixes the IE memory leaks exhibited by most of the other submissions. Thanks to Joe for hosting the file - if you play FF, sign up!

11 Posted by David Flanagan on 10 September 2005 | Permalink

My entry isn't done yet.

PPK: before deleteing this comment would you clarify something?

From your guidelines, I gather that you only expect entries to follow the original addEvent/removeEvent API to the extent necessary to make the example code work. Is this correct?

For example, addEvent() and removeEvent() return a boolean value which seems to be vestigal, and I plan to eliminate the return value in my entry. The example code will work, but my entry won't be a perfect drop-in replacement for the original functions. Do your rules allow this?

12 Posted by ppk on 10 September 2005 | Permalink

Yes, that's allowed. I never understood the boolean return value in the first place, and the other scripts on the page don't use it.

13 Posted by Cris Perdue on 10 September 2005 | Permalink

This implementation is very platform-neutral and avoids hashing
on a string containing the function's source code. That will not work
if different instances of the same closure are used as handlers.

14 Posted by Angus Turnbull on 10 September 2005 | Permalink

I'll enter my AddEvent Manager script; here's the main demo and download page:

I've posted PPK's demo page in my testing area:

It's quite a lot more complicated than some other entries, but it plugs MSIE memory leaks, interoperates with other event-capturing scripts, and also works perfectly in IE5/Mac. See the main project demo page for details!

15 Posted by James Newton-King on 10 September 2005 | Permalink

I've left in meaningful variable names for readability but it could be easily be compressed down in size. Tested in IE5, IE6, Mozilla and Opera.

16 Posted by Mark Wubben on 11 September 2005 | Permalink

I have no idea why I'm posting this at 3:45 am, but I finally finished writing the article explaining all the code, and it's live at

Tested in IE5, IE6, Mozilla, Safari and Opera.

And now I need sleep.

17 Posted by Kelly on 12 September 2005 | Permalink

Looks like Joe changed something on his server. New URL:

18 Posted by Steve Joynt on 12 September 2005 | Permalink

I coded this up before looking at any of the other entries. It's pretty messy.

19 Posted by Peter Nederlof on 12 September 2005 | Permalink

Closures and circular references don't necessarily cause memory leaks; it's more a matter of cleaning up the mess you leave behind. There are enough articles out there about where leaks originate from, and what to do about them. And who's responsibility is it anyway? Why shouldn't we use a prefectly suited solution for a problem, just because the app leaks a bit of memory.

Since I'm violating guideline 1 and 2 with the following link, I guess I'm not competing :) The code, however, passes guideline 3 and 4, and clearly illustrates that the event fuctions and closures and circular references don't matter one bit in memory leakage if you clean them up onunload. And if you familiarize yourself a bit with the way scope works in javascript, it's basically a walk in the park to attach events in any way and any scope you see fit.

the link (see the source):

20 Posted by David Flanagan on 13 September 2005 | Permalink

My entry code (along with extensive documentation in comments) is at

The test case is at

My code uses closures to invoke the handler as a method of the document element, and then registers an onunload handler to clean up and prevent memory leaks. I also prevent duplicate registration of functions with attachEvent, and pass an event object to the handler function that simulates a w3c-standard event object.

21 Posted by Michaël Guitton on 13 September 2005 | Permalink

A clunky DOM0-based solution. So far it's the only one I tested that really works in IE5/Mac.

Unfortunately I had to tweak some of the *DON'T TOUCH* handlers because they did not work in IE5/Mac (!) I guess I'm not competing but who knows?

Sorry but I'm really short on time (please see embedded comments for further details)

22 Posted by David Smith on 14 September 2005 | Permalink

Awesome entries! Some of the scripting knowledge and complexity has blown me away. And helped with this entry which works as follows:

If the browser cannot use the W3C event registration model events are registered using traditional event registration.

23 Posted by Joshua Richardson on 15 September 2005 | Permalink

24 Posted by Jason Davis on 19 September 2005 | Permalink

My last comment apparently never submitted, so here it is again:

Works everywhere that apply() does. Doesn't use any W3C DOM event or IE event interfaces. Events may be cancelled by returning false in the listener. Makes use of the JS Scope (proper use of which would have made the previous critique of addEvent() moot - if you can do bla.attachEvent(), then as long as the listener is created in the same scope, it can also access `bla`. e.g. bla.attachEvent("onclick", function() { alert(bla.tagName) }).

25 Posted by Pachunka on 20 September 2005 | Permalink

Could use some work, especially in that in doesn't use onpagehide at all in its memory cleanup, but it is what it is, given the time I had to work on it.

My apologies if this is drasticly similar to anything already up- I haven't had a chance to look.

'night. :)

26 Posted by Ismael Jurado on 20 September 2005 | Permalink

Short, simple, and compatible across browsers.

27 Posted by Jeffery To on 21 September 2005 | Permalink

I sure hope I win eternal and undying fame. It's been on my Christmas list since forever.

28 Posted by Ric Hossenfus on 21 September 2005 | Permalink

Unlike many of the entries, works in IE5 on a Mac (I thought that was one of the reasons for doing this). Similar to a few previous entries, but a bit simpler.

29 Posted by James Mc Parlane on 21 September 2005 | Permalink

Here is my entry.

Its not the smallest or simplest, but this was a project that I started before the contest was announced and its main purpose is to solve a much larger problem. Read the full blog entry if you want to get the whole story.

30 Posted by Rob Tannert on 21 September 2005 | Permalink

I was interested to see how hard it would be to merge the functions specified for the contest into a scheme I had developed to enable JavaScript objects to listen for events raised by other objects. It turned out to be fairly straightforward but pushes the bounds of the contest, since the entry's intent is to convert DOM event handling into generic JavaScript-object event handling, not to facilitate DOM event handling per se. I present it as a curiosity rather than a serious entry:

Note to the winner: These functions will be superfluous in a couple of years (let's hope). Remember that all glory is fleeting!

31 Posted by Masayuki AOKI on 22 September 2005 | Permalink

Check this. It's simple but enough. Behaves as modern browsers like firefox.

32 Posted by Cris Perdue on 22 September 2005 | Permalink

Here is Mark II of my entry, with better description and
extended to help prevent memory leaks:

(Slightly off-topic?) I hope a discussion of including
objects as event handlers might be possible as well.

33 Posted by ppk on 23 September 2005 | Permalink

Entries for the contest are closed. The judges will start working now. I'll post a new entry as soon as anything has been decided.