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
    Regular Expressions for the Rest of Us

    Sooner or later you'll run across a regular expression. With their cryptic syntax, confusing documentation and massive learning curve, most developers settle for copying and pasting them from StackOverflow and hoping they work. But what if you could decode regular expressions and harness their power? In...

  • By
    Create a CSS Flipping Animation

    CSS animations are a lot of fun; the beauty of them is that through many simple properties, you can create anything from an elegant fade in to a WTF-Pixar-would-be-proud effect. One CSS effect somewhere in between is the CSS flip effect, whereby there's...

Incredible Demos

  • By
    Scroll IFRAMEs on iOS

    For the longest time, developers were frustrated by elements with overflow not being scrollable within the page of iOS Safari.  For my blog it was particularly frustrating because I display my demos in sandboxed IFRAMEs on top of the article itself, so as to not affect my site's...

  • By
    Introducing MooTools ScrollSidebar

    How many times are you putting together a HTML navigation block or utility block of elements that you wish could be seen everywhere on a page? I've created a solution that will seamlessly allow you to do so: ScrollSidebar. ScrollSidebar allows you...

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!