<<< back

Explanation of addEvent and removeEvent

This is the explanation page for the addEvent and removeEvent functions designed by Aaron Moore. On this page I will attempt to describe:

  1. The functionality provided.
  2. The tools they use.
  3. How the functions work.
After this I will do a comparison between this method and it's alternative, the W3C and IE functions which come built into various browsers.

The Functionality

Here are the features that my event registration method provides:

  1. Multiple handlers. The method supports the assignment and removal of as many handlers as you like to a single listener.
  2. This. Inside any handlers which use my method, the 'this' keyword refers to the calling element.
  3. Prevent Default. My method allows for the cancellation of default events, such as following a link, submitting a form, or even typing a character into a text box.
Here are a few last little pieces of functionality. Handlers are not assigned twice, the method will exit if it finds that the handler has already been assigned to the listener.1 If, before my add function ever runs, an assignment from an outside script exists on the listener, it will be taken into account and not overwritten, therefore my method should seamlessly integrate into existing systems.

1Note: this does not apply to anonymous functions. since they are nameless, they are impossible to identify. The add function doesn't know if they are already assigned or not.

The Tools

I'm going to start my explanation by doing a quick run through of the javascript features which make this method possible.

  1. Registration by Direct Assignment. This is what PPK calls the traditional model. Every element which supports a given event listener has a property for that listener (the html 4.0 specification refers to these as 'intrinsic events'). This property is a single slot which may hold the reference to a function which will be called when the event fires.
  2. Creation of Properties. Javascript automatically creates new properties to objects when you assign them. Even on objects that you did not create. If you want to store something on an element, such as how many times it has been clicked, you can do so: element.numClicks = count;
  3. Closure. If function B is created entirely within function A, function B can access variables local to function A's scope, even if it is not called within function A's scope. In other words, functions remember the context in which they were created.

How it Works

For the purpose of explanation, say we are trying to assign multiple handlers to element a's onclick listener. Here are the elements which make up my design:

  1. A Generic Handler. The functions which are to be called onclick are not stored inside a.onclick at all. Instead, a generic function is assigned, which knows the location of each specific handler which is needed to run onclick. This generic function works by looping through a series of function calls.
  2. Storing Handlers on the Element. The location which is known to the generic function is on the element itself. Each function is assigned to a property which is a variant of the listener. a.onclick0, a.onclick1, a.onclick2, etc. In addition, a.onclick_num contains the number of handlers which have been assigned. The generic function uses a.onclick_num in it's loop condition, meaning if you set a.onclick_num to 0, you will effectively clear all event handlers from the listener. Since each function has been copied to a property on the object, this refers to the calling object.
  3. e and return. A given function is called like this: a.onclick1(e); This means that the event object (w3c dom) is available for event property collection. You can use it to find the mouse coordinates relative to the page onclick or the keycode data onkeypress. As far as I can tell, there is no requirement, however, that handlers specify the e argument. It will be ignored if it's not provided. Furthermore, the generic handler examines each specific handler's return value. If one of the handlers returns false, the generic function will return false, canceling the default behavior of a.onclick.
  4. Removal. The remove function first searches for the handler. If it is found, all of the handlers which follow it are shifted down one slot, so that they overwrite the target handler. Then, the handler count is decremented so that the last handler, which has two copies at this point, is not executed twice. Also, if the target handler is the last handler, and there are no following functions to overwrite it with, the count is merely decremented, which makes the generic handler ignore this last function call, and overwrite it on the next run of the add function. In this manner it works similarly to a queue when implemented with a circular static array.

Comparison

To finish, here is a comparison of my method with the W3C and IE alternatives, namely:

  1. W3C: addEventListener(), removeEventListener()
  2. IE: attachEvent(), detachEvent()
First, the most important difference between my method and these is that my functions have better browser support. As far as I've tested, they work in IE, Firefox, and Opera. Neither of these methods have that. Firefox doesn't support IE's methods and IE doesn't support the W3C's standards.

Also, with W3C and IE's functions, there is no way to know what handlers are registered. It would be a very simple task to write a function to check if a given handler is registered with my method. Also, it won't hurt to run add or remove when the handler is already registered or removed. Add will exit if it finds the function already assigned, and remove will do nothing if it doesn't find the function.

