Command Palette

Search for a command to run...

Hectal
PHASE 8Intermediate ~21 min· topic 1 of 8

Topic 8.1

What the DOM Is

In one line

The DOM is the live tree of objects the browser builds from your HTML; every tag, piece of text and comment becomes a node in it, document is the entry point, and changing the tree changes the page you see.

Think of it like this

A family tree. At the top is a great-grandparent, below are their children, and below them the grandchildren. Every person has exactly one parent above them (except the top one), may have children, and may have brothers and sisters next to them. The browser draws your web page as a family tree just like this. <html> is at the top, <head> and <body> are its children, and every heading and paragraph sits somewhere below. JavaScript can walk this tree, read it and change it.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

DOM
Document Object Model: the tree of objects the browser builds from your HTML, which JavaScript can read and change.
Node
Any single item in the DOM tree: an element, a piece of text, a comment, or the document itself.
Element
A node made from a tag, like <p> or <button>. Elements are one kind of node.
Text node
A node holding only text, including the spaces and new lines between tags.
Parent, child, sibling
Family words for the tree: the node that contains you, the nodes you contain, and the nodes beside you with the same parent.
document
The global object for the whole page: the top of the DOM tree and the starting point for finding and making elements.
nodeType
A number on every node saying what kind it is: 1 element, 3 text, 8 comment, 9 document.
Render tree
What the browser builds from the DOM plus CSS to decide what to draw; hidden elements are left out.

Step by step

01Start from the HTML

Here is a small page. It looks like text, but the browser reads it as a set of boxes inside boxes.

index.htmlwhole filehtml
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Shop</title>
  </head>
  <body>
    <h1>Lamps</h1>
    <p>Only <b>two</b> left!</p>
  </body>
</html>

02See it as a tree

The browser turns each tag into an element node and each piece of text into a text node. document sits on top. <b> is a child of <p>, and the text two is a child of <b>.

The whitespace text nodes (the line breaks and spaces between tags) are left out of this picture to keep it readable, but they are really there.

See it as a treediagram
Rendering diagram…

03Reach into the tree from JavaScript

Every box in the picture is an object you can reach. document.body is the <body> element; document.querySelector("b") finds the <b>; its firstChild is the text node two.

app.jswhole filejavascript
console.log(document.body);                       // <body>
const b = document.querySelector("b");
console.log(b.parentNode);                        // <p>
console.log(b.firstChild.nodeType);               // 3 (a text node)

04Change the tree, change the page

Set a property on a node and the screen updates. Nothing in index.html changes: the file on the server stays the same. Reload the page and the browser builds a fresh tree from the file, so your change is gone.

app.jswhole filejavascript
document.querySelector("b").textContent = "three";
// the page now says: Only three left!

05Check the real tree in DevTools

Right-click anything on a page and choose Inspect. The Elements panel shows the live DOM, updated as JavaScript changes it. Select an element there and type $0 in the Console: it refers to the selected node, so $0.textContent reads its text.

Try it yourself

  1. 1

    Remove the whitespace

    In the first example, write the whole #card on one line with no spaces between the tags. Predict the new childNodes count before you run it.

  2. 2

    Find another fix-up

    In the second example, add <p>One<p>Two to the HTML (no closing tags) and log document.querySelectorAll("p").length. How many paragraphs did the browser make, and where did it close the first one?

  3. 3

    Explore a real page

    Open DevTools on any website, select an element in Elements, then type $0.nodeType, $0.parentNode and $0.childNodes.length in the Console. Compare the counts with what the Elements panel shows.

Code & diagrams

Nodes, elements and the whitespace you can't see New tab

The card has 2 element children but 5 child nodes: the line breaks and spaces between the tags are text nodes (type 3). `nodeName` is upper case for HTML elements.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

#document
9 #document
<html> <head> <body>
children: 2 childNodes: 5
3 #text
1 H2
3 #text
1 P
3 #text
#text 'bold'
The DOM is what the browser built, not your file New tab

The HTML never mentions `<tbody>`, but the parser added one because the HTML standard says table rows live inside a table section. The comment is a real node of type 8.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

Parent of the row: <tbody>
<tbody><tr><td>Lamp</td><td>499</td></tr></tbody>
8 #comment
 a comment is a node too 
Change the tree and the page follows New tab

The page updated as soon as the properties changed. Press Run again: the browser rebuilds the tree from the HTML tab, so the change starts over, just like reloading a real page.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

Before: two
After: three
Only three left!

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Expect `firstChild` to be the first tag

In the first example, add console.log(card.firstChild.textContent.length, card.firstChild.nodeName); and expect the <h2>.

terminal
$ Console
── what you'll see ──
3 #text

Break #2

Use the DOM where there is no page

Save console.log(document.body); in dom.js and run node dom.js.

terminal
$ node dom.js
── what you'll see ──
ReferenceError: document is not defined

Myth vs fact

Myth

The DOM is the same thing as my HTML file.

Fact

