jQuery is a library written in Javascript that is specialized for changing web documents on the fly. It is one of the most used libraries on the Web.

Interactive Example

Once you have completed reading these notes and perhaps the book chapter as well, you might want to test your learning by trying to add jQuery code to this HTML page, so that you gradually build a page that displays the behavior shown in this screencast. You can do so without adding a single line to the HTML or CSS portions, but only with jQuery code.

Don't worry if you cannot figure out everything. On Lab this week, you will work on a variation of this example.

jQuery Basics

1. Include jQuery in a webpage

In order to use jQuery in a webpage, we need to include it with the <script> tag. The library itself is a big Javascript file with hundreds of lines of code. We can either download this file from the jQuery website, or we can use an absolute URL to some web server that keeps a copy of the library online. For simplicity, we will do the latter. Here is how we will include jQuery in our programs:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

As of this lecture, the most current version of jQuery is 1.11.0. In your reading or examples from the Web, you will notice other version numbers. The .min part of the filename means mininfied. This refers to the practice of deleting all newlines and other space to reduce file size. If you open this file, you'll notice that it doesn't show the structure of a normal Javascript program with indentation and nesting. Thus, it is not for human consumption. However, it does load faster, because the file is smaller.

2. jQuery wrapper

Once we have the jQuery library linked to our page, we can start using its main method, the jQuery Wrapper. This is a function that has two forms, one is more used than the other:

// Short form used more often
$()

// Long form  used rarely
jQuery()

There are three things we can do with this function, they are listed below in order of most common to less common:

// Usage 1: Select elements from the DOM, using CSS selector phrases

$("h1");
$("nav ul li");
$("li:nth-of-type(2)");

// Usage 2: Create new HTML elements on the fly
$("<p>It's a rainy day</p>").appendTo("body")

// or
$("<p>").text("It's a sunny day")
              .appendTo("body");

// Usage 3: Access elements through their variable names
$(document);
$(this);

var header = $("header");
$(header).append("<h1>Welcome guest!</p>")

Being able to distinguish between these three usages is helpful to understand code written by others.

3. Method Chaining

The jQuery wrapper function always returns a value, which is an array. Sometimes this array might be empty, sometimes it has one element, and sometimes it has multiple elements.

Knowing that the jQuery wrapper always returns something is very useful for chaining jQuery methods. This is done to avoid storing results in temporary variables. Here is how an example of chaining looks like:

// create a new element and add it to the body tag
$("<p>")
      .text("Just added a new paragraph")     // put some text to this element. No semi-colon
      .css("font-size", "30pt")               // add some style. No semi-colon
      .appendTo("body")                       // append it to the body. Semi-colon here because we are done

The first call to $("p") created a new element and returned it. To the returned result, we applied the method text, which set the contents of the paragraph and then returned it, so we then applied the css method, which changes the css and also returned the paragraph, so we applied the .appendTo() method to append the paragraph to the body of the document. Note that there are no semi-colons until we are all done.

You don't have to use this technique if you don't want to, but it can be very clear to read (once you are used to it) and it is commonly used in online tutorials and examples.

4. Is the DOM ready?

An important question is when should our jQuery code be executed. Putting the code in different parts of the HTML file might have different effects on the page, based on when the browser reads and interprets the code. This is why, normally, the jQuery code should be executed only after the DOM has been created and is ready for dynamic manipulation.

Most examples you'll see in the provided reading, will show code usually wrapped in a big event handler for the document object, as shown below:

$(document).ready(function(){

  // all other jQuery code goes here

});

This code is complex to understand. It uses the jQuery wrapper function with an object, to the result it applies the method ready() (which is triggered when the DOM is ready), and to this method it passes as an argument an anonymous function. Notice that the final line is });.

Avoiding $(document).ready(function(){..});

Since the syntax for this event handler is complex and difficult to remember, we'll use a trick. We will always put our jQuery code at the very end of the HTML file, just before the end tag for body. This way, we know that the previous HTML lines have been already processed by the browser and the DOM is ready.

If you put the jQuery code (or the script tag referring to the jQuery code) anywhere else in the HTML file, you'll run into the problem of the DOM not being ready and your code will not work.

Javascript versus jQuery

After having spent weeks learning Javascript you might ask why use jQuery. The reason is simple, it allows you to write less code to achieve the same things. jQuery itself is completely written in Javascript, however, it encapsulates in methods some of the most common activities that one would have to code and code over again for every program. jQuery is a perfect example of the big ideas of abstraction and modularity which are at the heart of computation.

Below is a table of some one-to-one mapping between Javascript code we have seen and jQuery method calls.

Javascript Code jQuery Code
document.querySelector("nav ul")        
$("nav ul");
document.querySelector("h1").innerHTML = "Welcome";     
$("h1").html("Welcome");
function doWhenClicked() {
  // body of function
}
document.querySelector("button").onclick = doWhenClicked;
function doWhenClicked() {
  // body of function
}
$("button").click(doWhenClicked)
document.querySelector("h1").style.color = "red";       
$("h1").css("color", "red")
 window.onload = onDocumentReady;
 function onDocumentReady() {
     // body of function 
 }
$(document).ready(function(){
  // body of function
});


As you can notice, all the Javascript examples can be written in less code with jQuery.

Some jQuery Methods

Here is a list of jQuery methods used in our interactive example or in the assignment for this week.

  • .ready()
  • .append()
  • .appendTo()
  • .click()
  • .show()
  • .hide()
  • .text()
  • .attr()
  • .val() // for input fields
  • .parent()
  • .clone()
  • .addClass()
  • .removeClass()
  • .find()

