jQuery and JavaScript Phrasebook (2014)

5. Manipulating the jQuery Object Set

An important aspect of jQuery objects is the ability to access and manipulate the set of DOM elements that are represented by the object. This is different than manipulating the DOM elements themselves.

jQuery provides several methods that allow you to modify which DOM elements are represented by the jQuery object. There are also methods to iterate through each element to build different elements or apply other operations.

The following phrases are designed to show you how to work with the jQuery object set in various ways.

Getting DOM Objects from a jQuery Object Set


$("div").get();
  //returns an array of DOM object for all <div> elements
$("div").get(0);
  //returns a DOM object for the first <div>
$("div").get(-1);
  //returns a DOM object for the last <div>


The .get([index]) method returns the DOM elements represented in the jQuery object set. If no index is specified, an array of the DOM objects is returned. If an index is specified, the DOM element at that zero-based offset in the array is returned.

If the index is a negative number, the item at the reverse offset from the end of the array is returned. For example, –1 is the last item and –2 is the second to the last item.

Converting DOM Objects into jQuery Objects


var containerObj = document.getElementById("myDiv");
$(containerObj); //Equivalent to $("#myDiv");
var objs = document.getElementsByClassName("myClass");
$(objs); //Equivalent to $(".myClass ");
var objs = document.getElementsByTagName("div");
$(objs); //Equivalent to $("div");


The jQuery constructor $() accepts DOM objects and arrays as an argument. If you pass in a DOM object, $() converts the DOM object or array into a jQuery object that you can then manipulate in the normal jQuery way.

Iterating Through the jQuery Object Set Using .each()


$("p").each(function (idx){
    $(this).html("This is paragraph " + idx);
  });


The .each(function) method is one of the most important jQuery object methods because it allows you to traverse all elements in the jQuery set and perform actions on each of them individually. This is different from just applying the same action to all items in the query.

The .each() method allows you to specify a function to run for each element in the jQuery object set. The function is passed an index number as the first argument. Inside the function, the this variable points to the current DOM element.

To illustrate using .each(), check out the following snippet of code. It iterates through all paragraph elements and sets the content of the empty <p> elements to a string that includes the index number of the element, as shown in Figure 5.1:


01 <html>
02 <head>
03 <title>Python Phrasebook</title><meta charset="utf-8" />
04 <script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
05 <script>
06   $(document).ready(function (){
07     $("p").each(function (idx){
08         $(this).html("This is paragraph " + idx);
09       });
10   });
11 </script>
12 </head>
13   <body>
14     <p></p>
15     <p></p>
16     <p></p>
17     <p></p>
18   </body>
19 </html>


ch0501.html

Image

Figure 5.1 Results of running the ch0501.html code.

Notice that idx is passed in as an index number, 0 for the first <p> element, 1 for the second, and so on. Also note that I converted this to a jQuery object using $(this) so that I could call the .html() method.


By the way

When using functions with jQuery methods that iterate through the DOM elements, you can use the this keyword to access the current DOM object that is being iterated on. this is a DOM object and not a jQuery object, so if you need to use the jQuery form of the DOM object, use $(this). Keep in mind, though, that it takes work to build the jQuery form of the DOM object, so only create the jQuery form if you want the functionality that is provided.


Using .map()


var liValues = $("li").map(function (idx){
  return $(this).html();
}).get();


The .map(function) method also iterates through each element in the jQuery object set. Although similar to .each(), there is one big difference: .each() returns the same jQuery object, but .map() returns a new jQuery object with the values returned by each iteration.

To illustrate using .map(), check out the following snippet of code. This code iterates through all <li> elements and returns an array containing the HTML content values inside the <li></li> elements shown in Figure 5.2:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-2.0.3.min.js"></script>
07   <script>
08     $(document).ready(function (){
09       var liValues = $("li").map(function (idx){
10         return $(this).html();
11       }).get();
12     });
13   </script>
14 </head>
15   <body>
16     <ul>
17       <li>Aragorn</li>
18       <li>Legolas</li>
19       <li>Gimli</li>
20     </ul>
21   </body>
22 </html>


ch0502.html

Image

Figure 5.2 Results of running the ch0502.html code.


[
 "Aragorn",
  "Legolas",
  "Gimli"
]


Ending value of liValues

Notice that during each iteration, the function returns the HTML content in the <li> element. This value is added to the mapped object set that the .map() method returns. The .get() call at the end gets the JavaScript array object represented in the mapped set.

Assigning Data Values to Objects


$("li:eq(0)").data("race","Men");
$("li:eq(1)").data("race","Elves");
$("li:eq(2)").data({race:"Dwarves"});
$("li").each(function(){
  $(this).append(" of the race of ");
  $(this).append($(this).data("race"));
});


jQuery provides the .data(key [,value]) method to store pieces of data as key=value pairs inside the DOM object. This allows you to attach additional pieces of data to the object that you can access later.

