Home Module 10 What is the DOM?

1. Introduction

When a browser loads an HTML page, it does not just display the raw text — it parses the HTML and builds an internal tree of objects that represents the page. This tree is called the DOM: the Document Object Model.

JavaScript does not directly touch the HTML file. Instead, it reads and modifies the DOM — and the browser instantly reflects those changes on screen. This is how web pages become interactive:

  • A button click adds a new <li> to a list → JavaScript creates a DOM node and inserts it.
  • A form is submitted → JavaScript reads the input values from DOM nodes.
  • A user switches theme → JavaScript changes class names on DOM nodes, which CSS then styles differently.

Understanding the DOM is the bridge between "knowing JavaScript syntax" and "building real web pages."

2. Theory

2.1 The DOM tree

The browser converts HTML into a tree where:

  • Each HTML tag becomes a node (an object).
  • Nodes are related: parent, children, and siblings.
  • Text inside a tag is a text node.
  • Attributes (id, class, href) are properties of the element node.
<!-- HTML -->
<body>
  <h1 id="title">Hello</h1>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
  </ul>
</body>

DOM tree equivalent:

document
  └── html
        ├── head
        └── body
              ├── h1#title  ← element node, id="title"
              │     └── "Hello"  ← text node
              └── ul
                    ├── li
                    │     └── "Item 1"
                    └── li
                          └── "Item 2"

2.2 The document object

The entry point to the DOM is the global document object. It represents the entire page and provides methods to find and create elements.

// document is always available in the browser
console.log(document);           // the whole page
console.log(document.title);     // the <title> text
console.log(document.URL);       // current URL
console.log(document.body);      // the <body> element
console.log(document.head);      // the <head> element
console.log(document.documentElement); // the <html> element

2.3 Node types

TypenodeType valueExample
Element node1<div>, <p>, <button>
Text node3The text inside a tag
Comment node8<!-- comment -->
Document node9document itself

In everyday DOM work, you almost exclusively deal with element nodes (nodeType 1).

2.4 Key DOM properties

const el = document.querySelector('p');

// Navigation
el.parentElement      // the parent element
el.children           // HTMLCollection of child elements
el.firstElementChild  // first child element
el.lastElementChild   // last child element
el.nextElementSibling // next sibling element
el.previousElementSibling // previous sibling element

// Content
el.textContent  // all text inside (including hidden text)
el.innerHTML    // the HTML markup inside
el.outerHTML    // the element itself + its inner HTML

// Identification
el.tagName      // 'P' (uppercase)
el.id           // the id attribute value
el.className    // the class attribute as a string
el.classList    // DOMTokenList for working with classes

// Dimensions
el.offsetWidth   // element width including border
el.offsetHeight  // element height including border
el.getBoundingClientRect() // position relative to viewport

2.5 The window object

The window object is the global scope in a browser. It sits above document:

window.document  // the DOM document
window.location  // current URL, navigation
window.history   // browser history
window.navigator // device/browser info
window.innerWidth  // viewport width
window.innerHeight // viewport height
window.scrollY     // how far the page is scrolled
window.alert('Hi') // same as alert('Hi')

// console.log is a shorthand for window.console.log

2.6 DOM vs HTML source

The DOM is a live representation of the page, not a copy of the HTML file. JavaScript changes affect the DOM immediately — they do NOT change the HTML file on disk. If you reload the page, it goes back to the original HTML.

// Change the title
document.title = 'New Title'; // browser tab title changes immediately
// But if you view the HTML source (Ctrl+U), it still shows the original

// The DOM is what you see in DevTools Elements tab
// The HTML source is what was sent by the server

2.7 Exploring the DOM in DevTools

Open DevTools (F12) and click the Elements tab to see the live DOM tree. You can:

  • Click any element to inspect its properties.
  • Double-click text to edit it live.
  • Right-click an element → "Store as global variable" → manipulate it from the Console.
  • Type $0 in the Console to reference the currently selected element.
  • Type document.querySelector('selector') to find and inspect any element.

3. Real World Example

When you type in a search box on a website:

  1. The browser has a DOM node for the <input> element.
  2. Every keystroke fires an event (Module 11). An event handler reads inputEl.value from the DOM.
  3. JavaScript filters a list of results and updates DOM nodes to show/hide matching items.
  4. The page updates instantly — no server request, no reload.

The DOM is the live canvas. JavaScript reads from it (get input values, check states) and writes to it (update text, add/remove elements, change styles).

4. Code Example

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>DOM Explorer</title></head>
<body>
  <h1 id="main-title">DOM Introduction</h1>
  <p class="intro">The DOM is a tree of objects.</p>
  <ul id="list">
    <li>First item</li>
    <li>Second item</li>
  </ul>
  <button id="explore-btn">Explore DOM</button>

  <script>
    document.querySelector('#explore-btn').addEventListener('click', () => {
      // The document object
      console.log('Title:', document.title);
      console.log('URL:', document.URL);

      // Find elements
      const heading = document.querySelector('#main-title');
      const para    = document.querySelector('.intro');
      const list    = document.querySelector('#list');

      // Read properties
      console.log('Heading tag:', heading.tagName);       // H1
      console.log('Heading text:', heading.textContent);  // DOM Introduction
      console.log('Para class:', para.className);         // intro
      console.log('List children count:', list.children.length); // 2

      // Navigate the tree
      const firstItem = list.firstElementChild;
      console.log('First item:', firstItem.textContent);  // First item
      console.log('Its parent tag:', firstItem.parentElement.tagName); // UL
      console.log('Next sibling:', firstItem.nextElementSibling.textContent); // Second item

      // Window properties
      console.log('Viewport:', window.innerWidth, 'x', window.innerHeight);
    });
  </script>