To see more examples and explanations for these methods, you should consult the jQuery API documentation.

Generating Content

One of the things we have used JavaScript for is to dynamically add things to the document. For example, in the lecture on Arrays and Loops, we built a bunch of paragraphs for some books from an array of objects describing each book. (We can imagine that this array of objects is dynamically loaded from some server, maybe from a search request we made.) Similarly, in the associated class activities on arrays and loops, we built a list of thumbnail pictures from an array of objects.

We used two different techniques in these loops. The first was to build up a long string of HTML code:


Try it!

This technique works fine, but the coding is made harder with nested quotation marks, difficulty balancing angle brackets and tags, and so forth. It becomes increasingly difficult as the HTML gets more complex.

Another technique is to build the HTML elements using the document.createElement methods and assemble them that way. We used that with the gallery of thumbnails:


Try it!

The disadvantages of this technique is that it's just tedious, requiring a new line of code for every attribute, for every element, for every attachment of one element to another.

Cloning

Today, we'll learn an alternative to both of these techniques for generating content, called cloning. The idea of cloning is pretty straightforward:

  • Write some HTML that you want to replicate many times. You can debug this in all the usual ways that you're used to from the first weeks of this class.
  • Put it inside a container DIV that you can give an ID and then hide.
  • In your loop, you can clone this template (making a copy of all the elements). This clone is a tree with all the parent/child relationships of the original
  • You can use the jQuery find method to find elements of the clone, and other jQuery methods to modify the elements, filling in their attributes.

Let's see it in action. Let's first write the template HTML. I'll use the clownfish in the template example:

<figure>
  <img src="animals/images/clownfish.jpg" alt="clownfish">
  <figcaption>Nemo's ancestor</figcaption>
</figure>

Next, I'll put it in a wrapper, so that the template is hidden. (In practice I would do the hiding in an external CSS file, but I wanted to show you the CSS here.)

<div id="template" style="display: none">
  <figure>
    <img src="animals/images/clownfish.jpg" alt="clownfish">
    <figcaption>Nemo's ancestor</figcaption>
  </figure>
</div>

Now, I'm ready to do my looping and cloning.


I think you'll agree that code is shorter, easier and more intuitive than either of the first two.

A few more details:

  • You'll note the use of a child selector (#template > figure) when we get the thing that we want to clone. We don't want to clone the wrapper (which is hidden and has an id).
  • Your template and your clones should not use ID, because a ID is supposed to be unique. Instead, use classes.
  • The argument to .find() is a CSS-style selector. Here, we used the names of the elements, like img and figcaption. If we were doing the books example, where there were several spans, we might have used .title and .price as the selectors, looking for things with a particular CSS class.
  • The .find() method can be used in other contexts, of course, but it is often used in cloning.

User-defined Attributes

When we create elements, we sometimes want to add some additional information that doesn't quite fit into the HTML code. For example, on a e-commerce site, we might want to put the SKU number or bar code on the element, so that we can have that info for ordering.

The new HTML5 standard explicitly addresses this by saying that any element can have custom attributes starting with data- and those attributes are reserved for users. Let's do that in our books example.

First, the template:

<div id="book_template" style="display: none">
  <li><span class="title"></span>, which costs <span class="price"></span>
</div>

Now, the code to generate the book list. Note that I added the ISBN-10 data to our objects. We'll add a click handler so that if you click on a book, the ISBN-10 is displayed.


Try it! Try clicking on one of them, too.

Hide, Show and Anonymous Functions as Handlers

A few more fun items to know.

First, we often want to hide something on the page and then reveal it later. Like this:

peeker says peek a boo!

This can be done by manipulating the CSS. If an element has a display: none property, it won't be displayed, so it's hidden. If you change the display property back to what it was originally (block for block elements and inline for inline elements), the element reappears.

jQuery has methods that do this for us: .hide() and .show().

We could define two functions and add them as event handlers to the two buttons. The code would look like this:

function hide_peeker () {
    $("#peeker").hide() {
}

function show_peeker () {
    $("#peeker").show();
}

$("#hide_it").click(hide_peeker);
$("#show_it").click(show_peeker);
$("#peeker").hide();  // hide it initially

The code is pretty clear, but it's verbose and requires us to make up two names for functions. Experienced jQuery programmers use anonymous functions like this:

$("#hide_it").click(function () { $("#peeker").hide(); });
$("#show_it").click(function () { $("#peeker").show(); });
$("#peeker").hide();  // hide it initially

Now, there's a punctuation nightmare at the end of the first two lines, but nevertheless, this is a nice trick worth knowing.

When you ask jQuery to modify a set of things, it will modify each one in the set. This makes it really easy to add the same function as an event handler to lots of different elements, just by using a CSS selector that matches more than one thing. In the following example, we have three boxes, all with the class alice, and we want them to grow by 25% each time you click on them. Try it! (I wanted to use AliceBlue as the background color, but it's too pale.)

I'm Alice 1
I'm Alice 2
I'm Alice 3

The jQuery code to do that is here:

  $(".alice").click(function () {
      var w = parseInt($(this).css('width'));
      $(this).animate({'width': w * 1.25});
  });

Of course, we could have done that with a named function as well, but this is almost as easy, and some would say it's easier. Using the anonymous function also makes it clear what this refers to, namely, the Alice that was clicked on.