Why I moved from Prototype to jQuery



jQuery is a JavaScript library which follows unobtrusive paradigm for application development using JavaScript. jQuery inherently supports Behavior driven development and is based on traversing HTML documents using CSS Selectors. On the other hand, Prototype is a JavaScript library for Class driven development which makes life easier working with JavaScript. Prototype library has a good support in Ruby on Rails via helper functions.

I have always used Prototype library for most of my projects until I was introduced to jQuery three months back ... and it enchanted me.

The reasons

  1. Behavior driven development (BDD)

    Using jQuery, behavior(s) of HTML elements is defined separately from HTML code similar to defining style of an element using CSS. Lets look at a simple example to display alert box on click of an element

    1
    2
    3
    4
    5
    6
    
    
    
    $(element).click(function(){
      alert("warning");
      //fill stub for confirming this action from user
    });
    

    A complex example: All elements of class "speciallinks" should emit the following behavior:

    1. change their href link to "javascript:void(0);"
    2. generate logs on click
    3. onhover should change background color.

    1
    2
    3
    4
    5
    
    
    $("div.speciallinks").attr("href","javascript:void(0)")
        .click(function() {console.log("div.speciallinks clicked");})
        .hover(function(){$(this).addClass("hovered");}, 
                 function(){$(this).removeClass("hovered");});
    
  2. MVC + J

    MVC framework divides web development into 3 separate parts Model-View-Controller and Ruby on Rails is a great MVC framework. The View part of MVC framework comprises of HTML, CSS and JavaScript which is bulky, combining three different parts of GUI development into one. Moreover, using Prototype helpers in Ruby on Rails views messes up HTML and JavaScript together. Here, jQuery fits in nicely (due to BDD) to separate JavaScript(J) from Views(V) to visualize the framework as MVC + J which I find very powerful especially working with Ajax.

    Using jQuery, I keep all my HTML files are clean and clear as all the JavaScript code is kept in .js files defining behavior of HTML elements.

  3. Chaining of actions

    Chaining of actions for a HTML element follows DRY principals and increases readability of JavaScript code. If I want to add a bunch of operations on a single/multiple elements, it can be as simple as:

    1
    2
    3
    4
    5
    
    
    $("div.message").show()
      .append("<p>Action has been executed successfully")
      .addClass("flash");
    // chained functions can be on separate lines :)
    

    Now, this is possible because every method within jQuery returns the query object itself on which further methods can be applied to form a chain of methods on "selected" HTML elements.

  4. CSS Selector rocks!

    CSS Selectors are very powerful when playing with HTML DOM. jQuery is based on CSS Selectors to identify elements in a HTML document, which avoids tedious job of managing id attribute for each of my HTML tags. Most of id attributes can be avoided using right CSS Selector. Prototype does supports CSS Selectors via $$ function, but it doesn't fully leverages the power of CSS Selectors. I find Prototype working best with element's id attribute.

  5. No more checks for presence of an element

    In prototype, I always need to check if an element exists before applying an action to it. For example: I want to display user specific content in a div{id='user-box'} only if user is logged in (this div will exist on rendered page only if user is logged in). In Prototype I will do :

    1
    2
    3
    4
    5
    
    
    if ($('user-box')!=null) {
      // this if block is redundant with jQuery
      $("user-box").style.backgroundColor = "red";
    }
    
  6. Aids development process

    Using jQuery HTML code is clean and nearly untouched. My web designer can easily modify html and stylesheets without learning the Prototype library.

Examples

Here are few examples highlighting the difference in using jQuery and Prototype. (code in the examples may not be the shortest way possible.)
jQueryPrototype
Example1:
Tabbing system with 3 tabs of class "tabs" and ids=>["tabs1","tabs2","tabs3"] respectively. When user clicks on the link "show first tab", #tab1 should only be displayed.
1 
2 $("div.tabs").hide();
3 $("div#tabs1").show();
1 
2 $$("div.tabs").invoke("hide");
3      //or
4 $$("div.tabs").each(function(x){
5   Element.hide(x);
6 });
7 // then..
8 $("tabs1").show();
Example2:
Modify CSS of some element
1 $("#user-box").css("background-color","red")
1 
2 var a = $("user-box");
3 a.style.cssText +=
4        "background-color:red;";

