addEvent and removeEvent

This project attempts to create functions for flexible event registration which build on direct assignment (window.onload = func;) in order to maintain broad browser compatibility.

Because of how essential event registration is to javascript programming, for the sake of graceful degradation, I believe addEvent and removeEvent should work in as many browsers as possible. This approach should work in everything from Netscape 4 to IE 5.2 on Mac, in theory. I don't have the resources to test all browsers, I just know the fundamental nature of the tools which it is built on.

Quick Explanation

In a nutshell, my solution looks like this:

element.onclick = function(){
     // loop through function calls:
     // element.onclick0 through element.onclickN
}
element.onclick0 = handler1;
element.onclick1 = handler2;
element.onclick2 = handler3;
...
element.onclickN = handlerN+1;
element.onclick_num = N+1;


This bit of pseudo code illustrates how the design works internally. It is not necessary to think about this when using the functions.

Demonstration

Type characters into the input, and their key code data will be read out. Type the backspace key, and the input will resume normal behavior. The code which generated this behavior is below. As you can see it is exceedingly simple and elegant.

Also, it's obvious that this method of registration doesn't save us from differing event support. Since IE doesn't fire an onkeypress when the backspace key is clicked, and opera doesn't attach default behavior to onkeydown, the cross-browser solution requires an extra handler for opera.



addEvent(window,'onload',function(){
    var test = document.forms[0].elements[0];

    function printCode(e){
        var code = (e.which) ? e.which : e.keyCode;
        this.value = code;
    }

    function cancel(e){
        var code = (e.which) ? e.which : e.keyCode;
        if(code == 8){
            removeEvent(test,'onkeydown',printCode);
            removeEvent(test,'onkeydown',cancel);
            removeEvent(test,'onkeypress',operaCancel);
            this.value = '';
        }
        return false;
    }

    function operaCancel(){
        return false;
    }

    addEvent(test,'onkeydown',printCode);
    addEvent(test,'onkeydown',cancel);
    addEvent(test,'onkeypress',operaCancel);
});

Links

If you'd like to test the script for yourself, or learn how it works:

  1. Test
  2. Explanation

Updates

On the 30th of August, 2006, I began recoding all the testing functions to make a Netscape 4.8 test possible. Later on, I found that the type of test which the test page is built around will not work in Netscape 4.x, but the demonstration on this page will. The trouble was lack of getElementById. Netscape 4.x's layers and DOM-CSS interfacing aren't good enough to make it possible. The demo can work through the document.forms[0].elements[0] construct.

On the 23rd of August, 2006, I found the remnants of a quirksmode addEvent contest which took place last year around this time. I looked at the winner and saw that it had 1 additional feature that my method lacks: the event object is passed as an argument for both the w3c model and the ie model. I added this line e = (e) ? e : window.event; to create the same functionality with my functions.

Evidently simplicity was a factor in the choosing of the winning functions. My functions admittedly are not as simple as the winner of this contest, but they have better browser support and backward compatibility. The solution to the IE this problem seems to be cleaner in my functions, as well.

On the 22nd of August, 2006, I began to look for experienced javascript coders who could give me an opinion about my design and implementation, and of the method in general. I began by corresponding with Robert Nyman (robertnyman.com).

On the 19th of July, 2006, I made a slight change to the way the script detects if the method it uses has been setup yet or not, that is, if the generic function has been assigned, one or more handlers have been placed in the slots, and listener_num is assigned. This change makes it possible to clear all events with, for example, test.onclick = null; instead of test.onclick_num = 0;, without screwing up the method. I figured this method of clearing all handlers would be more intuitive to those who were used to working with direct assignment without my system.

On the 13th of July, 2006, I redesigned this script from the ground up. The previous method I had been using for registering multiple handlers with direct assignment had rendered 'this' useless. That was because it involved wrapping the function calls in an overall function and registering that to the listener. When the function calls are wrapped in an overall function, they no longer belong to the element, thus 'this' is undefined. The new design maintains the usefulness of 'this.'

Using Them

Feel free to copy or modify these functions. If you find problems or fix anything, post something here about it. If you use the functions, just keep the credit comment at the top. Since they were a lot of work, it would be nice to get credit for designing them. Here is the script.

Syntax

  1. addEvent: addEvent(window, 'onload', func); The first argument can be any element, the second is a string which contains the name of the listener, and the third contains your handler, which can be anonymous, but if so, you can't use the remove function to remove it because there is no way to identify it.
  2. removeEvent: removeEvent(document.getElementById('test'), 'onclick', back); The arguments for remove are exactly the same as for add. As long as remove has a reference to the function, it can find it and remove it.

About Me

My name is Aaron Moore, and I'm a sophomore computer science major at Gonzaga University. I've been coding in c++ for 2 years for my major. I've tinkered with javascript for about 6 years, but have only seriously studied it in the last 2. I am a proponent of the free software movement. I also use Blender to do 3d modeling occasionally. This script marks my first attempt at making a reusable tool in javascript.

Contact

two.a.ron [at] gmail [dot] com