DOM traversal
Finding elements based on ID, element type, and class name is very useful, but what if you want to find an element based on its position in the DOM tree? In other words, you have a given element and you want to find its parent, one of its children, and its previous or next node sibling. For example, take the following fragmentary HTML code:
Listing 1: HTML fragment (a table)
<table>
<thead>
<tr>
<th>Name</th>
<th>Email Address</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr id="row-001">
<td>Joe Lennon</td>
<td>[email protected]</td>
<td><a href="#">Edit</a>
<a href="#">Delete</a></td>
</tr>
<tr id="row-002">
<td>Jill Mac Sweeney</td>
<td>[email protected]</td>
<td><a href="#">Edit</a>
<a href="#">Delete</a></td>
</tr>
</tbody>
</table>
Listing 1 uses indentation to indicate the location of each element node in the DOM tree. In this example, the table element is the root element and has two child nodes, thead and tbody. The thead element has a tr child node, and tr has three children - all th elements. The tbody element has two tr child nodes, and each tr node has three children. The third node in each line above further contains child nodes, both of which are two link tags.
As you know, you can easily select an element by ID using a JavaScript framework 's select function. In this example, there are two elements with IDs, which are tr elements with IDs row-001 and row-002. To select the first tr using the Prototype library, you can use the following code:
var theRow = $('row-001');
In the previous chapter, you also learned about using selectors to retrieve elements based on their type or class. In this example, you can use the following syntax to get all td elements.
var allCells = $$('td');
The main problem with changing the code is that it returns every td element. But what if you just want to get all td elements of tr with ID row-001? This is where DOM traversal functions come into play. First, let's use the prototype to select all children of tr with ID row-001.
var firstRowCells = theRow.childElements();
This will return an array of all child elements of theRow variable (the tr you initially set with ID row-001).
Next, let's assume that you only want to get the first child element of the row. In this case, that is the td element containing the text "Joe Lennon". To do this, use the following statement:
var firstRowFirstCell = theRow.down();
So simple! This specific usage is equivalent to:
var firstRowFirstCell = theRow.childElements()[0];
It can also be expressed like this:
var firstRowFirstCell = theRow.down(0);
JavaScript indexes start at zero, so the above statement basically tells JavaScript to select the first child element. To select the second child element (the cell containing the email address [email protected] ), you would use:
var firstRowSecondCell = theRow.down(1);
Alternatively, you can browse the DOM between sibling nodes. In this example, the second cell is the next sibling of the first cell. Therefore, you can use the following statement:
var firstRowSecondCell = firstRowFirstCell.next();
Just like the down() function works, selecting the third cell can be used like this.
var firstRowThirdCell = firstRowFirstCell.next(1);
In addition to using indexes to find specific nodes, the Prototype library can also use CSS selector syntax. In Listing 1, we're looking for the second link (the "remove" link) that contains Jill Mac Sweeney's details.
var secondRowSecondLink = $('row-002').down('a', 1);
In this example, use the $ function to find the row with ID row-002, traversing down to the second descendant a element (the anchor).
Some frameworks also allow "daisy-chaining" traversal functionality, which means you can connect traversal commands to each other. In the above example, another expression of the Prototype library is as follows:
var secondRowSecondLink = $('row-002').down('a').next();
Take a look at the following example:
var domTraversal = $('row-001').down().up().next().previous();
As you can see, daisy chaining allows you to connect multiple DOM traversal statements. In fact, the above example actually ends up selecting the tr element with ID row-001, so the daisy chain is back to where it started.
Reprint address: http://www.denisdeng.com/?p=708
Original address: http://www.ibm.com/developerworks/web/library/wa-jsframeworks/index.html