The HTML file is text. The DOM is the tree of objects the browser built from it, after fixing mistakes and adding missing parts, and it keeps changing as JavaScript runs. View Source shows the file; DevTools Elements shows the DOM.

Myth

Nodes and elements are the same.

Fact

Elements are one kind of node. Text, comments and the document are nodes too. childNodes includes them all; children lists only elements.

Myth

The DOM is part of JavaScript.

Fact

The DOM is a browser API defined by the WHATWG DOM and HTML standards. JavaScript is one language that uses it. The same tree is what screen readers, extensions and DevTools work with.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    DOM objects are host objects: JavaScript wrappers around C++ objects inside the browser engine (Blink in Chrome, Gecko in Firefox, WebKit in Safari). Every property read crosses from the JavaScript engine into the rendering engine. That crossing is cheap but not free, so code that reads the same property thousands of times in a loop should store it in a variable first.

  • ▸

    Each node type is a class in a long inheritance chain: a <p> is an HTMLParagraphElement, which extends HTMLElement, then Element, then Node, then EventTarget. Try Object.getPrototypeOf(document.querySelector("p")) and follow the chain: it's the prototype chain from Topic 7.3 in action.

  • ▸

    The accessibility tree, which screen readers use, is built from the DOM plus CSS and ARIA. Removing an element, hiding it with display: none or changing its role from JavaScript changes what assistive technology announces too (see the /html course, Phase 7).

  • ▸

    Parsing rules are exact and the same in every modern browser (the HTML5 parsing algorithm), which is why the <tbody> fix-up and the auto-closing of <p> happen identically everywhere. Before HTML5, each browser repaired broken markup differently.

Remember this

  1. 1

    When the browser loads a page, it parses the HTML (reads it from top to bottom) and builds the DOM, short for Document Object Model. Document means the page. Object means every part of the page becomes a JavaScript object with properties and methods. Model means it is a structured copy of the page that programs can work with. The DOM is not your HTML file: it is what the browser built from it, and it changes while the page is open.

  2. 2

    The DOM is a tree. Each item in it is a node. A node that contains other nodes is their parent; the nodes inside are its children; nodes with the same parent are siblings. The single node at the very top is document, and its one element child is <html>, called document.documentElement. Shortcuts take you to common places: document.head, document.body, document.title.

  3. 3

    There are several kinds of node, and each has a number in its nodeType property. An element node (type 1) is a tag such as <p> or <li>. A text node (type 3) is the text inside or between tags, including the spaces and line breaks you typed to indent your HTML. A comment node (type 8) is an <!-- comment -->. The document node (type 9) is document itself. So every element is a node, but not every node is an element. That difference explains why childNodes (all nodes) and children (elements only) give different counts.

  4. 4

    document is a global object the browser gives you. It is the doorway to the whole page: you use it to find elements (document.querySelector), create new ones (document.createElement) and read page details (document.title, document.URL). document comes from the browser, not from the JavaScript language: Node.js has no document because it has no page (see Topic 0.1).

  5. 5

    The browser fixes broken or incomplete HTML as it builds the tree, following exact rules in the HTML standard. A <table> with rows written straight inside it gets a <tbody> added. A <p> left unclosed is closed when the next block starts. Missing <html>, <head> and <body> tags are added. So the tree can differ from your source, and the Elements panel in DevTools always shows the real DOM, not the file. (View Source shows the file.)

  6. 6

    The DOM is live: change it and the browser updates the screen. Under the hood, the browser combines the DOM with the CSS rules into a render tree, works out sizes and positions (layout), then draws pixels (paint). Every DOM change can start this work again, which is why Topic 8.8 shows how to change the page efficiently. The DOM is defined by the DOM Standard and the HTML Standard from WHATWG, not by ECMAScript, so it has no since tags like the language features do.

Explain it without notes

01

What is the DOM, and how is it different from the HTML source?

02

What is the difference between a node and an element? Give three kinds of node.

03

Why can childNodes.length be larger than children.length?

04

Is the DOM part of JavaScript? Explain where it comes from.

Practice

01

Given <ul id="menu"> with three <li> items on separate lines, log the nodeName of every child node and then the number of element children.

02

Log the nodeType and nodeName of document, document.documentElement and the first text node inside a <p>.

Trade-offs

  • ↔

    Changing the DOM directly is simple and fast for small pages; large apps often use a framework (React, Vue, Svelte) that keeps its own description of the page and updates the DOM for you, which costs some download size and indirection but keeps big UIs consistent. The React course (/react) teaches that approach from zero once you're comfortable with the DOM.

  • ↔

    Indenting HTML makes it readable but creates whitespace text nodes; that is harmless when you use element-only APIs, and only matters when you walk childNodes or in rare inline layout cases.

Done when you can

  • I can explain the DOM as a tree of nodes built from HTML.

  • I know the difference between nodes and elements, and between childNodes and children.

  • I can name the node types 1, 3, 8 and 9.

  • I know the browser fixes HTML as it builds the tree, and that DevTools Elements shows the real DOM.

  • I know document comes from the browser, not from the JavaScript language.