For those that haven’t come across the term before, event delegation refers to the technique of reducing the number of event listeners attached to the document by attaching just one listener to a containing element and testing in the handler where that event has bubbled up from.
Let me give you an example from the Multimap website. The main navigation on the site includes 6 links across the top, 4 of which require event handlers to alter the href attribute of the link when it is clicked. These 4 links have a class attribute of ‘bundle’.
Traditionally you might approach that situation in the following way.
There’s a lot of overhead in the above code. First of all the
getElementsByTagName loops through every DOM node in the
mainNav element to find all the links. We then have to loop through them again manually to check the class names of the links. That’s wasted CPU cycles at every stage.
How about if we could just attach one event listener to the
mainNav element and then capture any click on the links within that?
The simplicity and elegance of this should be pretty clear, but it has a number of performance benefits as well:
- The less event listeners attached to a document the better. They all take up memory and in extreme circumstances can slow browsers down considerably.
- ‘Just in time’ execution. The second example does a little bit more work when the event handler is executed, but this is better than doing that work on ‘load’ when we don’t even know if the resulting handler is going to be executed or not.
- It’s less code. Less code means less maintenance, and less bandwidth for both your web server and your users.
There’s one caveat to the above code. Getting the target element of the event is not always as simple as using
e.target. In Internet Explorer you need to use
e.srcElement. The easiest way of dealing with this is to use a small
getEventTarget function. Below is what I use.