×
By the end of this chapter, you should be able to:
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:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="container"></div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.js"></script> <script> $(function(){ var $container = $("#container"); $container.text("Hello World!"); $container.css('color','red'); $container.on("mouseenter", function(e){ console.log("moused over!"); }); var $newDiv = $("<div>", { text: "I am a div!", css: { color: "green" } }); $container.append($newDiv); }); </script> </body> </html>
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.
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:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="container"></div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.js"></script> <script> $(function(){ var $container = $("#container"); var $newDiv = $("<div>", { text: "I am a div!", css: { color: "green" } }); $container .text("Hello World!") .css('color','red') .on("mouseenter", function(e){ console.log("moused over!"); }) .append($newDiv); }); </script> </body> </html>
Consider the following HTML page:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Long list</title> </head> <body> <ul> Profit/Loss by Day <li>-$10</li> <li>$9</li> <li>$1</li> <li>$1</li> <li>$0</li> <li>$0</li> <li>$10</li> <li>-$7</li> <li>-$6</li> <li>-$9</li> </ul> <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.js"></script> </body> </html>
Suppose you wanted to print each day's profit or loss to the console using jQuery. One way you could do this is by iterating through the jQuery object you get when you grab all of the li
s:
for (var i = 0; i < $("li").length; i++) { console.log("Day " + i + ": " + $("li").eq(i).text()); }
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.
Here's how we could achieve the same result using each
:
$("li").each(function(i,el) { console.log("Day " + i + ": " + $(el).text()); });
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.
When you're ready, move on to Intermediate jQuery Exercises