Advertisement

Learn 3 Excellent JavaScript Libraries at Once

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

Let's go with a hands-on approach today. We are going to write a tiny snippet of code in jQuery and then port it over to several different libraries. Outside of that chunk, we are going to look at how to implement some basic, necessary functionality in each of these libraries. Sounds fun? Let's dive in!

A Word From the Author

JavaScript frameworks are a boon when you have lots of ideas to turn into functional, clean code. And with the meteoric rise of web applications using AJAX technology, frameworks like jQuery are necessary to reduce the time you spend implementing the required functionality. And looking around you see jQuery this and jQuery that with little to no mention of other frameworks. Fact is, there are a ton of other frameworks which are just as elegant as jQuery. Today we are going to take a look at two frameworks which promise to make writing code easier. Do note that I use the words library, framework and toolkit interchangeably. I am not going to go into semantics and neither should you. Each of these libraries try to accomplish different things. We are only going to look at the parts where their intended functionalities overlap.

Basic Functionality

Outside of esoteric and/or dedicated apps, most people's JavaScript code can be broken down into chunks which take care of the following functionality:

DOM ready

A JavaScript developer runs into this problem sooner or later: his pristine code just won't run. He has debugged the code again and again but to no avail. The problem is that the code is just placed at the top of the page. When the script is executed, the elements he is referring to in his code don't even exist in the DOM leading to these errors.

Remember, script calls are synchronous. This means that when a browser sees a script tag, it ceases loading everything else until the scripts are loading. This is in stark contrast to its general loading mechanism where other objects are often loaded asynchronously.

You could always work around this by just placing the code at the bottom of the page but you never know. With this in mind, most libraries provide a DOM ready function to make sure the code is only executed after the DOM is ready to lock n' load but before the images are completely loaded.

With raw JavaScript, you'd be looking at something like this.

window.onload = someFunction;

Accessing elements

You obviously want to access specific elements and manipulate them somehow. Unfortunately, IE is rather finicky and can break your code. To let developers write better code, each library provides a cross browser method which lets you access a specific element. Most libraries use CSS style selectors to zero in on their target elements to make the learning curve shorter and much more importantly, cleaner looking code.

Without a framework, you'd have to do this:

var elem = document.getElementById('header');
var io = document.getElementsByTagName('input');

Manipulating elements

Of course, once you've obtained the element, you'd want to perform some operation. This includes adding or removing a class, toggling its visibility, changing its dimensions, editing its contents and so on. As always writing all this in raw JavaScript can be painful. Each of these libraries provide wrapper functions to do all of the above noted work and lots more.

With raw JavaScript, your code would look like so:

document.getElementById("title").innerHTML="Title";

Manipulating the DOM

Often, you'd want to directly change the nodes in the DOM. You might want to create a new wrapper object to which you want to put your recent Twitter status in or you might want to remove a div element for an email app you are writing. In each of these cases, you'd want to manipulate the DOM efficiently and all of these libraries provide methods to do so in a clean manner.

Appending an element would take this much code with raw JS.

var myElement = document.createElement("<div>Sometext</div>");
document.all.myBody.appendChild(myElement);

Hooking up events

Events are the building blocks of any application and one of the more peskier parts of cross browser scripting. The thing is, W3C defines one way and IE does its own thing. To over come this, all of these libraries provide ways to attach or unattach even handlers to specific events of the element.

Hooking up events in raw JavaScript.

element.addEventListener('click',doSomething,false)

AJAX request

Native JavaScript using the XHR object is tedious to write and debug. In order to let developers write code more easily each of these frameworks abstracts the tedious details of implementing an AJAX request behind a simple function call with methods to call when the request succeeds or fails.

I am not even going to try and post some code to make AJAX request with raw JS. Instead you should look at Jeffrey's excellent screencast. Shortly, we'll see how a framework drastically cuts down your code.

The Functionality we are Looking to Code

Nothing fancy really; we'll build a simple demo. The markup looks like so:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Net Tuts</title>
</head>

<body>
<p id="text">This is some sample <span id="maintrigger">random</span> text. Click on the word random 
to modify the DOM by creating a new element and appending it to the current content. 
</p>
</body>

</html>

