HomeBlogPrototype JS vs jQuery - A Comparison

Prototype vs jQuery, Round 1, FIGHT!

Published October 29, 2009


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!

blog comments powered by Disqus

1 COMMENT

Michael Butler

Michael Butler

Michael joined the RustyBrick team in 2008 to focus on transitioning existing web sites to new & enhanced platforms. He graduated from Rutgers University in 2005 and holds a B.S. in Computer Science.

This article is under Programming, Web Programming

There is 1 comment for this post

Connect With Us

Send Us a Message

Do you wish to give us feedback on one of our apps, send us a message or explore a proposal? Fill out the form below and we'll get back to you pronto!

Visit Us

250 West Nyack Road, Suite #200 West Nyack, NY 10994
Get Directions

Call Us Toll Free

877-GO-RUSTY
877-467-8789

Telephone

845-369-6869

Fax

845-228-8177