debuggable

 
Contact Us
 

jQuery is a true prototype killer

Posted on 24/8/06 by Felix Geisendörfer

Deprecated post

The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.

Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.

Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).

Update: jQuery 1.0 has just been released. Go and check it out!

After spending (too) much time on learning how to use prototype, I recently gave jQuery a serious try. Saying that I'm amazed is maybe an understatement. I think I'll never go back.

Just take look at my code for opening external links (with a rel attribute = 'external') in prototype:







[javascript]/**
* This attaches an onClick event to all anchors containing rel="external" on the site
**/
this.Behaviors.externalLink = function()
{
var anchors = document.getElementsByTagName('a');
for (var i=0; i {
var anchor = anchors[i];
var relAttribute = String(anchor.getAttribute('rel'));
if (relAttribute.toLowerCase().match('external'))
{
Event.observe(anchor, 'click', function(event){Lugsteinhof.Behaviors.externalLink.click(event);});
}
}
}

/**
* This is the behavior for externalLinks that are clicked (open them in a new window).
**/
this.Behaviors.externalLink.click = function(event)
{
Event.stop(event);
var element = Event.findElement(event, 'a');
window.open(element.getAttribute('href'));
}
[/javascript]

And now jQuery:
[javascript]/**
* This attaches an onClick event to all anchors containing rel="external" on the site
**/
this.Behaviors.externalLink = function()
{
$("a[@rel='external']").click(function(){window.open(this.href); return false;});
}[/javascript]

If you think that's cool, go and checkout their website and refactor your site to use jQuery like technorati already did.

--Felix Geisendörfer aka the_undefined

 
&nsbp;

You can skip to the end and add a comment.

Nate K said on Aug 24, 2006:

Wow - thats pretty nice! I have been reading up on both, weighing out decisions based on my needs. Your examples have helped me to narrow down this process.

Gonna go play with it now :)

Bryan Buchs said on Aug 24, 2006:

Now all we need is for someone to write a jQuery Cake Helper... Any takers??? Please?

