Prototype vs jQuery, Round 1, FIGHT!


Prototype vs jQuery
Before I joined RustyBrick I had been coding basic JavaScript functionality into websites mostly "by hand", in other words, without using a well defined third party package. The exception is the Yahoo! User Interface (YUI) which assisted me with AJAX style programming. Then, thanks to the RustyBrick team, I was introduced to the Prototype JS library which provides all sorts of user interface development shortcuts and cross browser compatibility assistance. Now I wouldn't even dream of coding another website without it (or a similar packaged library as you'll soon see).

Everything was fine until I was asked to enable Google's javascript based Virtual Keyboard gadget, with newly added Hebrew support, on an upcoming project. We had already written a lot of Prototype JS functionality into the site when I was hit with an incompatibility between the virtual keyboard and the Prototype JS library. While this was most likely an oversight by Google, it also represents a flaw and feature of the library -- permanently augmenting native JavaScript objects with it's own methods.

After seeing examples of what jQuery had to offer, along with solid documentation and examples, I decided to start using jQuery in future projects, whenever possible. After a month of using it I can offer some comparisons.

To give a quick example of Prototype, lets say I want to color each paragraph red upon clicking a link inside of that paragraph, and let's assume the paragraphs are coming from a database so we don't know how many there will be. Here is how to do that with Prototype:

<!-- HTML -->
<div>
    <p>Lorem ipsum <a href="#">Click Me</a></p>
    <p><a href="#">Click Me</a></p>
    <p><a href="#">Click Me</a> Lorem ipsum </p>
    ...
</div>

<script type="text/javascript">
$$("div p a").each( function(element){
    element.observe("click",function(pEvent){
        // 'this' refers to the DOM element on which the event occurred.
        $(this).up("p").setStyle({backgroundColor:"red"});
    } );
} );
</script>

To script the same thing in jQuery you'd do this:

<script type="text/javascript">
$("div p a").bind("click",function(){
        // 'this' refers to the DOM element on which the event occurred.
        $(this).parent().css("background-color","red");
} );
</script>

Live example:

Lorem ipsum Click Me

Click Me

Click Me Lorem ipsum

Click Me Lorem ipsum

Click Me Lorem ipsum

The differences in this small example are as follows:

  1. jQuery's $() function can be described as a more powerful version of Prototype's $$(). If you need to grab one or more elements (with or without ID), you use $ and specify the CSS selector, like "div p a" as a parameter. If you just need to get an element by ID, you would still use a CSS selector like $("#my_element_id") instead of Prototype's $("my_element_id"). You can grab an (unmodified) DOM element from this by index with [x] after it.
  2. Only one anonymous function instead of two: I'm binding a function -- triggered by a "click" event -- to each div > p > a element, without using an each function. This is because most jQuery functions are automatically called on each of the elements you select with your CSS query. In some cases, it will only act on the first element even if multiple elements are selected (such as the val() function which grabs the value of the first matched element). This saves you from having to code an anonymous "each" function all the time. Of course, the each() method is also available if you need more customized handling.
  3. You can use the css() function to change the styling of elements by using their regular css attribute name in quotes. Multiple attributes are supported at once by passing an object.

Because the use of jQuery is centered around using CSS selectors in general, not just element IDs, I found myself not worrying about assigning so many unique id attributes to elements all over the page server-side, especially if the HTML elements are generated dynamically by database content (which would then require a server-based increasing index, like myelement_1, myelement_2, etc). I can just assign a unique id to a container somewhere and then easily work on elements within that div using CSS selectors like $("#mydiv ul li").doStuff(). This turns out to be a cleaner and faster way to code and results in less cooperation between the client and server.

Other examples of what you can do quickly with ALL the stuff returned from $():

  • html() - gets or sets the inner html of all the matched elements.
  • val() - gets or sets the value of the first matched element (will return the selected value if the element is a select box)
  • hide() / show() - shows or hides the matched elements
  • addClass() / removeClass / toggleClass - self explanatory
  • bind() - attach an event handler to matched elements
  • live() - attach an event handler to matched elements -- and future matched elements if more happen to be created!

Other cool shortcuts I've found with jQuery:

  • the bind() function, which is used to listen to an event on an element or elements, can be specified with multiple event types at once, like this: $("input#my_email").bind("focus keyup blur",myFunctionName); // this will invoke myFunctionName() on focus, keyup, and blur events. Simply separate events with spaces.
  • I can actually use the CSS selectors :first and :last -- The prototype documentation says you can use them but I personally couldn't get them to work in Prototype using simple code like $$("a:first") or $$("a:last") to grab the first or last link of a document. In jQuery that works fine.
  • Most its functions are compact and abbreviated and are faster to type and easier to memorize. Compare:
    • addClassName() vs addClass()
    • removeClassName() vs removeClass()
    • getValue() vs val()
    • readAttribute/writeAttribute vs attr()/attr("name")
    • update() vs html()

It's not just the core library that is important  -- while Script.aculo.us goes with Prototype to provide animation effects and other UI shortcuts, jQuery UI goes with jQuery. I've found jQuery's UI library and other third party addons to be much faster and simpler than that of Prototypes. For example, jQuery UI has a wonderful draggable/droppable extension that allows you to quickly specify which things can be dragged, where they may be dropped, and dynamically change these rules at any time, sometimes simply by adding or removing a CSS class name to or from the element or spot. Also, jQuery Tools has proved to be a very valuable add on for tabs, tooltips, and overlay handling.

jQuery also strives to be optimized, providing minified/compact/combined versions which results in speedy load times.

 Prototype JS may prevent headaches, but jQuery prevents even more headaches. I will highly recommend it to all JavaScript developers!

Bookmark and Share    
blog comments powered by Disqus

5 COMMENTS

posted by VĂ­tor on: Jul 7, 2010 02:04pm

Nice post. the thing is, and about performance between that two frameworks?

posted by web designer in sri lanka on: May 28, 2010 09:59am

Thx, this is a good Artical web designer in sri lanka http://www.springtec.net

posted by web design company sri lanka on: May 28, 2010 10:00am

web design Thx, this is a good Artical web design company sri lanka http://www.springtec.net

posted by Alex Fierro on: Oct 29, 2009 08:25pm

Excellent post... but I'm too stuck in my ways to make the jump to jQuery. I'll miss Prototype too much!

posted by OneNerd on: Dec 28, 2009 02:46pm

I use both, but I must say that Prototype has a much more comprehensive JavaScript (the language) overhaul, where jQuery seems to be laser-focused on DOM manipulation. So I use the jQuery noConflict() to assign jQuery() to $j. Primarily, I like jQuery because I can do this: $('.someclass').click(function(){}); Very useful.