CosmoCode is a Berlin based IT service provider focusing on CMS, Wikis and Web2.0
Great software. Bright people. Happy customers!
Mail info@cosmocode.deTel +49 (30) 814504070
We're currently evaluating various JavaScript libraries for inclusion in some of our future projects.
Last week I tried JQuery which is so far my favourite library. JQuery is build around a very powerful CSS/XPath notation for selecting DOM nodes to manipulate. It is leightweight (10k) and comes with a few basic effects additional to the DOM-manipulation and AJAX stuff you?d expect from a decent Web-2.0 lib. There are many additional plugins for adding new things like drag'n'drop, table sorting or fancy effects available.
So far we had a look at prototype/scriptaculous, JQuery and Dojo. Dojo seems to be very powerful and well designed but for my taste it is just too much. Prototype has really good ideas but somehow everytime I try it I struggle with it more than it helps me. But JQuery is so elegant…
Here is what really sold me to JQuery. I tried to build an object and assign two eventhandlers to the same event maintaining the “this” context. Prototype has a nice way to keep the this context using the “this.foo.bindAsEventListener(this);” method. Unfortunately I couldn't find out how to use this with binding multiple eventhandlers to the same event.
So the following is what I finally tried in prototype:
var FBrowser = Class.create();
FBrowser.prototype = {
label: "world";
initialize: function(){
var flinks = $$('#fbrowser-folders a.folder').toArray();
for(var i=0; ilength; i++){
flinks[i].onclick = this.foo.bindAsEventListener(this);
flinks[i].onclick = this.bar.bindAsEventListener(this);
}
},
foo: function(){
alert('hello '+this.label);
},
bar: function(){
alert('hi '+this.label);
}
}
As I said it didn't work. I only got the 'hi' prompt - the 'hello' prompt was overwritten by the second assignment. Note that I used the new $$ function of the current prototype beta release to select all the links I wanted to change using CSS notation.
So how do I do the same in JQuery? Here it comes:
var FBrowser = new Function();
FBrowser.prototype = {
init: function(){
var self = this;
$('#fbrowser-folders a.folder').bind('click',function(e){ self.foo(e,self); });
$('#fbrowser-folders a.folder').bind('click',function(e){ self.bar(e,self); });
}
foo: function(e,self){
alert('hello '+self.label);
},
bar: function(e,self){
alert('hi '+self.label);
}
}
Okay. No automatic this context inside the eventhandlers, so I have to use closures. But do you notice the elegant way to assign the handlers? No loop, no overwriting of the previous assignment. It just works.
I realize this is about two years too late, but for the sake of those people just now finding the post, here's how you'd do it as of current Prototype: initialize: function(){ $$('#fbrowser-folders a.folder').each( function( link ) { Event.observe(link, 'click', this.foo.bindAsEventListener(this) ); Event.observe(link, 'click', this.bar.bindAsEventListener(this) ); }); } And here's how you'd do it in jQuery: init: function(){ var self = this; $('#fbrowser-folders a.folder') .bind('click',function(e){ self.foo(e,self); }) .bind('click',function(e){ self.bar(e,self); }); } (keep in mind, jQuery loves chaining, so there's no reason to select the same elements twice)
Or you could pass 'this' through in the optional data parameter: jQuery('someSelector').bind('click', {this:this}, function(eventData) { alert(eventData.data.this); });
In fact, it's worthy of another post :o) http://www.codecouch.com/2008/12/replacement-for-bind-or-bindaseventlistener-in-jquery/
About CosmoCode
Subscribe
Mike Stenhouse
2006/08/07 18:17
I just ripped the addAsEventListener code out of prototype.js and included it in my jquery-addons.js file, where I keep my plugins… It works a treat!