Version 1.0 of jQuery should be released tomorrow (I hope I hope I hope), and the author of the Interface plugins (jQuery's Scriptaculous) said that he'll be releasing his update around the same time.

I used jQuery on a small project recently, and another developer who had never seen nor heard of it was able to look over my code and understand exactly what was going on.

Felix Geisendörfer said on Aug 24, 2006:

Hi Bryan,

I really dislike the CakePHP Ajax/Prototype helper and I won't ever code something like this for jQuery. The reason I don't like it, is that it produces "inline" js and leaves back a mess of crapy non-semantic html/javascript. It's not the fault of the helper itself, it does the best it can do. But JS should not be embedded in Html(attributes) in first place. Because it will very likely make your site inaccessible. Javascript should be an additional layer on a solid html/css basis.

So really, what advantage do those helpers give you? Besides generating code that one should write himself in js (not php) ?

wluigi  said on Aug 24, 2006:

I think Felix is right "inline" js is a realy bad think and helpers are not a solution

John Resig said on Aug 24, 2006:

Glad to see that you're enjoying jQuery - let me know if you hit any snags.

As far as CakePHP + jQuery integration, I'd be happy to promote this and donate any support possible to making this happen. We're currently, also, working with two other PHP projects: Symfony and Drupal, trying to get jQuery integrated with their code base. If you have any questions, there's a good number of PHP/jQuery developers on the jQuery Mailing List (http://jquery.com/discuss/) so feel free to bring up your questions there.

sosa said on Aug 24, 2006:

I'm not really sure, but I think that prototype can be a lot simpler than your example. Maybe something like this (not tested):

$$('a').each(function(element){if element.toLowerCase().match('external') Event.observe(element,'click',function(event){window.open(event.target..getAttribute('href'))});

jQuery is cool, but many of their examples are misleading. (and your jQuery example is case sensitive, while the Prototype one is not)

Btw, Cake does a very good job on unobtrusive javascript if you use Event:Selectors and the Javascript::Event

Felix Geisendörfer said on Aug 24, 2006:

John: Hey, thx for stopping by, I subscribed to the RSS feed of the mailing list for now, maybe I'll get active in it at some point. As far as integration with CakePHP goes I'm not sure what would be a good way for this. In my oppinion there is something wrong with your JS if you have to write PHP wrappers for it to reduce complexity. If it's ment to get non-JS programmers into using JS then this is like letting people create html with frontpage - not a good idea. But maybe somebody else will pick you up on that one?

sosa: Yes, maybe my prototype example is a little too long / bad, but I was able to make the jQuery one after working with it for about ~30 minutes. I used prototype way longer then that and didn't see something easier right away. In general I was able to reduce/replace half of the JS in my current project by using jQuery without thinking about it too much. Prototype definitly allows you to do the same stuff as jQuery, but it's just a lot more difficult/complex & less intuitive.

Regarding CakePHP's Javascript::Event: Yes that looked like it wasn't too bad, but it still is inline js and therefor I'm not going to use it. I much rather code my entire application the traditional way and then do all the fancy web 2.0 stuff as a JS layer on top of it. Because when it comes to maintainance/redesigning etc. you'll have to go through all your views(templates) and rewrite id's, classes', etc. instead of having a central js file with all of it.

Another thing I really hate about these new "web 2.0" sites, are those embedded ajax spinners with style="display: none;". I mean come on, the people who use it claim to do semantic html with ajax. I can't see that! That stuff can easily be attached to the dom tree via js instead of a hidden div.

Vladislav said on Aug 25, 2006:

About helpers, Felix have a reason.

When I programming my application with html->ajax, I got a lot of problem... Why? Becouse I need more functionality with scriptalous/prototype. More & different, then can make AJAX helper...

Finally, after a long dance around computer, I write all code by myself... without helper. Yep, I am not a JS programming and not so understanding how all work's (smile). But it's not impossible.

Whe you need fast code with functionality different, then standart drop shadows/hide... You couldn't use helper.

Sorry for my bad english ;-)

Bryan Buchs said on Aug 25, 2006:

Wow, I didn't realize that an innocent comment about a Helper would generate such discussion. I only suggested it because I don't like the fact that Prototype/Scriptaculous is the default/only JS solution in the Cake package, and would like to see an alternative available for PHP developers who aren't javascript-savvy.

For the record, I totally agree about inline scripting. But it would be nice to quickly spit out simple jQuery functions ("$.post" for example) while I'm prototyping an application.

Felix Geisendörfer said on Aug 25, 2006:

Hey Bryan,

I agree that Prototype/Scriptaculous as the default/only Helper solution in CakePHP is questionable. But I still stay with my oppinnion that people who don't know javascript shouldn't use javascript code generators to pretend they do, unless it's for their personal/experimental needs.

I know that CakePHP has to go with the web 2.0 hype from a marketing stand point, but if you want to write a real application, using cutting edge technology, you should really know what you are doing. And this sometimes includes learning "new languages like javascript ...

I'm no expert at javascript, I admit, but I write all my js code myself (err, besides the libraries I use), so I understand what it does. It also allows me to perfectly seperate behavior (js) from content (html) which results in almost automatic graceful degration.

However, using inline js and code generators for prototyping needs as you suggessted is totally reasonable and worth the effort of writing some helpers. I just can't stand that sometimes 1/4th of the CakePHP mailing list is cluttered with people who use the javascript/ajax helpers without having the slightest clue about what they are doing.

Vijay said on Aug 25, 2006:

Great, realy i am appreciate.
Thanks for new things.

Kiyoshi (nemontemi)  said on Aug 26, 2006:

Why don't you give a try to the Dojo (http://dojotoolkit.org) Ajax library?

As far as I know, Dojo was the first Ajax library and has the best 'mommentum' among the other libraries.

Also, an 'underground' news said that the OpenAJAX Alliance, leaded by IBM and has members like Sun, will invite the Dojo staff to become member of the group.
Talking about standarts and development, for sure this is a remark to pay attention to.

Besides this, I see no problem trying new alternatives =)

Best regards, Felix.
And luck in the development road!

olivvv  said on Aug 28, 2006:

The Head helper (Rossoft) is the quick and simple solution to your hepler without inline scripting worries...

Bryan Buchs said on Aug 29, 2006:

Good suggestion olivvv! I had not seen the Head Helper before, and wondered why there wasn't some way to accomplish that.

Matti Putkonen said on Sep 02, 2006:

We used JQuery on Bakesale and have been very happy with it. Though with my limited imagination it is hard to see how an CakePHP helper would actually help as part of the beauty of Jquery has been the fact we can just link the external javascript files and JQuery library and the thing works :)

m3nt0r said on Sep 09, 2006:

What about a "helper" which redirects its output into an external javacript file(php), auto-adds it to the header and associates its actions by using the IDs provided by the view-author? This way the Helper can be used within the view (for the sake of easy element association) but when it comes down to parsing it outputs just one *.js file containing all the observers. :) Besides the resulting fact that ther will be no inline javascript whatsoever, gzip support and other fancy stuff could be added. What you think?

PS: Also consider Behaviour.JS .. creating a rule file with php is pretty easy and also pretty straight forward.

