Getting Good with JavaScript - Andrew Burgess [32]
Thankfully, each of these different types of nodes has a property called nodeType; they are as follows:
HTML elements = 1
HTML element attributes = 2
Text nodes = 3
Comment nodes = 8
The document = 9
So, to find that h2, we just have to get the first child of the div node; then, we check the nodeType property of that node. If it's not 1, we get the next sibling node and check that. Here's the code for that:
Example 5.4
var products = document.getElementsByClassName("product"),
i = 0,
child;
for ( ; i< products.length; i++) {
child = products[i].firstChild;
while (child.nodeType !== 1) {
child = child.nextSibling;
}
console.log(child);
}
We start by getting all the elements with that class "product"; remember, since we've getting more than one element, this returns an array (Well, it's not really an array; it's a NodeList, which can be iterated over like an array, as we see here). For each node in our list, we get the first child via the firstChild property and assign it to the variable child. Then, we're using a while loop to find the first node with a nodeType of 1 (meaning an HTML element). Our condition says "while the node type of child node is not 1"; this means that if the firstChild is an element, the loop won't run. If it's not, we'll run the loop, which simply reassigns the child variable to child.nextSibling (the next sibling of child). When we find the first element in the list of children, we can do what we want to do. We're not going to do any more than print it out to the console right now, so you can see that is, in fact, the h2.
Those are the basics of traversing the DOM. There are a few more links between nodes that we'll wrap up this discussion with.
childNodes
Every node has a property called childNodes; it's a NodeList (remember, an array-like object) containing all the child nodes of the node. Don't forget, it's zero-based.
Example 5.5
//
- one
- two
//
//
//
var my_node = document.getElementById("container");
my_node.childNodes[1]; // gets the first list item (the second child node)
children
While childNodes holds all node types, children just includes the element nodes. These are usually what you want, so this is probably more useful that childNodes. However, IE 6 - 8 includes comment nodes for some reason, so beware of that.
lastChild
Works just like firstChild, except it gets—wait for it—the last child node.
previousSibling
Just as you'd (hopefully) expect, the previousSibling property returns the previous sibling of the node.
parentNode
This is the one-way link every node has to its parent. Think back to our bunch of product divs. We wanted to sort them by product name. This meant we needed to find the h2 element, to sort by. But if we actually got to the sorting step, we would have used parentNode to get the div parent for each h2.
Example 5.6
//
- one
- two
//
//
//
var my_node = document.getElementById("first");
console.log( my_node.parentNode); // ul element
Others
There are a bunch of properties for traversing the DOM that are incredibly useful, but not incredibly well-supported. They are as follows:
firstElementChild
lastElementChild
nextElementSibling
previousElementSibling
You can probably guess what they do; because most of the time you just want to work with element nodes, these properties do exactly as their already-seen counterparts do, except they ignore all those other types of nodes that just get in the way.
That's the