Why jQuery ?

(and not Prototype? Or Scripty? Or doing JavaScript by hand?)

JavaScript and Me

Having been a Java server-side developer for some years, I did manage to avoid doing (real) work in JavaScript to this day. My adventures in the web client side were few and far between, and did let me with rather mixed feeling, remembering projects that were difficult to test, awkward to debug and a language that allowed all from the best to the worst, and more often the worst.

When I did read for the first time about "Server-side JavaScript" (some years ago, it was about Rhino, a JVM implementation of JavaScript), my first reaction was: why would I ever want to program in JavaScript outside of a web page? (for those of you asking the same question about Node.js, I heavily recommend this article, as Node.js is not so much about JavaScript than it is about event based I/O).

Then, those last years, JavaScript became more and more (omni)present, with GMail and GoogleMaps, and the emergence of more and more web based dynamic applications. To the point that it was becoming increasingly clear that we (the programmers not yet knowing it) would need to learn JavaScript. I must admit, I was quite convinced, but not totally motivated.

From Rails to jQuery

The Rails framework was a part of this "web emergence", and quickly begin to add options to tap on those new "dynamic" possibilities for effects or Ajax functionalities. The first time that I use it, Prototype and Scriptaculous were the JavaScript frameworks of choice. When we came back to Rails this time, it was just about the switch from Prototype to jQuery (well, for the default option, as Rails still support both).

It was probably just what I needed to take a more thorough look at jQuery: a mature JavaScript framework (being there for some years already), used by many people (so help is available, for example on Stack Overflow), with good documentation and a large plugin ecosystem. As our time is most precious in this period, we know that we could not afford to learn to much different frameworks at the same time, so jQuery it is.

Why you need a JavaScript framework

While not the bazaar that some make of it, JavaScript still suffer from many plague, unequal browser support being probably the first: let's say you've done a niece piece of JavaScript for your new website. It's working pretty well ... on FireFox. But will it run on Internet Explorer 7? 8? On Safari? ... Of course, solutions exist to test on different platforms. But this costs time. And anyway, do you want to clutter you code with chunks of

if (browserName=="Microsoft Internet Explorer")

Above and beyond of all its remarkable API, the first benefit that you gain from using jQuery is peace of mind from many of JavaScript incompatibilities problems, letting you concentrate on what you try to achieve.

Learning jQuery

Even if the web is full with jQuery example, I suggest you pick the "jQuery in Action" book. It is a really good investment, with progressive lessons, nice examples and a very nice set of labs, allowing to "play" with jQuery with immediate results. I would personally recommend the eBook version, because you will want to read it at your computer anyway, for experimenting.

With what the book cover and some exercises you can then use the web API for the details on the different methods (even if lots of them are already documented in the book for reference). I cannot emphasis enough the need to have some project to apply this knowledge as soon as possible, if possible a "real one". Well, I had the Bemco, so it was a quite good motivator.

jQuery provides four large areas of functionalities:

Selectors

Almost all of jQuery API works on a "working set", actually a list of DOM elements (or, to be more precise, a list of jQuery wrapper around DOM elements - more on that in a short while). To constitute such a list, jQuery provides a very powerful series of "selectors" : expressions selecting some elements in a DOM. The most positive things about them is that... you already know them. jQuery selectors are CSS expressions. Compare those two examples, selecting the "li" items inside "ul":

CSS:

ul > li {
  property:value;
  ..
}

jQuery:

$("ul > li") # do something with all the "li" elements

The "$" is a shortening of the main "jQuery" function. As you can see, both use exactly the same syntax, so if you know CSS, you already know how to select elements in jQuery. If you don't, well you'll need to learn it anyway, so from one side or the other, it probably does not matter. Class or id can also be used to select elements :

$("#my_div") #select the element with id = my_div
$(".important") #select the elements with "important" class

Once an element is selected, you can use various operations on it (e.g. update the html, change its class or attributes):

$("#notice").html("new content"); #replace html with "new content"
$("li").addClass("important"); #add a class "important" to all li

Events

The DOM event model can be quite tricky to use, especially (again) with the difference between browser. jQuery proposes a nice unified model, with two main elements: the event ("click", "hover", ...) and the handler (a function receiving the element generating the event) that come globally in two flavors, one creating the handler with a specific function on the element triggering the event, the second using "bind", specifying the type of the event and the handler.

$("img.button").click(function() {
  ...
}); # using the event on the element
$("img.button").bind('click',function() {
  ...
}); # using bind

The second form allows an interesting variation, which uses the same syntax but the "live" function, which creates handler on all elements respecting the selector. Even if they do not exist at the time the "live" method is called. Which is pretty useful, for example to add some behavior on elements that are created dynamically.

The event system is really interesting in the context of Unobtrusive JavaScript (UJS), as no JavaScript at all need to be inserted in the HTML code (no more "onclick=" in button tags), achieving a nice decoupling between the two.

Ajax calls

jQuery provides various options for Ajax calls, allowing for the different methods (POST, GET), format (HTML, JSON), but more interestingly for various "callbacks", some nicely preconfigured for some typical operations. The parameters to be passed are a simple array of name/value pairs.

$.post("/customers/changeName",[{"name":"customerName","value":customerName}],
	function(data){
		$("#notice").html("Customer updated" + data.customer.name);
	},"json");

A good example is the "load" method, that calls the remote operation and loads the result in the given HTML element :

$('#result').load('ajax/test.html');

You can choose between two main way of work:

  • Call the method, have the server return well formed HTML, and put/append it to your DOM
  • Call the method, have the server return informations, and adapt the DOM in the callback

The first one is easier, but does not fill all situations, in the second case, be sure to have the server return a JSON object, as it will make the manipulation in JavaScript much easier.

Effects and jQuery UI

Last but not least, jQuery provides "eye candy", aka "effects". While the code library already gives some nice one, be sure to check jQuery UI, which, while a plugin, is almost part of the main library.

Some lessons hard learned

Most of my experience with jQuery has been very nice, with functions working as documented, and sending informing exception when given incorrect parameters. Still, starting with JavaScript is not exactly without hassle:

  • You need Firebug (Firefox extension): the debugging capacities of FireBug are impressive... And absolutely necessary, as are the error messages that are shown when something bad occurs, the DOM explorer, and the description of both request and response in an Ajax request. Not using Firefox? Install it for this. It will help you tremendously, it certainly did for me (I run Firefox only for Firebug, at this point).
  • Be careful of the difference between "this" and "$(this)", especially in an event handler. The first one is the "raw" HTML element, the second one is the jQuery wrapper. While the first maybe faster, it will frequently throw a "method not found on element", as jQuery greatly enhances the operations allowed on an element.
  • The notion of "type" in JavaScript is quite fuzzy (JavaScript falling in the "Prototype-Based" languages), especially when coming from a strongly typed language (static or dynamic). In the situation above, I tried to print the "types" of this and "$(this)", which did not help me at all. JavaScript objects are more like hashes than objects with concrete type, so asking for one is not so difficult as it is pointless.
  • When using jQuery Ajax function, you need to specify the format (JSON, most probably), if you do not, the function callback will not be called, without throwing any message.
  • jQuery makes things so easy that it did took a while before I stumble on my own JavaScript incompetency. While jQuery certainly helps tremendously, learning some "down the earth" JavaScript is very important ("jQuery in action" has a "JavaScript primer" appendix).

The more I'm using jQuery, the more I like it.

Martin