[...] Ok, I'm no expert on Javascript but I know enough to have some fun with it. Unlike lot's of folks, I'm not into using all those bloated JS libs, frameworks and other things around. However, I'm in love with the lightweight jQuery library, since it allows to write amazingly elegant code that's easy for others to read, and fun to work with. One of the coolest aspects about jQuery is that it doesn't use prototypes to turn Javascript into a new language (like the Prototype library does), but rather encapsulates all functionality into the $ object that is used as a wrapper/selector for the elements you want to manipulate. So if your app includes more then 100 kbyte of JS bloat right now, do yourself a favor and switch to the fresh jQuery 1.0.2. It will not only reduce your JS dependencies to 15kb, but also give you the chance to reduce your own code considerably (2-3x for me). [...]

gosciu  said on Mar 03, 2007:

Sorry, but Your example of propotype sucks. You just dont know how to use prototype /NEVER do _for_ loops with propotype my friend, use $R(x,y).each(i) instead/ ;)

[code]
/**

* This attaches an onClick event to all anchors containing rel="external" on the site

**/

this.Behaviors.externalLink = function() {

$$('a[rel="external"]').each(function(el){

Event.observe(el, 'click', externalLinkClick(event));

}

}

/**
* This is the behavior for externalLinks that are clicked (open them in a new window).

**/

function externalLinkClick(e)

{

Event.stop(e);

var element = Event.findElement(event, 'a');

window.open(

Event.findElement(event, 'a')

);

}

[/code]

PS. I use jquery as DOM selector/manipulator, but prototype has some unique JS language extensions which i cant resist (and noting prevents you from using them both).
PS2. Look at dom_query from you_ext if your're insrested in DOM selectors

Felix Geisendörfer said on Mar 03, 2007:

gosciu: Please keep in mind that this post was made quite a while ago when there was a) no official prototype docs, and b) prototype might not have had the capabilities you based your example on.

As far as JS language extensions go: That is why I actually *hate* prototype. I want to be able to do for - in loops without having to filter out stupid prototype functions and properties. I want regular JS code to not be effected by the library of my choice and most of all I want *one lightweight library* that selects elements *and* provides sophisticated DOM manipulation functionality ... ; ). And that's jQuery and nobody else these days.

Other then that I'm familiar with dom_query and think it's pretty neat but wouldn't use it because it doesn't come with the DOM manipulation package jQuery does unless I include huge EXT dependencies ...

valenluis  said on Apr 11, 2007:

jQuery seems good, but i agree with Felix Geisendörfer, the helpers aren't helpful enough if you really want to make an accesible website :)

el_vartauy  said on Apr 21, 2007:

I agree with Felix about:
_ usefulness of some helpers when you have to fine-tune your app for accesibility and special behaviors.

_ semantic considerations on the helpers output, aka inline js or unreadable auto-generated id's, i prefer behaviors.

_ prototype &co are a little bloated. (someone mentioned Dojo, another bloated one)

_ the elegance of resulting jQuery code over prototype one's, handwrite or generated.

but:
_ i have to agree with Thomas Fuchs (scriptaculous author) that in one pdf slide i saw his recommendation is to use the ugly inline style "display:none;", because the css or js behavior will be delayed on large docs, so some elements will start visible until the css style is applied by the browser.

_ i'm a 7 year's experienced PHP developer, and i have to tell that the same beauty and elegance that you find jQuery has over Prototye, Ruby has over PHP. i'm seriously considering the switch, with the advantage that CakePHP philosophy is based on Rails.

i think my next web stack will be Rails+jQuery.
long life to behaviors, microformats and conventions over configuration.

good thread.

el_vartauy  said on Apr 21, 2007:

i forgot to mention i think it could be handy the use of CJS/RJS for complex app behaviors and data logics.

imho.

Felix Geisendörfer said on Apr 23, 2007:

el_vartauy: Sure ruby definitely has some elegance PHP does not offer. I will do some ruby playing myself in my spare time (uh wait what was that again?) in the future I guess, but I know I'll mainly stay with PHP for various reasons for a good while:

- Hosting
- Sub-contractor costs

- Speed

- Knowledge in PHP over Ruby

- Vendor libraries

- My love and commitment to CakePHP

So if you feel like moving on go ahead. We'll see what PHP6 brings and if the market share will do a significant shift over the future, but for now I still think PHP ain't dead yet nor is it dieing ; ).

pablasso said on May 23, 2007:

you are open minded when it comes to js frameworks, but not when it comes to languages

go figure

Felix Geisendörfer said on May 23, 2007:

