Event Delegation with MooTools, Dojo, and jQuery

By  on  

I've covered the ins and outs of event delegation within JavaScript a few weeks ago but most developers utilize JavaScript frameworks so I thought I'd take a few moments to show you how to implement this wonderful event strategy with the MooTools, Dojo, and jQuery JavaScript frameworks.

The MooTools JavaScript

The Element.Delegation class with MooTools More allows for developers to user event delegation within their application.  The syntax looks very much like MooTools' Event class' addEvent method with the exception that the :relay pseudo allows you to provide an argument which represents the elements which should answer to delegation:

// link-list is the parent, a is the child elements
document.id("link-list").addEvent("click:relay(a)", function(event,node){
	console.log("you clicked a link!",node);
});

The MooTools team used addEvent with the custom relay method to make adding event delegation to nodes very much like native event assignment.  I hope you like it!

The jQuery JavaScript

jQuery uses the intelligently named delegate method for event delegation:

$("#link-list").delegate("a", "click", function(){
	// "$(this)" is the node that was clicked
	console.log("you clicked a link!",$(this));
});

The delegate method accepts three arguments:  the selector to be matched, the event to be responded to, and the callback with which to run for the given node.

The Dojo JavaScript

The Dojo Toolkit's event delegation capabilities live within the dojox.NodeList.delegate resource.  Much like jQuery, Dojo uses the delegate method for event delegation:

// Require the resource
dojo.require("dojox.NodeList.delegate");

// *Sigh* When the DOM is ready...
dojo.ready(function() {
	// Assign an event
	dojo.query("#link-list").delegate("a","onclick",function(event) {
		// "this.node" is the node that was clicked
		console.log("you clicked a link!",this);
	});
});

The delegate method accepts the same arguments as jQuery:  selector, event type, and callback.

Event delegation is especially useful for applications which dynamically create and remove DOM nodes.  Imagine the nightmare in having to assign events frequently (to new nodes) and remove events from deleted nodes (to prevent IE memory leaks).  Take full advantage of the delegation capabilities of each framework -- they'll come in use quickly!

Recent Features

  • By
    Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API...

  • By
    Chris Coyier’s Favorite CodePen Demos

    David asked me if I'd be up for a guest post picking out some of my favorite Pens from CodePen. A daunting task! There are so many! I managed to pick a few though that have blown me away over the past few months. If you...

Incredible Demos

  • By
    Adding Events to Adding Events in MooTools

    Note: This post has been updated. One of my huge web peeves is when an element has click events attached to it but the element doesn't sport the "pointer" cursor. I mean how the hell is the user supposed to know they can/should click on...

  • By
    Using MooTools to Instruct Google Analytics to Track Outbound Links

    Google Analytics provides a wealth of information about who's coming to your website. One of the most important statistics the service provides is the referrer statistic -- you've gotta know who's sending people to your website, right? What about where you send others though?

Discussion

  1. who hast the best API on this? :)

  2. Daniel

    Wow, MooTools event delegation API is “WINNING”! The other APIs look like “armless droopy eyed children” and lack the “Tiger Blood” required to keep up with the sexy, “goddess”-like code of Moo ;)

    • I also prefer the Moo one.

      BUT, I think that it’s just a different approach, moreover, jQuery and Dojo might have a “cleaner” API.

  3. Arian

    Also who has the best submit or change event delegation, technically? :)

  4. Blaine

    This is actually way better than the method I posted in the previous one, good job on posting up a few more examples, this has really helped me out. The code I’m making will be much cleaner then assigning/reassigning rel’s! :D

  5. Nice post comparing the different libraries.

    You might consider adding the jQuery live method as well since it too does event delegation. Instead of having the callback attached to the #link-list it would be attached to the document.

    $( "#link-list a" ).live( "click", function(){
      // "$(this)" is the node that was clicked
      console.log("you clicked a link!",$(this));
    });
    

    The delegate method, as you showed, is more flexible and can provide better performance so that the event doesn’t have to bubble all the way up to the document before it is handled.

  6. Love the event delegation on jQuery. Simplicity FTW.

    BTW, I would appreciate if you have some time to look over my post on jQuery Performance tips and maybe suggest some new stuff.

    http://dumitruglavan.com/jquery-performance-tips-cheat-sheet/

    Thanks a lot.

  7. Nick G

    Here’s another approach using DOMNodeInserted and DOMSubtreeModified.

    NinjaScript: Javascript so unobtrusive, you’ll never it see coming

    Basically when the DOM is modified, the collection of behaviors is told to reapply all the behavior objects.

    • Daniel

      DOMSubtreeModified applied on whole documents can be catastrophic to performance. Each insertion, deletion, or modification will cause an event to fire. For sites that are even somewhat advanced, this can cause the browser to constantly be evaluating your code.

    • Nick G

      But so is adding a delegate to documnent.body (every mouse click/over etc..)

      Anyway, it’s always a matter of using the right tool for the job.

  8. Cyril

    From the examples I can’t understand whether any of the libraries supports a to be a CSS selector – like a[class=something].

    I.e. would the following work ?

    dojo.query("#link-list").delegate("a[class=something]","click",function(event) {
      // "this.node" is the node that was clicked
      console.log("you clicked a link!",this.node);
    })
    • Daniel

      I know MooTools does, I can’t speak for the others.

    • Sid Burn

      Yes, that works in Dojo.

  9. Steve Chan

    I like mootools’ :relay persudo,
    pretty cool! :)

  10. gabel

    I don’t get the point of delegation at all. If i’ll bind the events to a set of elements doesn’t that have the same effect, even if it works different? The argument of saving event binding code declaration doesn’t fit in my opinion.

    So why using delegation… for speed?

    The quickly hacked example tells me delegation is quite faster, but thats just some “in 3 minutes written” perf testcode…
    http://jsperf.com/event-delegation-vs-event-binding

  11. msssk

    How do you maintain context with delegate in dojo?

    dojo.connect( node, ‘click’, context, handler )
    This allows my handler to maintain context.

    dojo.query( ‘.parent’ ).delegate( ‘a’, ‘click’, handler )
    With delegation, the context becomes the element that triggered the event.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!