However, both of these alternatives support the ability to stop the propagation of events, which my method doesn't. The body handlers will always run when divs within the body are clicked, and there's no way to stop this. But with good design, this fact can be partially circumvented. Both IE and W3C support their own version of target in their event objects. By comparing this and target it is possible to determine if the handler's element was clicked, or if bubbling happened. In this way it is possible to shield a given handler from bubbling, which is often the purpose that the ability to stop propagation is used for.

Now let me compare my method with these two alternatives individually.

W3C

The specific differences between my method and the w3c's standard functions are small and insignificant. Here are the ones I've found.

First, PPK pointed out in the advanced model article on quirksmode that the w3c standard does not specify the order in which handlers will run. My method does. They will be run in the order they are assigned in.

Second, the addEventListener() function has a parameter for specifying whether the handler is run in the capturing phase or in the bubbling phase. My functions do not support this ability. I believe that a real world design which hinges on this functionality would be hard to find.

IE

My functions have one crucial difference from the IE alternatives. They maintain the usefulness of 'this.' Knowing which element is calling the handler is an extremely powerful thing.

Comments

Tell me what you think of all this. If you find any flaws, a comment would be particularly appreciated. Thanks.


— Aaron
Maks
Hello achalasia [url=http://parlament.wan.io/achalasia/index.html ]achalasia[/url] http://parlament.wan.io/achalasia/index.html achalasia surgery [url=http://parlament.wan.io/achalasia/achalasiasurgery.html ]achalasia surgery [/url] http://parlament.wan.io/achalasia/achalasiasurgery.html achalasia cardia [url=http://parlament.wan.io/achalasia/achalasiacardia.html ]achalasia cardia [/url] http://parlament.wan.io/achalasia/achalasiacardia.html
otne jwinbqstu
krqsi vucw wvzdhgp kvlrbsedh nwxkcpuer yurpl jmouwikfl
hkyjgpw nijzryw
wgmcyxev pzfxryh tgokfbduz zrsqapwj nkegyhstw enaydusq hvxbayf http://www.rjemdaf.kvgcjxhdy.com
jhyvlk fnko
hglavrfmu sqzdkhv egpfom dqvrhju olxiatfug cwbq edtxk glubqezis vgnqea
ma morgage rates
In Indiana hotel sheets must be exactly 99 inches long and 81 inches wide ma morgage rates [URL=http://interactive.cens.ucla.edu/nims/docs/MA-Morgage-Rates.html] ma morgage rates[/URL] http://interactive.cens.ucla.edu/nims/docs/MA-Morgage-Rates.html
best lesbijan sex
Nice site. Thank you:-) best lesbijan sex
anal sex
Good site. Thanks. anal sex
best lesbijan sex
Good site. Thank you:-) best lesbijan sex
best lesbijan sex
Good site. Thanks. best lesbijan sex
anal sex
Cool site. Thanks:-) anal sex
best lesbijan sex
Very good site. Thank you. best lesbijan sex
discount cialis
Very good site. Thanks! buy cialis
Laura
Good design! [url=http://ubeacxmp.com/xetz/krvp.html]My homepage[/url] | [url=http://daukizni.com/knwl/iavv.html]Cool site[/url]
Laura
order phentermine online
Very good site. Thank you:-) phentermine online pharmacy
order phentermine online
Very good site. Thank you:-) phentermine online pharmacy
air line tickets
Nice site. Thanks!!! air tickets
buy tramadol
cortislim
emend
breast cancer chemotherapy
breast cancer chemotherapy
buy didrex online
buy didrex online
fosamaxprevacid
actos
codeine soma
emend
buy zyrtec
adipex
Very good site. Thanks:-) buy cheap phentermine
buy ionamin
cheap nexium
online pharmacy phentermine
Nice site. Thank you:-) herbal phentermine
albuterol inhaler
albuterol inhaler
estrace
Cool site. Thanks.
Nice site. Thank you:-)
agency insurance
Good site. Thanks! cheap insurance
m357 vicodin
Good site. Thanks!
adipex 37.5
Good site. Thanks! buy phentermine adipex