</body>
</html>

5. Code Breakdown

document.title and document.URL

Properties of the document object that give page metadata. You can also set document.title = 'New Title' to change the browser tab label dynamically.

heading.tagName

Returns the tag name in uppercase: 'H1', 'P', 'UL'. Note uppercase — this is a legacy convention from the HTML spec.

list.children.length

children is an HTMLCollection of direct child elements. It is "live" — if you add a new <li>, the length automatically updates without re-querying.

Tree navigation (firstElementChild, nextElementSibling)

These properties let you walk the DOM tree. Starting from any element you can reach its parent, children, or siblings. This is useful for traversing related elements without re-querying the document.

window.innerWidth / innerHeight

The viewport dimensions in pixels. Useful for layout calculations, responsive JavaScript, and knowing if something is visible on screen.

6. Common Mistakes

Mistake 1 — Confusing textContent and innerHTML

const el = document.querySelector('p');

// textContent — safe, treats content as plain text
el.textContent = '<b>Bold</b>'; // displays the literal string, not bold text

// innerHTML — interprets as HTML (use carefully, XSS risk!)
el.innerHTML = '<b>Bold</b>'; // displays bold text

Mistake 2 — Accessing the DOM before it loads

<head>
  <script>
    // Bad — runs before body exists
    document.querySelector('#btn'); // null
  </script>
</head>
<body>
  <button id="btn">Click</button>
</body>

<!-- Fix: script at bottom of body, or use defer -->

Mistake 3 — Assuming querySelector always finds something

const el = document.querySelector('#non-existent');
el.textContent = 'Hello'; // TypeError: Cannot set properties of null

// Always check
if (el) el.textContent = 'Hello';
// Or: el?.textContent = 'Hello'; // optional chaining

Mistake 4 — Confusing children and childNodes

// children — only element nodes (what you usually want)
el.children         // HTMLCollection of element children

// childNodes — ALL nodes including text and comment nodes
el.childNodes       // NodeList with text nodes, elements, comments
// Whitespace between tags creates text nodes!

7. Best Practices

  1. Place scripts at bottom of body or use defer so the DOM is ready before your script runs.
  2. Use textContent for plain text and innerHTML only when you need to insert HTML markup.
  3. Never set innerHTML from user input without sanitising — it opens XSS vulnerabilities.
  4. Cache DOM references in variables — repeatedly calling querySelector for the same element is inefficient.
  5. Check for null before accessing properties of elements that might not exist.
  6. Use DevTools Elements tab to explore the live DOM as you write code.

8. Practice Exercise

  1. Open any web page, open DevTools Console, and type:
    • document.title
    • document.body.children.length
    • document.querySelector('h1').textContent
  2. Create an HTML page with a heading, paragraph, and unordered list. Write a script that logs:
    • The heading's tag name and text content
    • The number of list items
    • The text of the first and last list item
    • The class name of the paragraph
  3. Use tree navigation (parentElement, nextElementSibling) to move between elements without re-querying.

9. Assignment

Build a "DOM Inspector" tool.

  1. Create an HTML page with several elements (heading, paragraphs, a list, an image, a form).
  2. Add a button "Inspect Page". When clicked, it logs a report to the console:
    • Page title and URL
    • Number of all elements on the page (document.querySelectorAll('*').length)
    • Number of headings, paragraphs, links, images
    • Text content of the first heading
    • Viewport width and height
  3. Also display the report as formatted HTML in a <pre> element on the page.

Deliverable: One HTML file.

10. Interview Questions

  1. What is the DOM?
    The Document Object Model is a tree of objects the browser creates from HTML. It is a live, in-memory representation of the page. JavaScript reads and modifies the DOM to change what is displayed — it does not change the HTML file on disk.
  2. What is the difference between the DOM and the HTML source?
    The HTML source is the file sent by the server. The DOM is the browser's parsed, live representation of it. JavaScript changes affect the DOM immediately but not the source file. Viewing source (Ctrl+U) shows the original HTML; DevTools Elements tab shows the live DOM.
  3. What is the document object?
    The global entry point to the DOM. It represents the entire page and provides methods to query (querySelector, getElementById) and create (createElement) nodes.
  4. What is the difference between textContent and innerHTML?
    textContent sets or gets plain text — any HTML tags are treated as literal characters. innerHTML parses the string as HTML markup. Use textContent for user-generated content to prevent XSS attacks.
  5. What is the window object?
    The global object in a browser environment. It contains document, location, history, navigator, and all global functions (setTimeout, alert, etc.). Variables declared with var at the top level become window properties.

11. Additional Resources

  • MDN — Introduction to the DOM
  • javascript.info — Browser: Document, Events, Interfaces
  • MDN — Document object reference
  • MDN — Node reference — parent class of all DOM nodes