4 AJAX with jQuery
3 sections, 2 - 3 hours

{ jQuery Best Practices. }

Objectives:

By the end of this chapter, you should be able to:

Explain what selector caching is

Use chaining to clean up jQuery code

Make use of jQuery iterators instead of writing for loops

Selector Caching

As we start building larger applications with jQuery, we can make those applications more efficient by caching our selectors. What this means is that when we find elements in the DOM that we will be using repeatedly, we should find them once and save them to variables. Here's an example:

In this case, jQuery only needs to go into the DOM and search for the div with an id of container one time. Since we store that jQuery object in a variable, we don't need to go back into the DOM and search for the element again on subsequent lines. We've also started our variable name with a dollar sign: this isn't required, but it's a nice convention. It indicates to the reader that the value inside of the variable is a jQuery object.

Chaining

One of the nicest things about jQuery is the ability to chain functions together. What this allows us to do is something like this:

$("div").first().parent().find(".projects").css("color","red").fadeOut(200);
// this can also be written as:$("div")
.first()
.parent()
.find(".projects")
.css("color","red")
.fadeOut(200);

This sort of method chaining is a fairly common pattern, so it's good to see an example of it.

We can also refactor our example from the previous section to use chaining. Not only is the code a little cleaner, but we can also remove many references to the $container selection:

However, jQuery also comes with several built-in iterator functions. In this section, we'll talk about each, map, and filter. These are analagous to the built-in forEach, map, and filter methods on JavaScript arrays.

END FROM OTHER SECTIONS

each

One way to refactor the code above is to use jQuery's built-in each function. each accepts a callback, and that callback can take two arguments: the first refers to the current index (analogous to i in the above example), and the second refers to the current element corresponding to that index.

Note that the second parameter in the callback doesn't refer to a jQuery object. If you want to use jQuery methods on it, you'll need to wrap it in $(...), as we did in the example above.

Also, it's important to note that the order of arguments in the callback is slightly different than what we saw with the built-in array methods that JavaScript provides. With jQuery's each method, for example, the callback took the index as the first argument and the element as the second. With the built-in forEach method, this order is reversed: the array element is the first argument, followed by the index. (This reversal of arguments holds for jQuery's map and filter functions as well.)

map

jQuery has another iterator called map. The structure of this iterator is similar, but it does different things. map creates a new jQuery object that contains the return values from the callback inside of map. This is why, when using map, you need to be sure to always return something inside of the callback.

Here's an example. Suppose you want to add some p tags to the page explaining what happened each day. Here's how you could do this with map:

var summary = $("li").map(function(i,el) {
return$("<p>", {
text: "On day " + i + ", I earned " + $(el).text()
});
});
// summary is now a jQuery object which contains one p tag for each li$("body").append(summary.get());
// this appends the summary to the page.// The .get method turns summary, a jQuery object, into an array.// Without invoking get, you'll receive a TypeError.

filter

There's a third iterator available to you in jQuery, called filter. Filter takes elements out of a jQuery object if they fail some test provided by the callback (very similar to the native filter array method). For example, suppose we wanted red text highlighting the days we lost money. Here's how we could achieve that effect using filter:

$("li").filter(function(i,el) {
return$(el).text()[0] === "-"// returns true if the first character in the text is a minus sign,// i.e. this checks whether or not the number is negative
}).css('color','red');
// We've chained filter and css together; filter returns to us the // li's with negative numbers in them, and we then style those li's// to have red text.

Click on the links to learn more about jQuery's each, map, and filter.