Event Delegation with MooTools, Dojo, and jQuery
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!
who hast the best API on this? :)
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.
Also who has the best submit or change event delegation, technically? :)
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
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.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.
Awesome, thanks for sharing Elijah!
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.
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.
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.
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.
From the examples I can’t understand whether any of the libraries supports
a
to be a CSS selector – likea[class=something]
.I.e. would the following work ?
I know MooTools does, I can’t speak for the others.
Yes, that works in Dojo.
I like mootools’ :relay persudo,
pretty cool! :)
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
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.