Event Delegation — An Example
December 20th, 2007 in tutorials | No Comments
After reading Event Delegation versus Event Handling, I wished I’d realized it sooner. I knew events bubbled, but I never thought to attach just one event to a parent element and detect what element was clicked, hovered over, etc, in the event handling function.
Event Handling
I’ve decided to create a more complex and practical example comparing the speed of the two techniques in an application scenario. In this situation, there exist many HTML elements that need functionality attached to them. Here is a demo page. Obviously it will be faster to attach a single event than to loop though a collection of the elements, attaching events to them. Here is the event handling method (note: I used the double click event so it didn’t interfere with the next example):
window.addEvent('load', function(){ // delete button $$('.delete').addEvent('dblclick', function(){ var parent = $(this.parentNode.parentNode); var placeholder = new Element('div').wraps(parent); parent.get('morph').start({'margin-left':100, 'opacity':0}).chain(function(){ placeholder.get('tween', 'height').start(0).chain(function(){ placeholder.destroy(); }); }); }); // min/max button $$('.minimize').addEvent('dblclick', function(){ var content = $(this.parentNode.parentNode).getElement('.content'); var value = (content.getStyle('height').toInt() === 0) ? content.getScrollSize().y : 0; if (!content.retrieve('tween')) content.set('tween', {link:'ignore'}); content.tween('height', value); }); });
In Firefox 3b1 on Linux, this takes anywhere from 70 to 75 milliseconds. You can visit the test page to find out how long it takes your browser.
Event Delegation
And here is the event delegation version that does the exact same thing:
window.addEvent('load', function(){ $('container').addEvent('click', function(event){ var target = $(event.target); // delete button clicked if (target.hasClass('delete')) { var parent = $(target.parentNode.parentNode); var placeholder = new Element('div').wraps(parent); parent.get('morph').start({'margin-left':100, 'opacity':0}).chain(function(){ placeholder.get('tween', 'height').start(0).chain(function(){ placeholder.destroy(); }); }); return; } // min/max button clicked if (target.hasClass('minimize')) { var content = $(target.parentNode.parentNode).getElement('.content'); var value = (content.getStyle('height').toInt() === 0) ? content.getScrollSize().y : 0; if (!content.retrieve('tween')) content.set('tween', {link:'ignore'}); content.tween('height', value); return; } }); });
Here, I get just one element, the parent ul, and add a click event function that detects what element was clicked and takes the appropriate action. This takes 0 to 2 milliseconds.
Adding new elements that have the same functionality is also about 2 times quicker, but besides that, it’s a lot easier. Every time you add a new element using the event handling method, you have to attach events to that new element. With event delegation, all you do is add the new element. There’s no need to attach any events because the parent element already has it.
Here’s a bonus demo page that illustrates the ease of creating nested elements with the same functionality. Again, the only event function is attached to the parent containing element.

Hi, I'm Chris, a passionate freelance web developer. My languages of choice are PHP and JavaScript, and that's what you'll mostly find in my blog. You'll also find updates about 