Welcome to Idea R | Branding - Web Agency - Digital Strategies
Switch to the mobile layout

      Idea R - Bring out your brand - Web Marketing strategies

Blog

Take a software geek from the 80s, add a new generation graphic designer and dilute with a longtime marketing strategist. Shake vigorously and you'll get the Idea R's blog.

Change language... italiano

JavaScript events? What a mess!

Published on 10/28/2011
Categories: Web Design
JavaScript events? What a mess!

The JavaScript events paradigm has three implementations, but all incompatible each other.
Let's try to put some order and to understand which one to use and when.

The original DOM 0 model

It's the base model, the first implemented, supported by all browsers, but with big limitations.
In practice the event handler is handled like a property of the objects that fires the event.

myButton.onsubmit = myObject.onsubmiteventhandler;

This means two important things:

  • You cannot set more than one event handler for each event, the last one that you set will substitute the previous one.
    Note that it is possible to set the same event handler for different events.
  • If you use the this object inside the event handler, this will refer to the firing object (myButton in the example) and not to the one that handles the event (myObject), as it happens in the classical Windows programming.

If the previous limitations are not a problem, for compatibility reasons this is without doubt the model to use.

The advanced DOM 2 model

It' the evolution of the previous one, but actually it's not supported by Internet Explorer versions older than 9.

document.myForm.myButton.addEventListener("submit", function(e) { ... }, false);

Or if you want to subscribe one object's method (note that Firefox allows to use the first method to directly pass object's methods):

document.myForm.myButton.addEventListener("submit", function(e) { myObject.onsubmiteventhandler(e); }, false);

Offers the following additional features:

  • You can register more event handler for the same event.
  • Every event handler has as a parameter an Event object with all significant event data.
  • If you  subscribe more times the same event handler, all the subscriptions after the first one are ignored.
  • The events are propagated in three consecutive phases:
    1. Capturing Pahase: the event is propagated from the Document objects following the descendants chain to the final object that subscribed to the event, to verify if any ancestor has set the event capturing (the third boolean event of addEventListener specifies if the event handling has to occur during this phase).
    2. Target Node: the event is handled by the subscribed object.
    3. Bubbling Phase: the event returns to the root node, from the subscribed node to the Document object.

In every moment the propagation can be interrupted by any event handler calling stopPropagation().
Regarding the this object, unfortunately there's no standardization, the most diffused interpretation is identical to the DOM 0 level.

Internet Explorer model

It's supported only by Microsoft's browsers, it's similar to DOM 2, but with some important differences.

document.myForm.myButton.attachEvent("onsubmit", function(e) { ... });

  • I does not implement the Capturing Phase during event propagation (in fact the third parameter is missing).
  • If you subscribe more times the same event handler, this will be invoked more times.
  • The Event object is not passed as a parameter to the event handler, but it's a global variable (window.event): this is not a problem because JavaScript programming it's single-threaded.
  • The this object inside event handlers refers to the global window object.

Let's take a look now to a typical example about handling all these implementations.
It happens frequently to subscribe an event handler for the page load completion, but if we have to use the DOM 0 APIs, there will be the risk to override another previously subscribed event handler. To solve this situation use the following function.

function subscribeOnLoad(eventHandler)
{
    // Check if DOM 2 level APIs are available
    if (typeof window.addEventListener != "undefined")
        window.addEventListener("load", eventHandler, false);
    // ...otherwise check if Internet Explorer APIs are available
    else if (typeof window.attachEvent != "undefined")
        window.attachEvent("onload", eventHandler);
    // ...otherwise use DOM 0 level APIs
    else
    {
        // ...if there's already an event handler
        if (window.onload != null)
        {
            var exsistingOnLoad = window.onload;
            window.onload = function (e)
                { exsistingOnLoad(e); window[eventHandler](); };
        }
        else
            window.onload = eventHandler;
    }
};

You are the reader number 14,104.

Comments

Previous article

Previous article

Centering text with CSS

Next article

Style sheets caching problems

Next article

Scroll to top