Quick Tip: JavaScript Event Delegation in 4 Minutes
videos

Quick Tip: JavaScript Event Delegation in 4 Minutes

Share

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.

XEROX CODE

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;
  }
});

Related Posts

Add Comment

Discussion 41 Comments

  1. piyanistll says:

    very nice tutorial thanks for post

  2. BCProducties says:

    Awesome! I was wondering about this like a week ago but never figured out how to get this working.

    Thanks a lot Jeffrey, really liking these quick tips!

  3. What’s wrong with using live events :) In this specific example using $(‘a#addItem’).live(‘click’, function(){ //fire up on click }); ?

  4. nice article, I just recently started to understand the problems that can be associated with the bubbling-up of events, especially if your parent has the same event bound to it as the child.

    Just a side thought, you could probably use this method to not only accommodate elements added dynamically, but you could also modify the parent UL and the clicked at the same time instead of binding click events to both or trying to get the parent of the clicked right?

  5. Mannyatico says:

    Hi, I know my question is out of order, but I really wanna know what’s the font name you use in your coda :P
    Great tut

  6. Great tutorial, great website!

  7. James says:

    Why are you rushing? Now and in the 200 second video…

  8. That’s great !

    Thanks !

  9. eric says:

    more codeignitor plzzzz

    • enatom says:

      no… NO more code-igniter… the world does NOT revolve AROUND cock-igniter

      jesus, what happened to PHP, jQuery, Ajax, Tips & Tricks… also articles relating to site architecture and rising technologies…

  10. Matt Bridges says:

    As always, another fantastic screencast, Jeff!

  11. Yosy says:

    Thank You Jeffrey,
    But for the next can you get bigger fonts?It`s hard to see with those tiny font.

  12. nikolai says:

    Great! Work in ie8. But i don’t think will work in previous version of IE because of a “last-child” pseudo class

    • Brian Egan says:

      Hey Nikolai,

      Lucky for Jeffrey it actually does work on IE6+! What’s happening is that Jeff is passing that CSS selector jQuery, not to the browser via a normal CSS rule (Which IE6 would choke on). Once sent to jQuery, jQuery then uses it’s Sizzle selector engine (written in JavaScript) to find the right element for you, in any jQuery supported browser (ie6+, FF2+, safari3+ ,opera9.5+).

      That right there is the magic of jQuery. It normalizes all these different tasks between browsers, from element selection to event binding. That’s why his raw JavaScript version isn’t nearly as simple as jQuery’s .click(), Jeff had to account for IE. jQuery already does this for you!

      Brian

      • nikolai says:

        Thanks man :)
        I primarily code css and xhtml and i’m not very familiar with jQuery, but it worth to learn to deal with browser compatibility (and all the others cool things you can do with jQuery :) ).
        best regards to you and Jeffrey

  13. Mike says:

    I don’t understand what you’re trying to achieve. The links have to be coded in anyway so you don’t save any typing and they all work without the javascript. Sorry to be so dumb!

    • Jeffrey Way says:

      I’m not sure what your question is??

      • Mike says:

        Well you start the video by saying ‘Imagine you want to add a click event to every link’ but every link already has a click event – that’s what a link is. And anyway why on earth would you want to add exactly the same click event to dozens of different links? They’re all meant to take you to different places.
        I’m obviously missing something important here…

    • This is just an example of how to use event delegation. It’s applicable to any element.

  14. Mike says:

    Please spend $3 for a pop filter for your mic and practice speaking at a normal speed when you talk.. or less coffee. Thank you so much for the tut! The info is great!

    • Jeffrey had a five minute time limit, so he needed to fit everything within that time-frame. That’s why he talked faster than normal.

      • Mike says:

        What is up with the time limit and lack of appropriate equipment to insure the quality of your product??? I’ve got a Plus subscription and I feel like you guys are developing an entire archive of difficult to listen to tuts that listeners would really prefer were as professional as possible. Please consider getting it together so that everyone will know you take pride in providing the best tuts possible. I’m pulling for you. Thanks.

      • Screenr’s time limit is five minutes. This isn’t a Plus tutorial, it’s a Quick Tip.

      • Jeffrey Way says:

        Hi Mike – I’m sorry you don’t like the quality of video. I did my best, but I’m not a video guy. With that said, I personally think the video sounds just fine – but I could be wrong.

        Talking fast is a mixture of the time limit, and me in general. :)

      • Alexander says:

        i think your quality(and the quality of all your screencasts) is great and the speed isnt a real problem, just view the vid again -> where is the problem?

  15. snaKeSz says:

    quick and clean. Well done!
    I think the most guys and girls got the idea behind this tutorial!

  16. Mike says:

    Jeffrey, you’re a very nice guy and there’s nothing to be sorry for. At least you got the comment, it’s yours to disregard as you please. Maybe you’re not the best judge on whether it’s an issue. At least I feel better that I tried to help. I think I need to only patronize companies that care what clients think and take their comments seriously. I’ll go ahead and cancel my subscription and try elsewhere. Thank you for your effort. Best always! ;-)

  17. Adardesign says:

    Thanks for these wonderful tuts….. In such cases can you please provide a link (in the bottom of the video) to download the media?

    Thanks again..

  18. Thai says:

    Thank you for clearly explaining that. I understood it but examples are so delightful to digest and makes sense of things.

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.