We have some text within a p element. We have the word random wrapped in a span element with an ID of maintrigger. Every time an element the element with an ID of maintrigger is clicked, a new div element needs to be appended to the paragraph element containing the text "clicked". This simple demo touches all of the basic functionality requirements including accessing elements, hooking up events and appending elements except that of AJAX abstraction and will let us get a feel for each library.

Before we look at the other libraries, it's best we look at how jQuery lets us do each of them.

jQuery

Ah, all pervading jQuery. It has been the talk of the town among web developers for a while know and rightly so. jQuery doesn't try to do too many things. You aren't going to find a dozen plus widgets bundled with the base build or ways to support classes or class based objects. jQuery focuses primarily on the DOM and I think they've done an excellent job.

If your work is primarily DOM related, jQuery is the way to go. The syntax is among the easiest and a lot of times it feels like reading pseudocode than actual, working code. The community is big and friendly and there are a ton of plugins you could just drop in for added functionality. Plus there is the UI library if you want to add some common widgets to your site.

jQuery's user base includes:

  • Google
  • IBM
  • Microsoft
  • Amazon
  • Dell
  • Twitter
  • ESPN
  • Digg
  • Netflix
  • Mozilla
  • WordPress

Extremely impressive if you ask me.

Now, we'll look at how jQuery lets us reduce the time we spend coding before we look at the other frameworks.

DOM ready

$(document).ready(function () {
    // Your stuff here
});

When writing your jQuery code it is imperative that you put your code inside this section. Here we ask the code to be executed when the DOM is ready to be manipulated. You can either pass in a functions name or just write all your code inside an anonymous function as in the example above.

Accessing elements

var container = $("#main");
var posts = $(".post");
var headings = $("h1");

Simple as it gets. We first create a variable to hold a reference to the DOM node since we don't want to look for it again and again. $ is an alias to the jQuery namespace. We just pass in the id, class or tag of the element just as you'd do if you were writing a CSS declaration. Passing in CSS selectors works just as you'd expect. Examples like the below work too.

$("span:has(a)").doSomething();
$("ul li:nth-child(3)").doSomething();
$("p:hidden").doSomething();

Manipulating elements

$("div").attr("class", "clicked");
$("div").html("<span>Hello</span>");
$("span").addClass("current");

Changing an elements attributes, its contents or the classes it has are fairly trivial. We just access the required element and call the necessary function. The attr method lets us change a specific attribute of an element, the html method lets us specifiy the HTML content and the addClass method needs no explanation.

Manipulating the DOM

$("#post").after("<div>Comments</div>");
$("p").wrap("<div></div>");
$(".comment").append("<span>Posted by</span>");

Adding elements after the specified element, adding content inside an element or wrapping the passed element with another is just as easy. We obtain the element and then call the function which best suits our need.

Hooking up events

// Using anonymous functions
$("#submit").bind("click", function(e){
// Your code here
});

// Passing in a functions name    
$("#submit").bind("click", evHandler);

Hooking up events is similarly easy. We obtain the element and then call the bind function. The first argument is the event type and the second is the code to execute when the event is triggered. You can either pass in the function's name or just create an anonymous function and place all your code inside that.

AJAX request