There is an alternate form of .data(object) that accepts JavaScript objects containing the key value pairs. This becomes useful when you are already working with objects.

To access a data item once it has been stored, simply call .data(key), which returns the object value. You can attach data to any kind of HTML object. For instance, you can attach additional data to select <option> elements that provide more information than the traditional values support.

The following code shows an example of storing data in objects. Line numbers 9–11 store data in <li> elements. Then each function in lines 12–15 iterates through the <li> elements and appends a string with the stored value onto the content. Figure 5.3 shows the resulting HTML page:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-2.0.3.min.js"></script>
07   <script>
08     $(document).ready(function (){
09       $("li:eq(0)").data("race","Men");
10       $("li:eq(1)").data("race","Elves");
11       $("li:eq(2)").data("race","Dwarves");
12       $("li").each(function(){
13         $(this).append(" of the race of ");
14         $(this).append($(this).data("race"));
15       });
16     });
17   </script>
18 </head>
19   <body>
20     <ul>
21       <li>Aragorn</li>
22       <li>Legolas</li>
23       <li>Gimli</li>
24     </ul>
25   </body>
26 </html>


ch0503.html

Image

Figure 5.3 Results of running the ch0503.html code.

Adding DOM Elements to the jQuery Object Set


var pars = $("p");
  //contains all <p> elements
var pAndDiv = $("div").add(pars);
  //contains all <div> and <p> elements
var pAndDivAndSpan = $("span").add("p").add("div");
  //contains all <span> and <div> and <p> elements


A great feature of jQuery is how easy it is to add additional elements to the jQuery object set. The .add(selector) method adds elements that match the selector to the set represented by the jQuery object.

The .add(object) method accepts another jQuery object and adds the elements in that object to the current object’s set.

Removing Objects from the jQuery Object Set


var items = $("span");
items.css({color:"red"});
  //colors text in all <span> elements red
items.remove(".menu"):
items.css({"font_weight":"bold"});
  //set all <span> elements except .menu to bold


Another great feature of jQuery is how easy it is to remove items from and add additional elements to the jQuery object set. The .remove([selector]) method will remove elements  that match the selector from the set represented by the jQuery object. Calling .remove() with no selector will remove all elements from the set.

Filtering the jQuery Object Results

jQuery objects provide a good set of methods that allow you to alter the DOM objects represented in the query. Reducing the results is helpful when you are trying to pinpoint a specific set of elements within a jQuery selector result. The following phrases provide examples of filtering the results of a jQuery selector to find the set of objects.

Filtering Items Based on Index


$("div#content").eq(1);
  //selects the second element found by the selector


The .eq(index) filter will return the element at a specific index in the jQuery object’s set. The index is zero based, so .eq(1) actually retrieves the second element found by the selector.

Filtering Selector Results Using a Filter Function


$("option").filter(
 function (index) {
  return (this.value>5); });
  //selects only the <option> elements with value=5
$("div").filter(".myClass");
  //selects only the <div> elements with class="myClass"


The .filter(filter) method reduces the set to only those items matching the specified filter. The filter can be a selector, a specific DOM element, a jQuery object, or a function that tests each element and returns true if it should be included.


Did you know?

The jQuery selectors that are the same as the CSS selectors are able to use the native DOM method querySelectorAll(), which has some advanced optimizations on DOM objects. Other jQuery selectors cannot take advantage of that optimization, so it is better to use a CSS-based selector first and then add the filter as a chained selector. For example, rather than using $("div:animated"), you should use $("div").filter(":animated").


Getting the First or Last Item


$("p").first(); //selects the first <p> elmemnt in the set
$("p").last(); //selects the last <p> elmemnt in the set


The .first() method selects the first element in the jQuery object’s set. Many of the jQuery methods that return values end up using the first element in the set. The .last() method selects the last element in the jQuery object’s set.

Getting Items That Contain Other Items


$("div").has("p");
  //selects <div> element that has <p> descendents
$("div").has("#menu");
  //selects <div> element that contains
  //the element that has id="menu"


The .has(selector or element) method reduces the set to those elements that have descendent elements that match the selector or contain the specified DOM element.

Filter Items Out Using Not Logic


$("div").not(".menu");
  //selects <div> element; do not have class .menu
$("option").not(function(){
  return (this.value==0); });
});
  //selects <option> elements that do not have value=0


The .not(filter) method reduces the set to match the filter. The filter can be a selector, one or more specific DOM elements, a jQuery object, or a function that tests each element and returns true if it should be included.

Slicing Up Selector Results


$("tr").slice(2,5);
  //selects the <tr> elements between 2 and 4 inclusive
$("p").slice(1,-1);
  //selects all <p> elments except the first and last


The .slice(start, [end]) method removes elements before index start and after index end and returns only the items in between. This allows you to break large selections into smaller chunks. The indexes are zero based. A negative end indicates the offset from the end of the list, where –1 is the last element and –2 is the second to the last element.