MOBILE

jQuery 1.3 : Selectors - DOM traversal methods, Accessing DOM elements

8/27/2012 1:14:26 AM

DOM traversal methods

The jQuery selectors that we have explored so far allow us to select a set of elements as we navigate across and down the DOM tree and filter the results. If this were the only way to select elements, our options would be quite limited (although, frankly, the selector expressions are robust in their own right, especially when compared to the regular DOM scripting options). There are many occasions when selecting a parent or ancestor element is essential; that is where jQuery's DOM traversal methods come into play. With these methods at our disposal, we can go up, down, and all around the DOM tree with ease.&;&;

Some of the methods have a nearly identical counterpart among the selector expressions. For example, the line we first used to add the alt class, $('tr:odd').addClass('alt');, could be rewritten with the .filter() method as follows:

$('tr').filter(':odd').addClass('alt');

For the most part, however, the two ways of selecting elements complement each other. Also, the .filter() method in particular has enormous power because it can take a function as its argument. The function allows us to create complex tests for whether elements should be kept in the matched set. Let's suppose, for example, we want to add a class to all external links. jQuery has no selector for this sort of case. Without a filter function, we'd be forced to explicitly loop through each element, testing each one separately. With the following filter function, however, we can still rely on jQuery's implicit iteration and keep our code compact:

$('a').filter(function() {
return this.hostname && this.hostname != location.hostname;
}).addClass('external');

The second line filters the set of <a> elements by two criteria:&;

  1. They must have an href attribute with a domain name (this.hostname). We use this test to exclude mailto links and others of its ilk.

  2. The domain name that they link to (again, this.hostname) must not match (!=) the domain name of the current page (location.hostname).

More precisely, the .filter() method iterates through the matched set of elements, testing the return value of the function against each one. If the function returns false, the element is removed from the matched set. If it returns true, the element is kept.

Now let's take a look at our striped table again to see what else is possible with traversal methods.

Styling specific cells

Earlier we added a highlight class to all cells containing the text Henry. To instead style the cell next to each cell containing Henry, we can begin with the selector that we have already written, and simply chain the next() method to it:&;&;

$(document).ready(function() {
$('td:contains(Henry)').next().addClass('highlight');
});

The table should now look like this:

The .next() method selects only the very next sibling element. To highlight all of the cells following the one containing Henry, we could use the .nextAll() method instead.

$(document).ready(function() {
$('td:contains(Henry)').nextAll().addClass('highlight');
});

As we might expect, the .next() and .nextAll() methods have counterparts: .prev() and .prevAll(). Additionally, .siblings() selects all other elements at the same DOM level, regardless of whether they come before or after the previously selected element.


To include the original cell (the one that contains Henry) along with the cells that follow, we can add the .andSelf() method:

$(document).ready(function() {
$('td:contains(Henry)').nextAll().andSelf().addClass('highlight');
});

T&;&;o be sure, there are a multitude of selector and traversal-method combinations by which we can select the same set of elements. Here, for example, is another way to select every cell in each row where at least one of the cells contains Henry:

$(document).ready(function() {
$('td:contains(Henry)').parent().children().addClass('highlight');
});

Here, rather than traversing across to sibling elements, we travel up one level in the DOM to the <tr> with .parent() and then select all of the row's cells with .children().

Chaining

T&;&;he traversal-method combinations that we have just explored illustrate jQuery's chaining capability. It is possible with jQuery to select multiple sets of elements and do multiple things with them, all within a single line of code. This chaining not only helps keep jQuery code concise, but it also can improve a script's performance when the alternative is to re-specify a selector.

It is also possible to break a single line of code into multiple lines for greater readability. For example, a single chained sequence of methods could be written as one line …

$('td:contains(Henry)').parent().find('td:eq(1)')
.addClass('highlight').end().find('td:eq(2)')
.addClass('highlight');

… or as seven lines …