pablasso: Says who? I'm learning Haskell right now ... go figure.

rloaderro said on Jun 04, 2007:

@Felix "And that’s jQuery and nobody else these days."

I know this article is a little dated now. Last year I moved from Prototype + Scriptaculous to prototype.lite + moo.fx. But since Mootools (http://www.mootools.net) was released it has been a paradigm shift in the world of JS frameworks for me. If you have a chance take a look at the latest release (1.11 atm). Really look at it - read the source - every line of code is beautifully engineered. Worth checking out since it does the same things you like about jQuery, only probably smaller and faster.

Felix Geisendörfer said on Jun 04, 2007:

rloaderro: Sry, but jQuery is way more elegant, beautifully engineered and so on then mootools. Now I'm not an expert at mootools but just checked out how to update a div via ajax in mootools and compared it to jQuery.

Mootools: http://bin.cakephp.org/view/902640095
jQuery: http://bin.cakephp.org/view/1657913354

Here is what's different: Mootools goes the prototype way of having objects for everything. jQuery uses the bucket concept: Selected html elements via CSS / XPATH, then do cool stuff with it. It's just much more effective when writing lot's of JS and I couldn't imagine anything better right now. But hey who says I'm not wrong. So if you can find some stuff where mootools is directly less verbose and more elegant then jQuery then go ahead and it show it to me.

Thanks, Felix

rloaderro said on Jun 05, 2007:

hi Felix:

I guess your examples aren't entirely fair. For example, with just reformatting mootools is not too different than jQuery:

http://bin.cakephp.org/view/1659581237

But I think where mootools really shines is with OO and extensibility. For example, a mootools approach to the above might be:

http://bin.cakephp.org/view/1811996526

Which results in a much more elegant, one line solution. For motive of size and speed mootools doesn't really waste any lines of code. I guess it is a framework for programmers - in that regard. mootools brings the heavy machinery and it is up to you to add the polish.

Anyway, I was always under the impression that Prototype was a good thing?

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Class-Based_vs._Prototype-Based_Languages

Peace

Felix Geisendörfer said on Jun 05, 2007:

rloaderro: I took the example straight from the mootools docs. Anyway, your reformatted example is not much better. Why do I have to specify the HTTP method? Why do I have to manually invoke the request? Why do I have to use a class? Why do I need to specify an 'update' parameter? Can't mootools guess what I want to update? (And why can you suddenly use 'return false' to stop event propagation when you don't do so in your following example?)

And your polished up example doesn't really impress me either. I can do something similar in jQuery like this:

http://bin.cakephp.org/view/288283534

However, it's much better then extending the prototype of the Element object for many reasons. Once you start doing this then for (var p in el) loops will lead to different results than they would in vanilla Javascript. You have essentially hacked the core language. Now if you want to go down this path then please do. But personally I like to have my stuff as compatible as possible and not build my stuff on shaky ground.

And so far I've been nice enough to talk with you about manipulating elements that have an ID attribute. Where jQuery's true strength arises however is when you get into situations where you have many elements you need to select. Here is a little older example that shows you jQuery beats the competition in that regard:

http://jquery.com/blog/2006/10/18/zebra-table-showdown/

> Anyway, I was always under the impression that Prototype was a good thing?
Well every tool is good as long as you use it properly. To me 'Prototype' makes bad usage of Javascript's prototype feature because it essentially uses it to alter the JS language itself which is very confusing if you ever get into some more abstract programming in JS.

So what's next? You can continue to show me why everything that can be done in jQuery can also be done in mootools and argue that this shows how it's better or at least equally good. I will continue to explain the value of stuff that already ships exactly the way I want it to be over something that I have to manually "Configure" in order to make it work to my liking. And when it comes down to Conventions over Configuration I think even you should agree with me that jQuery does a better job at that ; ).

Thanks for the interesting discussion, Felix

Xaviego said on Jan 10, 2008:

jQuery help my on my sites, thx for this art, very helpfull!

Bibingio Alaksn said on Feb 04, 2008:

Looks great! I found lots of intresting things here. Please more updates.

Bibingio Alaksy said on Feb 04, 2008:

Hi Guys! What Your Blog Powered By? Keep up the great work!

Alabama Manz said on Feb 05, 2008:

Thanks for taking the time and effort in creating this content to share your knowledge with all of us.

kistov said on Feb 06, 2008:
Alabama Mana said on Feb 07, 2008:

Good site! It very impressive, easy to find helpful information. Keep up the great work.
http://accessory-gucci-handbag-womens.mustclickbuy.com/site_map.html accessory gucci handbag womens

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.