404 Not Found

404 Not Found


nginx

Introduction to the DOM

The DOM is the only bridge between JavaScript and web pages. Without the DOM, JS would be nothing more than a pure computation language. With the DOM, JS can "see" pages, modify pages, and bring them to life.

📖 Summary

What Is the DOM?

DOM stands for Document Object Model. When a browser loads HTML, it doesn't store it as plain text — it translates it into an object tree. Each HTML tag becomes an object (called a node), and the nesting relationships between tags become parent-child relationships in the tree.

Think of the DOM as an upside-down tree: at the very top is the root (document), branching down into limbs (html, head, body), and further down into leaves (div, p, span...).

DOM Tree Structure

The DOM tree of a simple HTML page looks roughly like this:

document
  └── html
       ├── head
       │    ├── meta
       │    └── title
       └── body
            ├── h1
            ├── p
            └── div
                 └── span

Node Types

There are three core node types in the DOM:

Node Type Description nodeType Value
Element node An HTML tag, e.g. p, div 1
Text node Text content inside a tag 3
Attribute node A tag's attribute, e.g. class, id 2 (deprecated for general use)
HTML
<p class="intro">Hello World</p>

In this single line: <p> is an element node, class="intro" is an attribute node, and Hello World is a text node. In everyday development, element nodes are what you'll work with the most.

The document Object

document is the entry point to the DOM — the browser provides this global object automatically. Through it you can:

What the DOM Does

JS itself cannot "see" a web page — it can only compute. The DOM provides the "eyes" and "hands":

Without the DOM, JS and HTML would be two completely separate things. The DOM connects them.


