The Document Object Model

Document structure

You can imagine an HTML document as a nested set of boxes.

Tags such as <body> and </body> enclose other tags, which in turn contain other tags or text. Here’s the example document from the previous chapter:

<!doctype html>
<html>
  <head>
    <title>My home page</title>
  </head>
  <body>
    <h1>My home page</h1>
    <p>Hello, I am Marijn and this is my home page.</p>
    <p>I also wrote a book! Read it
      <a href="http://eloquentjavascript.net">here</a>.</p>
  </body>
</html>

Finding elements

Navigating these links among parents, children, and siblings is often useful.

But if we want to find a specific node in the document, reaching it by starting at document.body and following a fixed path of properties is a bad idea.

Doing so bakes assumptions into our program about the precise structure of the document—a structure you might want to change later. Another complicating factor is that text nodes are created even for the whitespace between nodes.

The example document’s <body> tag does not have just three children (<h1> and two <p> elements) but actually has seven: those three, plus the spaces before, after, and between them.

So if we want to get the href attribute of the link in that document, we don’t want to say something like “Get the second child of the sixth child of the document body”. It’d be better if we could say “Get the first link in the document”. And we can.

let link = document.body.getElementsByTagName("a")[0];
console.log(link.href);