Traversing the DOM

by kirupa   |   15 June 2014

As you may have realized by now, your DOM looks like a giant tree - a giant tree with elements dangerously hanging on to branches and trying to avoid the pointy things that litter the place. To get a little more technical, elements in your DOM are arranged in a hierarchy that defines what you eventually see in the browser:

the mapping

This hierarchy is used to help organize your HTML elements. It is also used to help your CSS style rules make sense of what styles to apply on which things. From the JavaScript angle, this hierarchy does add a bit of complexity. You will spend a fair amount of time trying to figure out where in the DOM you are right now and where you need to be. This is something that will become more apparent when we look into creating new elements or moving elements around. This complexity is something that you need to be comfortable with.

 That's where this tutorial comes in. To help you understand how to easily navigate from branch to branch (basically, like a monkey), the DOM provides you with a handful of properties that you can combine with techniques you already know. This tutorial will give you an overview of all that and more.

Onwards!

Finding Your Way Around

Before you can find elements and do awesome things with them, you need to first get to where the elements are. The easiest way to tackle this topic is to just start form the top and slide all the way down. That's exactly what we are going to do.

The view from the top of your DOM is made up of your window, document, and html elements:

the view from the top

Because of how important these three things are, the DOM provides you with easy access to them via window, document, and document.documentElement:

var windowObject = window; // um....
var documentObject = document;  // this is probably unnecessary
var htmlElement = document.documentElement;

One thing to note is that both window and document are global properties. You don't have to explicitly declare them like I did. Just shake and use them straight out of the container.

Once you go below the HTML element level, your DOM will start to branch out and get more interesting. At this point, you have several ways of navigating around. One way that you've seen plenty of is by using querySelector and querySelectorAll to precisely get at the elements you are interested in. For many practical cases, these two methods are too limiting.

Sometimes, you don't know where you want to go. The querySelector and querySelectorAll methods won't help you here. You just want to get in the car and drive...and hope you find what you are looking for. When it comes to navigating the DOM, you'll find yourself in this position all the time. That's where the various built-in properties the DOM provides for going all The Motorcycle Diaries will help you out, and we are going to look at those properties next.

The thing that will help you out is knowing that all of our elements in the DOM have at least one combination of parents, siblings, and children to rely on. To visualize this, take a look at the row containing the div and script elements in the following diagram:

parents, siblings, and children

Both the div and script elements are siblings. The reason they are siblings is because they share the body element as their parent. The script element has no children, but the div element does. The img, h1, p, and div are children of the div element, and all children of the same parent are siblings as well. Just like in real life, the parent, child, and sibling relationship is based on where in the tree you are focusing on. Almost every element, depending on the angle with which you look at them under, can play multiple familial roles.

 To help you through all of this, you have a handful of properties that you will rely on. These properties are firstChild, lastChild, parentNode, children, previousSibling, and nextSibling. From just looking at their names, you should be able to infer what role these properties play. The guy in red with the pointed pitchfork is in the details, so we'll look at this in greater detail next.

Dealing with Siblings and Parents

Of these properties, the easiest ones to deal with are the parents and siblings. The relevant properties for this are parentNode, previousSibling, and nextSibling. The following diagram gives you an idea of how these three properties work:

stuff

This diagram is a little busy, but you can sort of make out what is going on here. The parentNode property points you to the element's parent. The previousSibling and nextSibling properties allow an element to find its previous or next sibling. You can see this visualized in the diagram by just moving in the direction of the arrow. In the last line, our img's nextSibling is the div. Our div's previousSibling is the img. Accessing parentNode on either of these elements will take you to the parent div in the second row. It's all pretty straightforward.

Let's Have Some Kids!

What is a little less straightforward is how the children fit into all of this, so let's take a look at the firstChild, lastChild, and children properties in this next diagram:

the children

The firstChild and lastChild properties refer to a parent's first and last child elements. If the parent only has one child, as is the case with the body element in our example, then both firstChild and lastChild point to the same thing. If an element has no children, then these properties return a null.

The tricky one compared to the other properties we've looked at is the children property. When you access the children property on a parent, you basically get a collection of the child elements the parent has. This collection is not an Array, but it does have some Array-like powers. Just like with an Array, you can iterate through this collection or access the children individually kind of like what you see in the diagram. This collection also has a length property that tells you the count of how many children the parent is dealing with. If your head is spinning from this, don't worry. The snippets in the next section will help clarify the vagueness in my terrible explanation :P

Putting it All Together

Now that you have a good idea of all the important properties you have for traversing the DOM, let's look at some code snippets that tie in all the diagrams and words into some sweet lines of JavaScript.

Checking If A Child Exists

To check if an element has a child, you can do something like the following:

var bodyElement = document.body;
        
if (bodyElement.firstChild) {
    // do something interesting
}

This if statement will return null if there are no children. You could also have used bodyElement.lastChild or bodyElement.children.count if you enjoy typing, but I prefer to just keep things simple.

Accessing All the Child Elements

If you want to access all of a parent's children, you can always rely on good old uncle for loop:

var bodyElement = document.body;

for (var i = 0; i < bodyElement.children.length; i++) {
    var childElement = bodyElement.children[i];

    document.writeln(childElement.tagName);
}

Notice that I am using the children and length properties property just like I would an Array. The thing to remember is that this collection is actually not an Array. Almost all of the Array methods that you may want to use will not be available in this collection returned by the children property.

Walking the DOM

The last snippet touches upon a little bit of everything you've seen so far. This snippet recursively walks the DOM and touches every HTML element it can find:

function theDOMElementWalker(node) {
    if (node.nodeType == 1) {

        //console.log(node.tagName);

        node = node.firstChild;

        while (node) {
            theDOMElementWalker(node);
            node = node.nextSibling;
        }
    }
}

To see this function in action, simply call it by passing in a node that you want to start your walk from:

var texasRanger = document.querySelector("#texas");
theDOMElementWalker(texasRanger);

In this example, we are calling theDOMElementWalker function on an element referenced by the texasRanger variable. If you want to run some code on the element that this script found, replace my commented out line with whatever you want to do.

Conclusion

Finding your way around the DOM is one of those skills that every JavaScript developer should be familiar with. This tutorial provided you an overview of what is technically possible. Applying this into more practical ways falls entirely onto you....or a cool friend who helps you out with these things. With that said, in subsequent tutorials, we will expand upon what you've seen here as part of continuing our deep dive into everything you can do with the DOM. Yay!!!

Getting Help

If you have questions, need some assistance on this topic, or just want to chat - post in the comments below or drop by our friendly forums (where you have a lot more formatting options) and post your question. There are a lot of knowledgeable and witty people who would be happy to help you out

Share

Did you enjoy reading this and found it useful? If so, please share it with your friends:

If you didn't like it, I always like to hear how I can do better next time. Please feel free to contact me directly via e-mail, facebook, or twitter.

Kirupa Chinnathambi
I like to talk a lot - A WHOLE LOT. When I'm not talking, I've been known to write the occasional English word. You can learn more about me by going here.

Add Your Comment (or post on the Forums)

blog comments powered by Disqus

Awesome and high-performance web hosting!
BACK TO TOP
new books - yay!!!