$('td:contains(Henry)') // Find every cell containing "Henry"
.parent() // Select its parent
.find('td:eq(1)') // Find the 2nd descendant cell
.addClass('highlight') // Add the "highlight" class
.end() // Return to the parent of the cell containing "Henry"
.find('td:eq(2)') // Find the 3rd descendant cell
.addClass('highlight'); // Add the "highlight" class

A&;dmittedly, the DOM traversal in this example is circuitous to the point of absurdity. We certainly wouldn't recommend using it, as there are clearly simpler, more direct methods at our disposal. The point of the example is simply to demonstrate the tremendous flexibility that chaining affords us.

Chaining can be like speaking a whole paragraph's worth of words in a single breath — it gets the job done quickly, but it can be hard for someone else to understand. Breaking it up into multiple lines and adding judicious comments can save more time in the long run.

Accessing DOM elements

E&;very selector expression and most jQuery methods return a jQuery object. This is almost always what we want, because of the implicit iteration and chaining capabilities that it affords.

Still, there may be points in our code when we need to access a DOM element directly. For example, we may need to make a resulting set of elements available to another JavaScript library. Or we might need to access an element's tag name, which is available as a property of the DOM element. For these admittedly rare situations, jQuery provides the .get() method. To access the first DOM element referred to by a jQuery object, we would use .get(0). If the DOM element is needed within a loop, we would use .get(index). So, if we want to know the tag name of an element with id="my-element", we would write:

var myTag = $('#my-element').get(0).tagName;

For even greater convenience, jQuery provides a shorthand for .get(). Instead of writing the above line, we can use square brackets immediately following the selector:

var myTag = $('#my-element')[0].tagName;

It's no accident that this syntax looks like an array of DOM elements; using the square brackets is like peeling away the jQuery wrapper to get at the node list, while including the index (in this case, 0) is like plucking out a DOM element itself.

Other  
 
Most View
Looking Good, Sounding Great (Part 1) : Q Acoustics Q7000i 5.1, Bowers & Wilkins MT-50, Canton Movie 1050
Booting on HP 9000 Servers (part 2) - The setboot Command, Boot Console Handler (BCH) and Processor Dependent Code (PDC)
Sony Xperia ZL Review - A Powerhouse Phone In An Amazingly Compact Chassis (Part 3)
Long Awaited Canon Super Telephoto Emerges From The Wild
Sling Media Slingbox Pro-HD
Ouya Gaming Machine Review - Founding Backer Version (Part 1)
Seasonic And Enhance Junior PSUs - Compact Power Supply (Part 5) : Enhance ENP-7025E
SQL Server 2008 : Common performance problems (part 1) - Procedure cache bloating
ECS Z77H2-A2X v1.0 - Golden LGA 1155 Mainboard From The Black Series (Part 6)
Booting on HP 9000 Servers (part 4) - HPUX Secondary System Loader (hpux)
Top 10
SQL Server 2012 : Consolidating Data Capture with SQLdiag - Getting Friendly with SQLdiag (part 2) - Using SQLdiag as a Service
SQL Server 2012 : Consolidating Data Capture with SQLdiag - Getting Friendly with SQLdiag (part 1) - Using SQLdiag as a Command-line Application
SQL Server 2012 : Consolidating Data Capture with SQLdiag - The Data Collection Dilemma, An Approach to Data Collection
SQL Server 2012 : Troubleshooting Methodology and Practices - Data Analysis, Validating and Implementing Resolution
SQL Server 2012 : Troubleshooting Methodology and Practices - Data Collection
SQL Server 2012 : Troubleshooting Methodology and Practices - Defining the Problem
SQL Server 2012 : Troubleshooting Methodology and Practices - Approaching Problems
Windows 8 : Accessing System Image Backup and Recovery Functionality with Windows Backup, Cloud Backup
Windows 8 : Using the Windows 8 Recovery Tools (part 2) - Push Button Reset
Windows 8 : Using the Windows 8 Recovery Tools (part 1) - Creating a System Recovery Disc, Booting to the Windows Recovery Environment