jQuery

The Colorful Letterbox example explained

This is a little introduction to the power of jQuery. It explains most of the jQuery features used to create the 'Colorful letterboxes' page. It contains CSS, JavaScript, and HTML all in one comprehensive file. The only outside resource is a minimized version of jQuery loaded from the Google CDN:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

The advantage of downloading from Google as opposed to hosting on your own domain is an increased likelyhood that the library will already be cached in the browser.

The initial HTML of the page looks a bit anorexic. Much of what you can see pretty quickly after the page has loaded gets created dynamically with jQuery, playing out one of its core strengths.

  <body>
    <table>
      <tr class="letters"></tr>
    </table>
    <table>
      <tr class="colors"></tr>
    </table>
    <table class="write">
      <tr></tr>
    </table>
  </body>

Adding jQuery code

Having loaded the jQuery library, the most prominent member of its toolset is the $() function. Yes, the name is simply '$'. It is an alias for the longer form 'jQuery'. It is the Swiss Army Knife of web programming. So lets look at the blades and tools it has stacked up. They are available by feeding parameters of a large variety of types and values to the $() function. jQuery then analyzes what parameter types have been passed in, something supported by the dynamic nature of JavaScript, and acts accordingly.

The first type of parameter is a function. Such a function is usually declared anonymously right on location. The whole code pattern then stretches to the closing combination of a curly and round bracket.

    $( function() {
       ...
    });

The execution of the function is delayed until the document structure of the page has been fully loaded. At that time the browser may still be busy retrieving images from their sources, but the HTML tags have all been converted in to a model of the document built from individual objects (elements, attributes, styles and text strings). This is the DOM, the Document Object Model. Standard JavaScript without jQuery only has a couple of official methods at its disposal to work with the DOM. jQuery hides that layer of DOM access through its own clever wrapper, resulting in much more concise and powerful code.

Calling a function when the DOM has loaded can also be done with via standard DOM API:

    document.addEventListener( "DOMContentLoaded", function() {
        ...
    }, false );

The problem is, with so many old browser still out there and Microsoft's past refusal to follow such standards, that this won't even work in IE7 for example. The jQuery approach is much more concise, quite dramatically in this example, and will utilize other browser specific implementations if necessary.

So inside the function passed to $() jQuery can get started with its work. Usually it does quite a bit of its magic at the time the initial DOM has become available. Other functions, particularly event handlers, can be declared nested inside this function. This nesting of functions is a very important concept in JavaScript. A function, particularly the abundant anonymous functions in jQuery development, and the scope of variables it has been defined inside of make up a closure.

While it is not good style to declare global variables, which acutally are added as members to the window object by JavaScript, it is quite helpful and common practice to access variables from the closure's scope. Those scopes can be nested and any declaration in a more outerly scope is also accessible.

To structure the code and to keep the scopes smaller, two separate anonymous functions are passed to $() calls. jQuery puts them in a queue and executes them in the given order when the DOM has loaded. The code is kept nicely separated from the page definition in HTML. jQuery calls this unobtrusive JavaScript.

Manipulating the DOM

The second use of $() is the creation of detached bits of DOM structure from HTML code. This happens in the first function:

    var td = $("<td></td>");

Now td contains an empty table cell. We'll need lots of those with the state the tables are in intially. The initial DOM doesn't contain a single one of them. The first table should show the letters A through Z. That is done in a loop with a single line of jQuery magic inside:

    for (var i = 65; i < 91; i++) {
        td.clone().appendTo("tr.letters").text(String.fromCharCode(i));
    }

This line shows another popular jQuery code pattern: Method chaining. jQuery makes sure that method calls usually return a value that can be acted upon with the next method in the chain. We need more than one cell. The single template cell we've created gets cloned. The clone is then appended to the inner HTML of the table row located by the CSS selector 'tr.letters', which is empty intially. Another chained method sets its text content. The order of the .text() and .appendTo() methods can be reversed without any difference. Both just pass through the object for with they've been called, the clone of td. The same pattern is then applied of for the color row. It's just the color generation that is more complex here, with two .css() calls for setting font and background color.

The next usage of $() is via a CSS selector. This also happens to be a string parameter, so jQuery even makes a distinction by value, with stuff starting with angular brackets indicating HTML.

    var tr = $("table.write tr");

Given the initial HTML the selector just corresponds to a single row. But more than one row element could have been found in more general circumstances. A lot of the elegance of jQuery results from manipulation of a whole set of elements with a single method call. The typical jQuery object represents zero or more DOM elements. Most methods apply to all elements in the internal list, some only to the first.

To get the bigger table created the tr is filled with td clones again. Then tr is cloned to create multiple rows in the table with class='write'.

    for (var i = 0; i < 13; i++) {
        tr.append(td.clone());
    }
    for (var i = 0; i < 5; i++) {
        tr.clone().appendTo("table.write");
    }

The difference between using .append() versus .appendTo() is that the latter will allow a continuation of the method chain on the appended child, while the other provides the parent for further manipulation.

Reacting to events

The second function declares three variables to be used in the event handling closures that follow.

    var lett = "X";
    var lcol = "black";
    var bcol = "white";

    $("tr.letters").on("click", "td", function() {
        lett = $(this).text();
        $("tr.colors td")
            .text(lett);
    });

The part that you will need to sit back and reflect upon a bit here, before the whole power of jQuery may flow through you, is the .on() method called with three parameters. The first one is the DOM event for which a handler gets registered. It is the most common "click" event imaginable. The third parameter is the function that gets called when the event is triggered by the user.

The cool part comes in with the middle parameter. This specifies a CSS selector for elements inside of the container that the event is defined upon. The event is listened for across the entire row, but we are curious which particular cell was clicked. The 'td' selector makes the event handler determine which matching element the event was originally raised in and sets that element as the context (this) for the handler function.

Another use of $() is taking DOM elements and converting them into wrapped sets that jQuery methods can be applied to. Most frequently this is done on this, which holds the event's context element itself, not its jQuery equivalent.

Finally with $("tr.colors td") we have an example of multiple elements, represented by a slightly more advanced CSS selector, all getting the same treatment.

The second event handler - not listed here - does the equivalent thing for the row of colors and applies the choice to all letters. The third handler then applies the choices to whatever cell in the bigger table is clicked.

So there you are. The jQuery documentation is really exhaustive and provides lots of examples. The Manning book jQuery in Action is also warmly recommended, particularly for its ongoing usefulness as a reference, while still introducing each section to the newbies.