Example: Viewing the DOM Structure

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>DOM Structure</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .tree { margin: 16px 0; padding: 16px; background: #f5f5f5; border-radius: 8px; font-family: monospace; font-size: 14px; line-height: 1.8; }
    .node { color: #4a90d9; font-weight: bold; }
    .text-node { color: #5cb85c; font-style: italic; }
    .attr-node { color: #f0ad4e; }
    .indent { margin-left: 24px; }
    .info { background: #e8f4fd; padding: 12px; border-radius: 6px; margin: 16px 0; }
  </style>
</head>
<body>
  <h1 id="mainTitle">DOM Structure Demo</h1>
  <p class="intro">This is a paragraph</p>
  <div id="container">
    <span>Inline element</span>
  </div>
  <div id="output"></div>
  <script>
    function buildTree(node, depth) {
      if (depth > 4) return "";
      var indent = "";
      for (var i = 0; i < depth; i++) indent += "  ";
      var result = "";

      if (node.nodeType === 1) {
        result += indent + '<span class="node">&lt;' + node.nodeName.toLowerCase();
        if (node.attributes && node.attributes.length > 0) {
          for (var a = 0; a < node.attributes.length && a < 3; a++) {
            result += ' <span class="attr-node">' +
              node.attributes[a].name + '="' + node.attributes[a].value + '"</span>';
          }
        }
        result += '&gt;</span>\n';
      } else if (node.nodeType === 3) {
        var text = node.textContent.trim();
        if (text) {
          result += indent + '<span class="text-node">"' + text + '"</span>\n';
        }
        return result;
      }

      var children = node.childNodes;
      for (var c = 0; c < children.length; c++) {
        result += buildTree(children[c], depth + 1);
      }

      if (node.nodeType === 1) {
        result += indent + '<span class="node">&lt;/' +
          node.nodeName.toLowerCase() + '&gt;</span>\n';
      }

      return result;
    }

    var treeStr = buildTree(document.documentElement, 0);

    document.getElementById("output").innerHTML = `
      <h2>DOM Tree of This Page</h2>
      <div class="tree"><pre>${treeStr}</pre></div>
      <div class="info">
        <strong>Color Legend:</strong>
        <span class="node">Blue = Element node</span> |
        <span class="text-node">Green = Text node</span> |
        <span class="attr-node">Orange = Attribute</span>
      </div>
    `;
  </script>
</body>
</html>
▶ Try it Yourself

Example: Exploring the document Object

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>The document Object</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .card { border: 2px solid #4a90d9; border-radius: 8px; padding: 16px; margin: 12px 0; background: #f0f7ff; }
    .card h3 { margin: 0 0 8px; color: #4a90d9; }
    .prop { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid #e0e0e0; }
    .prop:last-child { border-bottom: none; }
    .key { font-weight: bold; color: #333; }
    .val { color: #4a90d9; font-family: monospace; word-break: break-all; }
    button { padding: 10px 20px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; margin: 4px; }
    .btn-blue { background: #4a90d9; color: #fff; }
    .btn-blue:hover { background: #357abd; }
    .btn-green { background: #5cb85c; color: #fff; }
    .btn-green:hover { background: #449d44; }
    .btn-orange { background: #f0ad4e; color: #fff; }
    .btn-orange:hover { background: #ec971f; }
    .demo-area { min-height: 60px; border: 2px dashed #ccc; border-radius: 8px; padding: 16px; margin: 12px 0; text-align: center; }
  </style>
</head>
<body>
  <h2>Exploring the document Object</h2>

  <div class="card">
    <h3>Common document Properties</h3>
    <div id="props"></div>
  </div>

  <div class="card">
    <h3>Try It Yourself</h3>
    <button class="btn-blue" id="btnTitle">Change document.title</button>
    <button class="btn-green" id="btnBody">Change body background</button>
    <button class="btn-orange" id="btnCreate">Create a new element</button>
    <button class="btn-blue" id="btnReset" style="background:#888;">Reset</button>
  </div>

  <div class="demo-area" id="demoArea">
    <p>This is the demo area</p>
  </div>

  <script>
    function showProps() {
      var props = [
        ["document.title", document.title],
        ["document.URL", document.URL],
        ["document.domain", document.domain],
        ["document.contentType", document.contentType],
        ["document.documentElement", document.documentElement.nodeName],
        ["document.body", document.body.nodeName],
        ["document.head", document.head.nodeName],
        ["document.body.childElementCount", document.body.childElementCount],
        ["document.all.length", document.all.length + " elements"]
      ];

      document.getElementById("props").innerHTML = props.map(function(p) {
        return '<div class="prop"><span class="key">' + p[0] +
          '</span><span class="val">' + p[1] + '</span></div>';
      }).join("");
    }

    showProps();

    var titleCount = 0;
    document.getElementById("btnTitle").addEventListener("click", function() {
      titleCount++;
      document.title = "Changed " + titleCount + " time(s)!";
      showProps();
    });

    var bgColors = ["#fff8e1", "#e8f5e9", "#fce4ec", "#e3f2fd", "#f3e5f5"];
    var bgIndex = 0;
    document.getElementById("btnBody").addEventListener("click", function() {
      document.body.style.background = bgColors[bgIndex % bgColors.length];
      bgIndex++;
    });

    var createCount = 0;
    document.getElementById("btnCreate").addEventListener("click", function() {
      createCount++;
      var p = document.createElement("p");
      p.textContent = "Newly created paragraph #" + createCount;
      p.style.color = "#4a90d9";
      p.style.fontWeight = "bold";
      document.getElementById("demoArea").appendChild(p);
      showProps();
    });

    document.getElementById("btnReset").addEventListener("click", function() {
      document.title = "The document Object";
      document.body.style.background = "";
      document.getElementById("demoArea").innerHTML = "<p>This is the demo area</p>";
      titleCount = 0;
      bgIndex = 0;
      createCount = 0;
      showProps();
    });
  </script>
</body>
</html>
▶ Try it Yourself

Example: Identifying Node Types

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Node Types</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    table { border-collapse: collapse; margin: 16px 0; width: 100%; max-width: 700px; }
    td, th { border: 1px solid #ddd; padding: 10px 14px; text-align: left; }
    th { background: #4a90d9; color: #fff; }
    .elem { background: #e3f2fd; }
    .text { background: #e8f5e9; }
    .note { background: #fff8e1; padding: 12px; border-radius: 6px; border-left: 4px solid #f0ad4e; margin: 16px 0; max-width: 700px; }
  </style>
</head>
<body>
  <h2>Node Types Explained</h2>
  <p id="demo">This is a paragraph <span>containing</span> multiple nodes</p>
  <div id="output"></div>
  <script>
    var demo = document.getElementById("demo");
    var results = [];

    function analyzeNode(node, depth) {
      var indent = "";
      for (var i = 0; i < depth; i++) indent += "│ ";
      var typeMap = { 1: "Element node", 3: "Text node" };
      var typeName = typeMap[node.nodeType] || "Other (" + node.nodeType + ")";
      var detail = "";

      if (node.nodeType === 1) {
        detail = "&lt;" + node.nodeName.toLowerCase() + "&gt;";
      } else if (node.nodeType === 3) {
        var text = node.textContent.trim();
        if (text) detail = '"' + text + '"';
        else return;
      }

      var cls = node.nodeType === 1 ? "elem" : "text";
      results.push(
        '<tr class="' + cls + '">' +
        "<td>" + indent + "</td>" +
        "<td><code>" + detail + "</code></td>" +
        "<td>" + typeName + "</td>" +
        "<td>" + node.nodeType + "</td>" +
        "</tr>"
      );

      var children = node.childNodes;
      for (var c = 0; c < children.length; c++) {
        analyzeNode(children[c], depth + 1);
      }
    }

    analyzeNode(demo, 0);

    document.getElementById("output").innerHTML = `
      <p>Analysis of <code>&lt;p id="demo"&gt;This is a paragraph &lt;span&gt;containing&lt;/span&gt; multiple nodes&lt;/p&gt;</code></p>
      <table>
        <tr><th>Level</th><th>Content</th><th>Node Type</th><th>nodeType</th></tr>
        ${results.join("")}
      </table>
      <div class="note">
        💡 Note: Line breaks and whitespace between tags are also text nodes! In practice, <code>children</code> (element nodes only) is more useful than
        <code>childNodes</code> (all nodes including text).
      </div>
    `;
  </script>
</body>
</html>
▶ Try it Yourself

❓ FAQ

Q Is the DOM part of JavaScript?
A No. The DOM is a standard defined by the W3C. JavaScript merely provides APIs to interact with it. Node.js has no DOM because it isn't a browser environment. Confusing DOM and JS is a common beginner misconception.
Q Why are there empty text nodes in childNodes?
A Line breaks and indentation in HTML are parsed as text nodes in the DOM. For example, the whitespace between two tags becomes a text node (containing a newline character). If you only want element nodes, use children instead of childNodes.
Q Does modifying the DOM affect page performance?
A Yes. Every DOM modification can trigger a browser reflow and repaint. Frequent DOM manipulation is a performance killer. Best practice: build all your changes in memory first, then write to the DOM in one go.

📝 Exercises

  1. Open the browser DevTools (F12), type console.dir(document) in the Console, and explore the document object's properties and methods. List 5 that you recognize or find interesting.
  2. Write code that gets the body element of the current page, prints its childElementCount (number of child elements), then uses children to loop through all child elements and print each one's tag name.
  3. Explain the difference between "element nodes" and "text nodes". Given <div>Hello <b>World</b></div>, draw its node tree structure and label the type of each node.
100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