The Dom Is A Tree

The DOM Is a Tree

A tree? Like, with leaves?

What do we mean when we say that the DOM is a tree? Are we saying it has leaves?

Well, yes, metaphorically.

Trees make a good metaphor for the DOM because we intuitively understand how we might traverse them. Starting at the roots, one can climb up the tree and out to the farthest — and thinnest — branches.

The thicker a branch is, the stronger its connections are: the more it holds within it.

Likewise, the thinner a branch is, the less it holds inside.

The DOM works basically the same way, except we usually talk about the root as being at the top of the DOM and the leaves being the most deeply nested HTML elements. So basically, we can imagine a tree turned on its head.

The DOM

An interesting property of trees is that every tree can contain subtrees, which we can, for all intents and purposes, treat independently of their parent trees.

Practically speaking, the DOM begins at <html>, but we should think carefully about manipulating what's between the <head></head> tags. Instead, we can look at the DOM subtree with its root at <body> and only deal with things that will be visible on the page. Within that tree, we might also deal with subtrees. So, for example, if we have

<body><div><p>Hi!</p></div><div><p>Bye!</p></div></body>

We would have a tree that looks like

body
/ \
div div
/ \
p p
/ \"Hi!""Bye!"

Pretty simple, right? Similarly, if we had a DOM subtree that looked like

<div><div><h1>Hello!</h1></div><div><h5>Sup?</h5></div></div>

We could simply treat it as the tree

div
/ \
div div
/ \
h1 h5
/ \"Hello!""Sup?"

Finding a Node

Remember when we said that we could organize our tree in such a way that a node's metadata didn't interfere with finding its children? It turns out that not only does providing additional information about a node make it more useful, it also makes it easier to find.

JavaScript exposes a few ways of finding DOM nodes more or less directly, courtesy of the document object.

document.getElementById()

This method provides the quickest access to a node, but it requires that we know something very specific about it — its id. Since IDs must be unique, this method only returns one element. (If you have two elements with the same ID, this method returns the first one — keep your IDs unique!) Given the following DOM tree

<div><h5id="greeting">Hello!</h5></div>

we could find the h5 element with document.getElementById('greeting'). Notice how the id that we pass to getElementById is identical to the id in <h5 id="greeting">. We can assign properties to HTML nodes (or elements) simply by including them between the <> tags at the start of the element (so not in the </h5> tag, in this case).

Try it out!

Open up your web inspector (command+option+j on OS X) and find an element on the page — make note of its id. Then open up your console, type document.getElementById('theIdYouTookNoteOf'), and check out your handy dandy DOM node. Try changing a few of its properties!

document.getElementsByClassName()

This method, as its name implies, finds elements by their className. Unlike id, className does not need to be unique; as such, this method returns an HTMLCollection (basically a list of DOM nodes — note that it is not an array, even though it has a length property) of all the elements with the given class. You can iterate over an HTMLCollection with a simple for loop.

Given the following DOM tree

<!-- the `className` attribute is called `class` in HTML -- it's a bummer --><div><divclass="banner"><h1>Hello!</h1></div><divclass="banner"><h1>Sup?</h1></div><divclass="banner"><h5>Tinier heading</h5></div></div>

we could find all of the elements with className === 'banner' by calling document.getElementsByClassName('banner').

Try it out!

Inspect the web page again, this time making note of a className. Get all elements with that className and give 'em a look. Remember, you can use a for loop to loop through them. (You can also assign the return value of document.getElementsByClassName() to a variable: var elements = document.getElementsByClassName('banner').)

document.getElementsByTagName()

Suppose you don't know an element's ID but you do know its tag name (the tag name is the main thing between the <>, e.g., 'div', 'span', 'h1', etc.). Since tag names aren't unique, this method returns an HTMLCollection of 0 to many nodes with the given tag.

Try it out!

Explore the DOM in console by typing document.getElementsByTagName('div'). Remember, you can iterate through these elements using a simple for loop.

Finding a Node without knowing anything about it

What if we know next to nothing about an element? Or what if we're just interested in finding out more about the child nodes of a given element? This is where our knowledge of trees and nested data structures comes in handy!

Given the following DOM tree (which you can find in index.html — feel free to open the file up in your browser to play along!)

how would we go about changing only the second "Hello!" to "Goodbye!"? We couldn't just iterate over document.getElementsByTagName('div'), checking for textContent === "Hello!", because we'd inadvertently change all three "Hello!"s. More importantly, the DOM might change (more on that later), and we want to make sure that we're updating the right element.

Let's start by getting the <main> element:

constmain=document.getElementsByTagName('main')[0]

Then we can get the children of main using main.children, so we can get the second child with main.children[1].

constdiv=main.children[1]

Finally, we can get and update our <p> element with

// we can call getElementsByTagName() on an _element_// to constrain the search to its children!constp=div.getElementsByTagName('p')[0]p.textContent="Goodbye!"

Obviously, this way of accessing that text isn't fully generic, but it does a good job of demonstrating the basic tools available to us for finding and manipulating HTML elements.

Learn about Flatiron School's Mission

With a new take on education that falls somewhere between self-taught prodigy and four-year computer science degree, the Flatiron School promises to turn students with little programming experience into developers.

In the six months since the Manhattan coding school was acquired by WeWork, it has spawned locations in Washington, D.C., Brooklyn, and London. Now, WeWork is opening a fourth Flatiron School location, this time in Houston.

Adam Enbar, Flatiron School's cofounder, believes now is the time to grow. "How the world is changing has impacted working and learning in very similar ways. We think education fundamentally is about one thing: enabling people to pursue a better life."

Learn. Love. Code.

Students come to Flatiron School to change their lives. Join our driven community of career-changers and master the skills you need to become a software engineer or a data scientist.