4.1 Module 4 · Document Object Model (DOM)

DOM Structure

Understand how browsers turn your HTML into a navigable tree of objects — and how JavaScript uses the document entry point to read and manipulate every part of a live web page.

1

Definition

The Document Object Model (DOM) is a programming interface for web documents. When a browser loads an HTML page it parses the markup and builds a tree of objects — one object for every element, attribute, and piece of text. JavaScript can then use this tree to read, change, add, or remove anything on the page without reloading it.

The DOM is live — any change made through JavaScript is immediately reflected in what the user sees. This is what makes modern interactive web applications possible.

2

Simple Way

Think of the DOM as a family tree for your webpage:

document The root of the entire tree — your entry point into any page
node Any single item in the tree — an element, text, comment, or attribute
element A node that represents an HTML tag — <h1>, <p>, <div>
parent / child Elements that contain others are parents — elements inside are their children
3

Code Examples

Example 1 — HTML That Becomes the DOM Tree
<!-- This HTML produces the tree shown below -->
<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
    <h1>Hello</h1>
    <p>Welcome</p>
  </body>
</html>

/*
  Document
   └── html
        ├── head
        │    └── title  ("My Page")
        └── body
             ├── h1  ("Hello")
             └── p   ("Welcome")
*/
Explanation
  • document is the invisible root that holds everything
  • html is the child of document and the parent of head and body
  • h1 and p are siblings — both children of body
Example 2 — Accessing DOM Nodes in JavaScript
// document is always available in the browser
console.log(typeof document);          // "object"
console.log(document.title);           // page title

// Navigate to body
console.log(document.body);            // the body element

// childNodes includes text nodes (spaces/line breaks too)
console.log(document.body.childNodes); // NodeList

// children — only element nodes (recommended)
console.log(document.body.children);   // HTMLCollection
Output
Click ▶ Run to execute
Explanation
  • document.body is a direct shortcut to the <body> element
  • childNodes returns all nodes including whitespace text nodes between tags
  • children returns only element nodes — much cleaner for most tasks
Example 3 — Node Types
// Every node has a nodeType property:
//   1 → Element node  (e.g. <div>, <p>)
//   3 → Text node     (the actual text content)
//   8 → Comment node  (<!-- ... -->)
//   9 → Document node (the document itself)

console.log(document.nodeType);       // 9 (Document)
console.log(document.body.nodeType);  // 1 (Element)

// nodeName tells you what kind of element it is
console.log(document.body.nodeName); // "BODY"
Output
Click ▶ Run to execute
Explanation
  • Every node in the DOM has a nodeType number — element nodes are 1, text nodes are 3
  • nodeName returns the tag name in uppercase for element nodes
  • This is how you can tell whether you're looking at an element or a text node when iterating
Example 4 — Navigating the Tree
// Navigate up, down, and sideways through the tree
let body = document.body;

console.log(body.parentNode);          // html element (parent)
console.log(body.firstElementChild);   // first element child
console.log(body.lastElementChild);    // last element child
console.log(body.children.length);     // number of element children

// parentElement is the cleaner version of parentNode for elements
console.log(body.parentElement);       // html element
Output
Click ▶ Run to execute
Explanation
  • parentNode / parentElement — move up one level
  • firstElementChild / lastElementChild — access first or last child element directly
  • children.length — count how many direct element children a node has
4

Real-Life Example

Think of the DOM like a company org chart:

document
The CEO — the top of the entire organisation, entry point for everything
<html>
The COO — directly under the CEO, manages all departments
<body>
The department manager — oversees all visible page content
<h1>, <p>
Individual employees — each has a specific role on the page
Text node
The actual work being done — the words the user reads
Live DOM
Org chart updates in real time — promote someone and the chart changes instantly
5

HTML + JavaScript Example

Click ▶ Preview, then press the button to inspect the DOM tree live — printing the tag name, node type, and child count of every direct child of <body>.

Live in Browser — DOM Tree Inspector
<!DOCTYPE html>
<html>
<head><title>DOM Structure</title></head>
<body style="font-family:sans-serif;padding:24px;background:#f8f9fa">

  <h1 id="title">Hello Aman</h1>
  <p id="intro">Learning DOM</p>

  <button onclick="inspectDOM()"
    style="margin-top:12px;padding:8px 18px;background:#f7df1e;border:none;
           border-radius:6px;cursor:pointer;font-weight:700;font-size:1rem">
    Inspect DOM
  </button>

  <div id="output"
    style="margin-top:16px;font-size:0.9rem;line-height:2;
           font-family:monospace;background:#1e1e2e;color:#cdd6f4;
           border-radius:8px;padding:16px">
  </div>

  <script>
    function inspectDOM() {
      let info = "";

      info += "document.title: <b>" + document.title + "</b><br>";
      info += "document.body.nodeType: <b>" + document.body.nodeType + "</b> (Element)<br>";
      info += "body.children.length: <b>" + document.body.children.length + "</b><br><br>";

      info += "<b>Direct element children of <body>:</b><br>";
      for (let el of document.body.children) {
        info += "  &lt;" + el.tagName.toLowerCase() + "&gt;";
        if (el.id) info += " #" + el.id;
        info += " → nodeType: " + el.nodeType;
        info += ", children: " + el.children.length + "<br>";
      }

      document.getElementById("output").innerHTML = info;
    }
  </script>

