Topic 01

The DOM Is a Tree

ConceptJavaScript

Chapters 6 and 7 gave you a programming language, but so far it has only talked to you through the Console. To change what a visitor sees, a script needs a way to reach the heading, the list or the button on the page. The browser provides one. When it reads your HTML, it builds a model of the page in memory: one object for every element and every piece of text, each connected to the objects around it. That model is the DOM, the Document Object Model that Chapter 1 named, and it is what JavaScript reads and changes.

The DOM has the shape of a family tree. Every element has exactly one parent, the element it sits inside, and any number of children, the elements and text inside it. From anyone in a family tree you can reach anyone else by stepping up to a parent and down to a child, and the DOM works the same way. One difference matters: a family tree has no single ancestor at the top, while the DOM always has one, an object called document.

How Does Text Become a Tree?

The browser reads your file from top to bottom. Each start tag opens a new node, a single object in the tree, and everything between that start tag and its end tag becomes the node's children. Nesting in the file becomes parent and child in the tree.

Here is the outline of the site's index.html from Chapter 2, with the contents of each region left out. The html element is the child of document. The head and body are the children of html. The header, main and footer are the children of body, which makes them siblings: children of the same parent. The figure below draws the same tree.

Fragment
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Your Name</title>
  </head>
  <body>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </body>
</html>
The site's index.html as a DOM tree
The root
document
Its one child element
html
Child of html
head
Child of html
body
Child of body
header
Child of body
main
Child of body
footer

Text is part of the tree too, as its own kind of node. The words inside the h1 are not a setting of the heading; they are a text node, a child of the h1. Even the line breaks and spaces between elements in your file become small text nodes, which is why DevTools sometimes lists entries called text where you expected only elements. Most of the time you can ignore those. What matters is that "the heading" and "the heading's text" are two separate objects.

Why Is the Live Page Not the File?

The DevTools topic in Chapter 2 showed that View source and the Elements panel can disagree. Now the reason has a name. View source shows the file the server sent. The Elements panel shows the DOM: the tree as the browser built it, including the repairs it made to broken HTML and every change a script has made since.

The screen follows the tree, not the file. When a script changes a node, the browser works out what that change means for the layout and redraws the part of the page that changed, usually before the next frame. Nothing writes to the file on disk. Reload the page and the browser reads the file again and builds a fresh tree, so every change a script made is gone.

That separation is the point. Your HTML file is the starting state every visitor receives. The DOM is the working copy each visitor's browser keeps while the page is open, and JavaScript works only on that copy.

What Can You Read from a Node?

Each node in the DOM is a JavaScript object, the same kind of thing as the project objects in Chapter 7: a bundle of named values you read with a dot. An element node has properties that describe it. tagName is the element's name, in capital letters. textContent is all the text inside it, joined together. children is the collection of elements directly inside it.

Some properties hold a plain value, and some point at other nodes. document.body is the body element. Its children are the header, the main and the footer, and each of those has children of its own. Following those links is one way for a script to walk the tree. The next topic shows a much quicker way to reach any element directly.

Can You Talk to the DOM Yourself?

The Console is the fastest place to meet the DOM, because it runs JavaScript inside the page that is open. Open your site's Home page through the preview server, open DevTools, choose the Console panel, and type these four lines one at a time, pressing Enter after each.

Console
document.title
document.body.tagName
document.body.children
document.title = "Changed by the DOM"
Console output
'Your Name'
'BODY'
HTMLCollection(3) [header.site-header, main, footer]
'Changed by the DOM'

The first line reads the page's title, the text inside the title element, and the Console prints it in quotes because it is a string. Yours shows whatever your title element says. The second line asks the body for its name and gets BODY, in capitals. The third lists the body's children: a collection of three elements, the header, the main and the footer. Chrome writes the header as header.site-header: the element's name, then a dot and its class. The last line sets the title to new text, and the Console echoes the value it was given.

Now look at the browser tab: its label reads "Changed by the DOM". Open index.html in your editor, and the title element still holds the old text. Reload the page, and the tab shows the old title again. The file never changed; the tree did, for as long as the page was open.

Now switch to the Elements panel and open the head. At its top sits a script element you never wrote. Live Preview adds it to the page as it sends it, so that it can reload the page when you save. That element is on the page but not in your file on disk, a small reminder that the file is only where the page starts.

Common Confusions
  • "JavaScript edits my HTML file." It changes the tree in the browser's memory. The file stays as you saved it, and reloading the page builds the tree from the file again.
  • "The DOM is the same thing as the HTML." It starts from the HTML, then includes the browser's repairs to broken markup and every change scripts make. That is why the Elements panel can differ from View source.
  • "Text is just part of an element." Text is its own node, a child of the element that holds it. Changing an element and changing its text are different operations, as topic 3 shows.
Why It Matters
  • Every interactive thing in the rest of this book, from a filter to a theme switch, is a change to this tree.
  • It explains why a page in the browser can look different from its source, and where to look when it does.

Knowledge Check

What is the DOM?

  • The HTML file saved in the site's folder
  • A tree of objects the browser builds in memory
  • The DevTools panel where you type JavaScript
  • The list of CSS rules the page has loaded

A script changes a heading's text. You reload the page. What does the heading say?

  • The new text, because the change was saved
  • Nothing, because the heading was replaced
  • It asks whether to keep the change or not
  • The original text from the HTML file

In the site's DOM, which of these is the parent of the main element?

  • The header element
  • The document object
  • The body element
  • The head element

Where in DevTools do you see the DOM as the browser built it, with every change a script made?

  • The Elements panel, which shows the live tree
  • View source, which shows the page's file
  • The Network panel, which lists every file
  • The Console, which lists every element

You got correct