For more examples checkout, Remy Sharp's presentation

I miss prototype

  1. On Ajax request, when a div is updated with a partial and this partial contains elements with JavaScript behavior, the behavior needs to be activated/reactivated. In jQuery I do not have to write a lot of code for this, but still I have to keep this in mind every time a partial is loaded with Ajax. In Prototype, each HTML element use to contain the corresponding JavaScript code along with it in the partial.
  2. Ruby on Rails helpers for Prototype library are awesome and makes life a lot easier working with JavaScript and Ajax.
  3. Prototype library provides Ruby like syntax in JavaScript for functions on arrays, objects, etc which further makes development easier and faster.
  4. With jQuery, element behavior gets activated only after DOM has been built and JavaScript files have been downloaded. For slow connections, this can be painful as there is a delay in activation of behavior.

Conclusion:

Jquery and prototype are both great libraries. For me, jQuery's philosophy (type less, do more, keeping things intuitive and unobstrusive) makes a big difference. But, I miss prototype core javascript additions. Waiting for jquery-rails integration. Some steps have been taken toward this goal. I would love to listen some of your personal experiences in shifting.

P.S: For using both libraries together, check this.
Filed in ruby on rails
Tagged as   
Posted on 06 November
33 comment Bookmark   AddThis Social Bookmark Button Updated on 23 February
Comments