$.ajax({
  type: "GET",
  url: "test.html",
  success: function(xhr){
    //Some code here
  },
  error: function(xhr){
    //Some code here
  }
  
  $.ajax({
  type: "POST",
  url: "test.php",
  success: function(xhr){
    //Some code here
  },
  error: function(xhr){
    //Some code here
  }

});

You only need 3 lines to make a barebones AJAX call. Specify the type of request, the URL and you are good to go. Success and error functions can be defined to specify what happens if their namesakes occur.

Equivalent code

To achieve the desired functionality mentioned above, your jQuery code would approximately look like so:

$("#maintrigger").click(function () { 
      $("p").after("<div>Clicked</div>");
    });

3 lines is all it takes. We select the necessary elements, call the click function, create an anonymous function and append a div element. It sounds a lot more complicated than it actually is really.

Now that we've looked at the jQuery code, we can explore the other libraries.

Prototype

Prototype is the grand daddy of JavaScript frameworks. It provides all the niceties you'd expect off a mature framework and then adds a little more. It also provides a number of library functions to help you write nicely abstracted, object oriented code.

Prototype's user base includes:

  • Apple
  • NASA
  • 37 Signals
  • hulu
  • Rails
  • Backpack
  • Gucci
  • last.fm
  • Wired
  • Prada
  • Dreamhost

A lot of well known, top tier names there. As I said, Prototype used to be the framework of choice for a long time before jQuery came in.

Now that the introductions are done, let's see how Prototype can help you write better JavaScript.

DOM ready

document.observe("dom:loaded", function() {
  // Your code here
});

The above is Prototype's version of DOM ready. It looks weird at first if you are coming from jQuery but it is just as simple. The observe function listens for the passed event for the lifetime of the document. We just pass in the necessary event and envelop all our code inside an anonymous function just like with jQuery.

Accessing elements

//Access an element with an id of post
$('post');

//Use the CSS selector engine
$$('.comment');

$ provides an alias for the document.getElementById method. It lets you find elements with the passed ID value.

$$ lets you use CSS selectors instead. It takes as it's arguments any number of CSS selectors and returns the specific element or an array of them. Just as with the jQuery selector engine, you can use all sorts of nefarious CSS3 selectors including child selectors, attribute selectors and even pseudo classes.

Manipulating elements

$('post').addClassName('author');
$('container').getWidth();
$('post').hide();

Prototype provides a number of powerful method to work with the returned element. Remember, you need to access this through the $ object. Which means you first need to save the reference before you can manipulate the element in what ever way you see fit.

Manipulating an element is as simple as obtaining a reference to the element and calling the necessary function. You can do lots of things from setting sttributes, to hiding the element.

Manipulating the DOM

$('post').wrap('div', { 'id': 'container' });
$('post').update('<p>Some random text</p>');
$('post').insert('div', '<p>Some random text</p>');

The first method wraps the passed element with a described element settings its various properties in the process. The update functions replaces the content of the passed element with the one we want. Insert inserts plain text or HTML snippets at the top, bottom, before or after the element. Instead of using separate methods like append and after as in jQuery, we just need to specify the position and we are done.

Hooking up events

// Using anonymous functions
$(btn).observe('click', function(event){
//Your code here
});
 
// Passing in a function's name 
$(btn).observe('click', doSomething);

As I mentioned before, the observe function lets you hook up events to their event handlers. We first obtain a reference to the element and then call the observe method passing in the event's name and function as parameters. If you don't want to create a separate function just for this, you are always free to create an anonymous function and put all your code inside there.

AJAX request

new Ajax.Request("test.html", {
  method: 'get',
  onSuccess: function(transport) {
  // Some code here
  },
  onFailure: function(transport) {
  // Some code here
  }
});

new Ajax.Request("test.php", {
  method: 'post',
  onSuccess: function(transport) {
  // Some code here
  },
  onFailure: function(transport) {
  // Some code here
  }
});

Prototype provides extensive wrapper functions for making an AJAX request. I've shown the lowest level AJAX POST and GET requests here. There are a ton of other specialized methods for AJAX requests including an auto updater.

Equivalent code

To achieve the desired functionality mentioned above, your code would approximately look like so:

$("maintrigger").observe('click', function(event){
  $("text").insert('<div>Clicked</div>');
 });

Still a 3-liner. What we are doing is similar to the jQuery code, the syntax is just different. We use the observe function to attach the click event to the code we created in an anonymous function. We just insert some text to denote that the process was a success.

You'll see that generally we are doing the same thing jQuery does, just with a different syntax and a few differences. When your work is not DOM-centric and you need proper objects to properly leverage your ideas, Prototype is the framework to choose.

Mootools

Mootools doesn't profess to be an easy framework to learn. Let's face it, its web page says it is a web application framework for intermediate to advanced web developers. Don't let them fool you. It is an extremely elegant framework which lets your create extremely classy JavaScript. It focuses on JavaScript as a whole instead of just the DOM. With that in mind, it provides a number of functions to speed up your workflow and also extends the DOM wherever possible. And just like Prototype, it contains a class creation and inheritance system which should make those coming from C# or Java more comfortable with JavaScript.

Companies which use MooTools include:

  • Ferrari
  • Vimeo
  • Palm
  • Nintendo
  • Formula 1
  • GameSpot
  • CNet
  • Joomla
  • phpMyAdmin
  • Jeep
  • Bing

Another framework with a very impressive user base.

Let's now look at how MooTools makes your life as a JavaScript developer easier.

DOM ready

window.addEvent('domready', function() {
    // Your code here
});

It might look complicated but don't fret. It just looks different. We attach the domready event of the windows to the anonymous function. The addEvent lets us attach events to their handlers. MooTools defines the domready event which we make use of here. As usual we wrap all our code in an anonymous function and place it inside. There! That wasn't so hard, was it?

Accessing elements

// Use the $ function
$('someElement');

// Use CSS selectors
$$("#main");
$$(".post");
$$("h1");

Just like with Prototype, you can use the $ function as an alias for direct retrieval or use the $$ function to use much more intuitive CSS selectors.

Each of these methods return either a DOM element or an array depending on which you use.

Manipulating elements

$('someElement).hasClass('clicked');
// Returns true if the element indeed has that class

$("someElement").setProperty('class', 'clicked');

$("someElement").empty();
// Empties the element of all its children

MooTools provides a number of methods to manipulate a specific element including setting its attributes, changing its contents and so on. If you are interested, you should consult the MooTools documentation here

Manipulating the DOM

var someElement = new Element('div', {id: 'mySecondElement'});
someElement.inject(someOtherElement);
// Injects the contents of someElement within someOtherElement

$("someElement").destroy();
// Removes element and all its children from the DOM

$('someElement').clone().
// Makes a copy of the element

Just like most libraries, MooTools provides a plethora of functions to let us modify the DOM. Everything from appending content to completely removing a node from the DOM is included.

Hooking up events

// Using anonymous functions
$('myElement').addEvent('click', function(){
    // Some code
});

// Passing in the functions name
$('myElement').addEvent('click', doSomething);

As I noted above, we use the addEvent method to attach the event to its handler. We pass the name of the event to the function and as usual we are free to choose between creating a separate or anonymous function to put our code into.

AJAX request

// A GET request
var myRequest = new Request({method: 'get', url: 'test.html'});
myRequest.send();

// A POST request
var myRequest = new Request({url: 'test.html'});
myRequest.send(someData);

Setting up an AJAX request is similarly easy. MooTools provides a robust Request class which lets use make POST or GET AJAX requests. The default method is POST so there is no need to specify if you are making a request.

Just like other frameworks, the request class supports callbacks for success, error and completion.

Equivalent code

To achieve the desired functionality mentioned above, your code would approximately look like so:

$$("#maintrigger").addEvent('click', function(){
   var elem = $("text");
   var someElement  = new Element('div');
   someElement.appendText("Clicked!").inject(elem, "after");
});

Slightly more verbose than the other 2 implementations but here we actually create a div node from scratch and then append it. Also we store a reference to the paragraph element itself. After that, we simple add the necessary text into the newly created element and then append it to the DOM.

More verbose? Yes. More difficult? Definitely no. It is just a different style of coding.

Code Comparison

jQuery

$("#maintrigger").click(function () { 
      $("p").after("<div>Clicked</div>");
    });

Prototype

$("maintrigger").observe('click', function(event){
  $("text").insert('<div>Clicked</div>');
 });

MooTools

$$("#maintrigger").addEvent('click', function(){
   var elem = $("text");
   var someElement  = new Element('div');
   someElement.appendText("Clicked!").inject(elem, "after");
});

All of these snippets of code essentially do the same thing. Just in different styles and with differing amounts of control.

Experiment

This article was in no way intended to compare these frameworks. Instead I wanted to call the reader's attention to the other viable solutions available outside of jQuery. It's not that jQuery is bad. I love jQuery, it is a wonderful framework but it primarily focuses on the DOM and DOM alone. If you are looking to write a web application or a renderer or some other cool thing, creating maintainable, extensible, clean code is a priority. It is for these kinds of scenarios when it make more sense to resort to another framework.

I could choose only two frameworks in this article due to space constraints. There are a number of other, just as powerful, frameworks including Dojo, YUI, Rico and GWT which also deserve your attention.

Hopefully I've piqued your interested in alternate JavaScript frameworks today and am truly hoping you are going to experiment with other frameworks. Let us know how the experimentation goes in the comments. Happy coding!


Advertisement