Advertisement

Quick Tip: JavaScript Event Delegation in 4 Minutes

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

Event delegation can be a confusing topic for those who are unfamiliar with the concept. But, luckily, it's really simple. In this quick tip video tutorial, I'll demonstrate the concept in just under four minutes.

Imagine that you have five hundred anchor tags on your page. As you might imagine, adding a click event to every one of those would be time consuming, and unnecessary. On top of that, what happens if, once you click on those anchor tags, we add additional anchor elements to the page? Would those new anchors be bound to the click event as well? The answer is no. You would then have to reattach a listener to those newly created elements.

Enter Event Delegation

Instead, with event delegation, we simply add a single event listener to an ancestor element, maybe something like a "ul." Then, when the user clicks on one of its child elements, like an anchor tag, we only check to see if the target of the click was, in fact, an anchor tag. If it was, we proceed per usual.

$('ul').click(function(e) {
	
	if ( $(e.target).is('a') ) {
		alert('clicked');
	}
});

Advantages

  • Only attach one event listener to the page, rather than five hundred (in our example)
  • Dynamically created elements will still be bound to the event handler.

Why Does this Work?

It works because of the way elements are captured (not IE) and bubble up. For instance, consider the following simple structure.

<ul>
   <li><a href="#">Anchor</a></li>
</ul>

When you click on the anchor tag, you're also clicking on the 'li' and the 'ul' and even the 'body' element. This is referred to as bubbling up.

Notes About this Screencast

Please keep in mind that this is just a simple example to explain the functionality. We used jQuery, only because I had four minutes to record! In that particular example (watch the screencast first), we could have used two alternative options:

  1. Pass true as a parameter of the clone() method. This would then clone the element, as well as any event handlers.
  2. Use the live() method instead. However, be careful when using this method: it reattaches the event handler X times. This may not necessarily be needed.

Mostly, this was meant to demonstrate the idea. With regular JavaScript, you could do something like:

// Get some unordered list, which contains anchor tags
var ul = document.getElementById('items');

// Quick and simple cross-browser event handler - to compensate for IE's attachEvent handler
function addEvent(obj, evt, fn, capture) {
	if ( window.attachEvent ) {
		obj.attachEvent("on" + evt, fn);
	}
	else {
		if ( !capture ) capture = false; // capture
		obj.addEventListener(evt, fn, capture)
	}
}

// Check to see if the node that was clicked is an anchor tag. If so, proceed per usual. 
addEvent(ul, "click", function(e) {
  // Firefox and IE access the target element different. e.target, and event.srcElement, respectively.
  var target = e ? e.target : window.event.srcElement;
  if ( target.nodeName.toLowerCase() === 'a' ) {
     alert("clicked");
     return false;
  }
});
Advertisement