Jul 3, 2007

Binding Event Listeners

Traditional Binding The traditional way of binding events is the one that I’ve been using up until now in this chapter. It is by far the simplest, most compatible way of binding event handlers. To use this particular method, you attach a function as a property to the DOM element that you wish to watch. Some samples of attaching events using the traditional method are shown in Listing 6-10.

            // Find the first form element and attach a 'submit' event handler to it
            document.getElementsByTagName("form")[0].onsubmit = function(e){
            // Stop all form submission attempts
            return stopDefault( e );
            };
            // Attach a keypress event handler to the body element of the document
            document.body.onkeypress = myKeyPressHandler;
            // Attach an load event hanlder to the page
            window.onload = function(){ … };
            

The disadvantages of the traditional method are as follows:

  • The traditional method only works with event bubbling, not capturing and bubbling.
  • It’s only possible to bind one event handler to an element at a time. This has the potential to cause confusing results when working with the popular window.onload property (effectively overwriting other pieces of code that have used the same method of binding events). An example of this problem is shown in Listing 6-11, where an event handler overwrites an old event handler.
  • The event object argument is only available in non-Internet Explorer browsers.

            // Bind your initial load handler
            window.onload = myFirstHandler;
            // somewhere, in another library that you've included,
            // your first handler is overwritten
            // only 'mySecondHandler' is called when the page finishes loading
            window.onload = mySecondHandler;
            

Knowing that it’s possible to blindly override other events, you should probably opt to only use the traditional means of event binding in simple situations, where you can trust all the other code that is running alongside yours. One way to get around this troublesome mess, however, is to use the modern event binding methods provided by browsers.

DOM Binding:W3C

            // Find the first form element and attach a 'submit' event handler to it
            document.getElementsByTagName("form")[0].addEventListener('submit',function(e){
            // Stop all form submission attempts
            return stopDefault( e );
            }, false);
            // Attach a keypress event handler to the body element of the document
            document.body.addEventListener('keypress', myKeyPressHandler, false);
            // Attach an load event hanlder to the page
            window.addEventListener('load', function(){ … }, false);
            

Advantages of W3C Binding

The advantages to the W3C event-binding method are the following:
  • This method supports both the capturing and bubbling phases of event handling. The event phase is toggled by setting the last parameter of addEventListener to false (for bubbling) or true (for capturing).
  • Inside of the event handler function, the this keyword refers to the current element.
  • The event object is always available in the first argument of the handling function.
  • You can bind as many events to an element as you wish, with none overwriting previously bound handlers.

Disadvantage of W3C Binding

The disadvantage to the W3C event-binding method is the following:
  • It does not work in Internet Explorer; you must use IE’s attachEvent function instead.

DOM Binding: IE

In a lot of ways, the Internet Explorer way of binding events appears to be very similar to the W3C’s. However, when you get down to the details, it begins to differ in some very significant ways. Some examples of attaching event handlers in Internet Explorer can be found in Listing 6-13.

Listing 6-13. Samples of Attaching Event Handlers to Elements Using the Internet Explorer Way of Binding Events

            // Find the first form element and attach a 'submit' event handler to it
            document.getElementsByTagName("form")[0].attachEvent('onsubmit',function(){
            // Stop all form submission attempts
            return stopDefault();
            },);
            // Attach a keypress event handler to the body element of the document
            document.body.attachEvent('onkeypress', myKeyPressHandler);
            // Attach an load event hanlder to the page
            window.attachEvent('onload', function(){ … });
            

Advantage of IE Binding

  • You can bind as many events to an element as you desire, with none overwriting previously bound handlers.

Disadvantages of IE Binding

  • Internet Explorer only supports the bubbling phase of event capturing.
  • The this keyword inside of event listener functions points to the window object, not the current element (a huge drawback of IE).
  • The event object is only available in the window.event parameter.
  • The name of the event must be named as ontype—for example, onclick instead of just requiring click.
  • It only works in Internet Explorer. You must use the W3C’s addEventListener for non-IE browsers.

DOM Binding:Dean Edwards way

            // Wait for the page to finish loading
            addEvent(window, "load", function(){
            // Watch for any keypresses done by the user
            addEvent( document.body, "keypress", function(e){
            // If the user hits the Spacebar + Ctrl key
            if ( e.keyCode == 32 && e.ctrlKey )
            {
            // Display our special form
            this.getElementsByTagName("form")[0].style.display = 'block';
            // Make sure that nothing strange happens
            //this works in IE and also firfox
            //because the library already fix the event
            e.preventDefault();
            }
            });
            });
            

Advantages of addEvent

  • It works in all browsers, even older unsupported browsers.
  • The this keyword is available in all bound functions, pointing to the current element.
  • All browser-specific functions for preventing the default browser action and for stopping event bubbling are neutralized.
  • The event object is always passed in as the first argument, regardless of the browser type.

Disadvantage of addEvent

  • It only works during the bubbling phase (since it uses the traditional method of event binding under the hood).