</body>
</html>
Live Preview
6

Tasks (Practice)

Easy Task 1 — Inspect document.body
Starter code (run in browser console)
// Open any web page and run these in DevTools console
console.log(document.body);
console.log(document.body.nodeType);
console.log(document.body.nodeName);
console.log(document.title);
  • Open DevTools (F12) on any page and run the code above in the Console tab
  • Confirm nodeType is 1 (Element) and nodeName is "BODY"
  • Navigate upward: document.body.parentElement — what does it return?
Medium Task 2 — childNodes vs children
Starter code
// Compare the two collections
console.log("childNodes:", document.body.childNodes.length);
console.log("children:",   document.body.children.length);

// Loop through element children only
for (let el of document.body.children) {
  console.log(el.tagName);
}
  • Run the code — observe that childNodes is larger (includes text/whitespace nodes)
  • Use children instead and loop through — confirm only element tags are listed
  • Print the firstElementChild and lastElementChild of document.body
7

MCQs

Q1
What does the DOM represent?
  • A CSS styles of a page
  • B HTML as a live tree of objects
  • C A database for web data
  • D A server-side rendering engine
💡 B is correct. The DOM is a live, tree-structured representation of the HTML document. JavaScript uses it to read and modify any part of the page without reloading.
Q2
What is the root / entry point of the DOM?
console.log(typeof document);
console.log(document.nodeType);
Output
Run it to verify
  • A <body>
  • B <html>
  • C document
  • D window
💡 C is correct. document is the top-level object representing the entire HTML page. It has nodeType === 9 (Document node) and is the starting point for all DOM traversal and selection.
Q3
Which property returns all child nodes including text and whitespace?
console.log(document.body.childNodes.length);
console.log(document.body.children.length);
Output
Run it to verify
  • A children
  • B childNodes
  • C getElementById
  • D querySelector
💡 B is correct. childNodes returns every node including text nodes (whitespace, line breaks, comments). children returns only element nodes — the one you should reach for in most situations.
8

Pro Tips & Extra Knowledge

  • 01

    Always use children instead of childNodes unless you specifically need text nodes — whitespace between tags creates unexpected text nodes:

    childNodes vs children
    // childNodes includes whitespace text nodes between tags
    let allNodes = document.body.childNodes;
    console.log("childNodes length:", allNodes.length);
    
    // children gives only element nodes — predictable
    let elements = document.body.children;
    console.log("children length:", elements.length);
    
    // Loop safely with children
    for (let el of document.body.children) {
      console.log(el.tagName); // always a real tag, never a text node
    }
    Output
    Click ▶ Run to execute
  • 02

    The DOM is live — collections like children automatically update when you add or remove elements, which can cause bugs if you're looping while modifying:

    DOM is live — changes instantly
    // Check child count before and after a DOM change
    console.log("Before:", document.body.children.length);
    
    let p = document.createElement("p");
    p.textContent = "Dynamically added";
    document.body.appendChild(p);
    
    // The live collection updates immediately
    console.log("After:", document.body.children.length);
    Output
    Click ▶ Run to execute
  • 03

    Use document.documentElement to access the <html> root element — distinct from document.body:

    document shortcuts
    console.log(document.documentElement.nodeName); // "HTML"
    console.log(document.head.nodeName);            // "HEAD"
    console.log(document.body.nodeName);            // "BODY"
    console.log(document.title);                    // page title string
    Output
    Click ▶ Run to execute
  • 04

    Use browser DevTools to explore the DOM visually — the Elements panel is the live DOM tree. Right-click any element on a page and choose Inspect to navigate to it instantly.

Mini Challenge

How many child nodes does this <body> have — and how many are element nodes? Think carefully before running.

What does this print?
// Imagine a page whose body looks like:
// <body>\n  <h1>Hello</h1>\n</body>

// In the runner here, document.body has its own children:
console.log("childNodes:", document.body.childNodes.length);
console.log("children:",   document.body.children.length);
console.log("first child nodeType:", document.body.childNodes[0]?.nodeType);
Output
Think first, then run!
Step-by-Step Explanation
// Consider a body written as:
//   <body>
//     <h1>Hello</h1>
//   </body>

// The newline + spaces between <body> and <h1> is a TEXT NODE
// The <h1> itself is an ELEMENT NODE (nodeType 1)
// The newline after </h1> is another TEXT NODE

// So childNodes.length may be 3:
//   [0] Text node  "\n  "   nodeType: 3
//   [1] h1 element          nodeType: 1
//   [2] Text node  "\n"     nodeType: 3

// children.length is 1:
//   only the <h1> — text nodes are excluded

// Key takeaway:
//   childNodes counts EVERYTHING (including whitespace)
//   children counts only HTML ELEMENTS
//
//   The actual count varies depending on the page you run it on.
//   In this runner, document.body contains the page's own elements.
//   Always prefer .children when you want predictable results.