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
documentis the root node of the DOM tree and the entry point for JS to access the DOMhtmlis the sole child element ofdocument(the document element)headandbodyare the two child elements ofhtml- From there, nesting continues layer by layer to form the complete tree
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) |
<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:
- Access page elements:
document.getElementById(),document.querySelector() - Create new elements:
document.createElement() - Read and write page content:
document.title,document.body - Listen for page events:
document.addEventListener()
What the DOM Does
JS itself cannot "see" a web page — it can only compute. The DOM provides the "eyes" and "hands":
- Read: Get text, attributes, and styles from the page
- Modify: Change text content, attribute values, and CSS styles
- Add: Create new elements and insert them into the page
- Remove: Remove elements from the page
- Listen: Respond to user clicks, input, and other interactions
Without the DOM, JS and HTML would be two completely separate things. The DOM connects them.
Example: Viewing the DOM Structure
<!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"><' + 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 += '></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"></' +
node.nodeName.toLowerCase() + '></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>
Example: Exploring the document Object
<!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>
Example: Identifying Node Types
<!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 = "<" + node.nodeName.toLowerCase() + ">";
} 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><p id="demo">This is a paragraph <span>containing</span> multiple nodes</p></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>
❓ FAQ
children instead of childNodes.📝 Exercises
- 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. - Write code that gets the
bodyelement of the current page, prints itschildElementCount(number of child elements), then useschildrento loop through all child elements and print each one's tag name. - 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.



