Event delegation with JavaScript

There has been a fair share about JavaScript and event delegation, but since a lot of people doesn’t seem to have read it, I thought I’d re-iterate the point here. The more the merrier, right? :-)

HTML used for this post

The HTML used for this post, which can also be seen live in the event delegation demo page, looks like this:

<ul id="navigation">
    <li><a href="http://www.robertnyman.com/code-libraries/">Code libraries</a></li>
    <li><a href="http://www.flickr.com/photos/robertnyman">Flickr photos</a></li>
    <li><a href="http://www.robertnyman.com/web-sites/">Web sites</a></li>
    <li><a href="http://www.robertnyman.com/archives/">Archives</a></li>
    <li><a href="http://www.robertnyman.com/geekmeet/">Geek Meet</a></li>
</ul>

Traditional event handling

As we’re all taught and how we start out is adding an event to each element we want the end user to be able to interact with; naturally, in an unobtrusive manner (basically, meaning that no events are inline in the HTML code, but rather applied directly from an external JavaScript).

window.onload = function () {
    var navigation = document.getElementById("navigation");
    var navigationLinks = navigation.getElementsByTagName("a");
    for (var i=0; i<navigationLinks.length; i++) {
        navigationLinks[i].onclick = function () {
            /*
                Something extraordinary that
                only you thought of...
            */
        }
    }
};

Why that isn’t always so good

The problem with the above approach is that with a web page with a decent level of interaction, it will soon be full of events that the web browser have to keep track of, and it might also pose memory issues in some web browsers (yeah, just guess…).

When I met Peter-Paul Koch (ppk) at @media Ajax, one of the questions I asked him is how/if he deals with memory leakage in Internet Explorer. If I remember correctly, he said:

I don’t really do much to code around it. Just as long as you’re using event delegation, it’s practically not a problem.

Presenting event delegation

The general idea with event delegation is to have just one (or a few) events on elements far higher up in the HTML hierarchy, and from there, trace on what target element the event actually occurred, and then take appropriate action. The code from above reworked:

window.onload = function () {
    var navigation = document.getElementById("navigation");
    navigation.onclick = function () {
        // Ta daa!
    }
};

Looks a little bit simpler, right? And it definitely helps to avoid scattering your events all over the place.

But.. Hang on!

“Hey, wait a minute!” I hear you say! “Sure, you only applied one event, but you broke the functionality!”, Well, no. The key to succeeding with event delegation is in the function/method receiving the actual event, and from there, decide what to do. Let us take the code above a bit further:

window.onload = function () {
    var navigation = document.getElementById("navigation");
    navigation.onclick = function (evt) {
        // Event tweaks, since IE wants to go its own way...
        var event = evt || window.event;
        var target = event.target || event.srcElement;
        var href = "Link's href: " + target.getAttribute("href") + "\n\n";
        // Completely simplifying below
        var text = "Link's text: " + target.innerHTML;
        alert(href + text);
    }
};

As you might see, the possibilities and advantages of having centralized event handling are probably becoming increasingly clearer to you just as you read this. Your code will be leaner and have better performance, without sacrificing any of the functionality. Ain’t that great? :-)

JavaScript library support

As you might have guessed, most JavaScript libraries cater to this in one way or the other. With DOMAssistant, we simply provide a cross-browser way to determine on what actual element the event took place. Same code, but with DOMAssistant:

DOMAssistant.DOMReady(function () {
    $("#navigation").addEvent("click", function (evt) {
        var target = evt.eventTarget;
        // And so on...
    });
});

By the way, if anyone has a suggestion how we can make your event delegation life even easier with DOMAssistant, just let me know!

Event delegation with other JavaScript libraries

Looking around at what other JavaScript libraries offer, I found some quick links to help you out:

Event delegation demos

I’ve put together a very simple demo page for you to see event delegation in action; there’s also an event delegation demo using DOMAssistant.

Now, go happy event delegating! :-)

Posted in Developing,DOMAssistant,JavaScript,Technology |

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>