Leave a response

  1. Tane PIperNovember 06, 2007 @ 04:49 PM

    On point 1 in “I miss prototype”, check out Live Query (http://brandonaaron.net/docs/livequery/) – this is a plugin for jQuery that allows you to manipulate the DOM and easily bind events after your HTML fragments have been loaded.

  2. Rich LaMarcheNovember 06, 2007 @ 05:28 PM

    A couple of untested tweaks of your Prototype examples:

    1

    $$(“div.tabs”).invoke(‘hide’); $(“tabs1”).show();

    2

    $(“user-box”).setStyle({backgroundColor: ’#f00’});

    This is a nice Prototype reference How well do you know prototype

    -Rich

  3. QuarksNovember 06, 2007 @ 06:12 PM

    Thanks for pointers @Tane and @Rich.

  4. DenisNovember 06, 2007 @ 07:53 PM

    JQuery helpers for Rails: http://code.google.com/p/jq4r/ or http://rubyforge.org/projects/jq4r/ Blog: http://jq4r.blogspot.com/

  5. SombodyNovember 06, 2007 @ 09:14 PM

    Prototype freaking slow

  6. WillNovember 06, 2007 @ 09:23 PM

    Do you have to give up scriptaculous if you move to jQuery?

  7. QuarksNovember 06, 2007 @ 09:39 PM

    @Will

    Yes, but you can use jQuery UI (http://ui.jquery.com/) instead.

  8. DerGuteMoritzNovember 07, 2007 @ 12:16 AM

    How about lowpro (http://svn.danwebb.net/external/lowpro/trunk/)? It’s a pretty neat behavior layer for prototype. I especially dig the way it lets you encapsulate behavior in separate classes. See http://www.danwebb.net/2007/7/17/low-pro-behaviours-101 and http://www.danwebb.net/2007/7/18/low-pro-behaviours-101-part-2

  9. Sam JonesNovember 07, 2007 @ 01:30 AM

    I’m just curious if you’ve played with YUI and if so, what you think about it.

  10. SudarNovember 07, 2007 @ 07:21 AM

    To add to your point, the file size is also an advantage for jQuery.

    — Sudar

  11. QuarkNovember 07, 2007 @ 08:02 AM

    @Sam, I am not familiar with YUI but have heard good things about it … will try it sometime. (added to my tolearn queue)

    @Sudar, definitely small file size gives a bonus point to jQuery … but after compression, I don’t think there is a significant difference between size of Prototype and jQuery.

    Quark

  12. LachlanNovember 07, 2007 @ 09:37 AM

    I’m no fan of either framework, however the Prototype code in example two is deliberately complex. It can actually be reduced significantly.

    JQUERY: $(”#user-box”).css(“background-color”,”red”) PROTO: $(“user-box”).style.cssText = “background-color:red;”;

  13. MarcoNovember 07, 2007 @ 11:20 AM

    Great post! Actually I’m working with rails and prototype, but after this article I will start to study jquery.

  14. kLNovember 07, 2007 @ 02:03 PM

    Turning links into bookmarklets (javascript:void(0)) is evil. If it’s not a link, just remove it! If removing is too difficult, remove href attribute. If it is a link with handler, use sensible alternative in href and stop propagation in onclick!

  15. PilafNovember 07, 2007 @ 02:26 PM

    In this example you’re creating a function redundantly (creating an identity function for Element.hide):

    $$(“div.tabs”).each(function(x){Element.hide(x);});

    You could’ve done:

    $$(“div.tabs”).each(Element.hide);

    I also think it’s a lot clearer than the jQuery counterpart.

  16. localhostNovember 07, 2007 @ 02:39 PM

    great article!

    “I have always used Prototype library for most of my projects until I was introduced to jQuery three months back … and it enchanted me.”

    This is identical to my experience. I resisted the move to jQuery initially, but as soon as i actually tried it i was blown away. Several months later, all my projects (commercial and personal) have been migrated to jQuery, and my html has never been cleaner.

  17. DaveNovember 07, 2007 @ 03:17 PM

    Hi, I’m interested in comparing jQuery and Prototype but your reasons are not compelling: 1) Similar BDD can be done with Protoype 2) Agree with you about using the RoR helpers, but – shock – you can put your Prototype javascripts in .js files too! 3) You can chain using Prototype 4) Prototype uses CSS selector too 5) You can acheive clean HTML with Protoype too! For even more unobtrusiveness take a look at Dan Webb’s lowpro or behaviours.js Soooo…

  18. QuarkNovember 07, 2007 @ 03:57 PM

    Hi @Dave,

    You are right, you can definitely make Prototype forcefully work like jQuery, why not use jQuery instead? ... its like let me make Java work like Ruby.

  19. kangaxNovember 07, 2007 @ 04:03 PM

    Dear author, I’m glad you like jQuery and that it fits your philosophy. That’s really wonderful and should be one of the main reasons to choose one over another. My concern here is that most of these points are quite misleading. I’m guessing what you were trying to say is that you like short syntax better and few of the jquery’s core concepts such as jQuery object wrapping. Most of what has been mentioned above can be easily achieved with prototype as well as with other popular frameworks. I hope readers of this blog understand that certain aspects of front-end development have been long time normalized among most of the libraries and only differ in syntax/philosophy.

    Best, kangax

  20. PilafNovember 07, 2007 @ 04:11 PM

    @Quark: I don’t see how doing anything you mentioned in the article would be “forced” if done in Prototype, it can actually do all of your examples quite gracefully (just not the way you presented it on the Prototype side). And comparing it to Java vs. Ruby is a terrible analogy IMO.

  21. batisteNovember 07, 2007 @ 04:48 PM

    For the point 1 jQuery interpret the javascript sent in HTML fragment after the fragment as been inserted in the page.

    So if you bind your events in the HTML fragment with a little function call, you don’t have to do anything else.

    If you find this ugly, like in the prototype case, you have to do it by hand in the callback. But it’s not a big deal.

    By the way the Live Query plugin seems to be a very nice idea :)

  22. AndyNovember 07, 2007 @ 05:19 PM

    This is exactly what I did a few months ago. I make Rails sites and have had lots of fun with Prototype and used the prototype helpers in abundance. Then a clientside developer showed me a few JQuery nuggets. Shock, awe and I changed.

    As for rails integration it is easier in Rails 2.0, the tip is not to use RJS. Just respond_to js and have your jQuery code in actionname.js.erb.

    Now I have wonderfully modular and light javascripts includes dotted around.

  23. Dustin DiazNovember 07, 2007 @ 09:14 PM

    Behavior driven development will only get you so far when you’re trying to build large web applications. Maintenance will become a nightmare and Prototype’s class system will most likely be more useful (between just these two). There is a reason Object Oriented design patterns have been practiced for many ages now.

  24. Kun XiNovember 07, 2007 @ 11:18 PM

    Would you take a look at dojo, www.dojotoolkit.org?

    It is like jQuery, and you have dijit for the UI as well.

  25. BrianNovember 08, 2007 @ 04:30 AM

    I love jquery and can’t imagine going back. As for having to activate behavior after loading partials, check out LiveQuery. Also I would recommend using minis_mor with jquery so that way you can have your actions respond with actual javascript, it has saved me a lot of headaches. I’m starting to write a few tutorials on my site about using jquery in rails as well as unobtrusive scripting. Finally, I think that the rails prototype helpers are horrible. It creates a lot of code duplication and makes graceful degradation very difficult. Javascript should be unobtrusive and in a js file. Oh, one last point you forgot to mention about jquery, the plugin architechture. I think that is a key part of jquery’s greatness.

  26. s0lnicNovember 13, 2007 @ 04:41 PM

    Short note: in what you described there’s nothing which cannot be done using Prototype!

    I must agree that jQuery has nicer syntax, but it’s not enough for me to make a switch, although I’m very interested in jQuery and have to give it a try in the real world.

    I’ve recently written an article where I compare the performance of jQuery and Prototype. The results are interesting, you can find them here:

    http://blog.solnic.in5.pl/2007/11/11/jquery-vs-prototype-part-i

    Cheers!

  27. AndreasNovember 18, 2007 @ 04:19 PM

    I think this just a question of flavor. We need both librarys and they need each other.

    However, this looks quite promising to me, too. “jRails is a drop-in jQuery replacement for Prototype/script.aculo.us on Rails. Using jRails, you can get all of the same default Rails helpers for javascript functionality using the lighter jQuery library.” http://ennerchi.com/projects/jrails

  28. Philippe RatheDecember 01, 2007 @ 05:15 PM

    @Brian:

    To use Plain Old Javascript into your views, since Rails 2.0, you don’t need the minus_mor plugin because it’s now possible to have javascript files with erb (.js.erb). That is your minus_mor (.ejs) files I’m talking about.

  29. Philippe RatheDecember 01, 2007 @ 05:20 PM

    Question for jQuery and Rails developer.

    Since we have the choice with jQuery for AJAX, which approach would you take beteween:

    1) to use callback function to receive xml or json datas and update the page.

    OR

    2) not to use callback function and eval the javascript snippets return by the server (like RJS is doing)

    Thanks

  30. KyleMarch 29, 2008 @ 12:47 PM

    I’ve been mostly using Prototype for the last couple years and was just doing the rounds to see how other frameworks are these days. I love Prototype and it is great to develop on top of, but for most sites I think it is too much (how much of that 75kb file goes unused on most sites?) which is why I was looking at what else is available. Prototype can be compressed down a long way (less than 30kb with scriptaculous effects) but how small could a framework be if it was designed for the common things and not so much to be built on top of (I guess that would mean it’s not a framework though, right)? I’d make my own but I’d never have the patience to make sure it works in so many browsers as other frameworks.

    But I must say, this post of yours is completely misleading and you should probably put a disclaimer saying as much right at the top. Everything you say can be done with Prototype. I mean, what you call behaviour driven development was the Prototype developers recommended way of using it back whenever I first found Prototype.

    With your code examples I have to wonder if you are purposefully being misleading to make Prototype look bad. Why would anyone know about show() but not hide()?

    However, your example of BDD with jQuery actually appears to me to be far inferior to how Prototype handles DOM events. So maybe you’re trying to make jQuery look bad too?

    Concerning your fourth point about why you miss prototype (“With jQuery, element behavior gets activated only after DOM has been built and JavaScript files have been downloaded.”) then I have to wonder how well you actually understand the DOM and if you even know what you’re doing.

    Now I might come off as a bit of a Prototype fanboy, but remember that I did come across this post while looking for potential replacements.

  31. Ódyr vefhýsingSeptember 30, 2008 @ 09:05 AM

    Prototype has Class.create … JQuery hasn´t. Regards, Ódyr vefhýsing.

  32. FrankJanuary 16, 2009 @ 08:46 PM

    Nice article. Thanks. Something I’ve found useful is this awesome jQuery Cheat Sheet for the iPhone today.

    http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=302090867&mt=8

    There’s also a CSS Cheat Sheet from the same guys.

    http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301093674&mt=8

    They’ve saved me a lot of time. Hope you find them useful too.

  33. NoiseFebruary 19, 2009 @ 03:24 PM

    @Quarks: I think you’re missing the point. Rails helpers are a bad way to go with javascript, no matter which framework you use.