Learning Goals
3 minBy the end of this lesson you will be able to:
- Explain what the DOM is, in one sentence.
- Inspect the live tree in the DevTools Elements panel.
- Read a page's heading text from the console with
document. - Say why a
<script>at the top of a page finds nothing.
Warm-Up · Where Did the Page Go?
5 minSection A ended with debugging. Everything you wrote printed to the console — the page itself never changed. Look at this:
const dishes = ['nasi lemak', 'roti canai'];
for (const dish of dishes) {
console.log(dish);
}Predict together
- Where do those two dishes appear?
- Would a customer visiting the site ever see them?
Reveal
They appear in the console — a panel only developers open. A real visitor sees a blank page. Everything you built in Section A is invisible to them.
Today that changes. To put those dishes on the page, you first need a way to reach the page from JavaScript. That way is the DOM.
New Concept · The Page as a Tree
12 minThink of a family tree. One ancestor at the top, children beneath, their children beneath them. Everyone has exactly one parent, and anyone can be found by tracing down from the top.
When the browser loads your HTML, it does not keep the text. It builds a tree of objects, one per tag. That tree is the DOM — the Document Object Model.
From tags to tree
<body>
<h1>Warung Aisyah</h1>
<ul>
<li>nasi lemak</li>
<li>roti canai</li>
</ul>
</body>The browser turns that into this shape:
Each box is an element — and each one is an object, exactly like the objects from Lesson 11. It has keys you can read and change.
document — your way in
The browser hands you one variable for free: document. It is the whole tree.
console.log(document.title);
console.log(document.body);Warung Aisyah
<body>…</body>Remember Lesson 1's Warm-Up? document is why that line only worked in a browser. Node has no page, so it has no document.
The HTML is not the DOM
Your HTML file
Text on disk. Written once.
Never changes while the page is open.
Seen in View Source.
The DOM
Live objects in memory.
Changes the instant your code changes it.
Seen in Elements.
This catches people out constantly. Add a list item with JavaScript and View Source still shows the original file — but the Elements panel shows your new item. Elements is the truth about what is on screen.
Order matters
The browser reads your file top to bottom. A script in the <head> runs before the body exists, so it finds nothing:
<head>
<script src="app.js"></script> <!-- too early: no h1 yet -->
</head>
<body>
<h1>Warung Aisyah</h1>
</body>That is why Lesson 1 put the <script> last in the <body>. By then the whole tree is built.
Why it matters
Every interactive page changes its DOM. React's whole purpose is to update it for you — but it is still the DOM underneath, and when something looks wrong on screen, the Elements panel is where you look.
Worked Example · Explore a Live Tree
12 minDo this in your own browser. Save the file below as warung.html and open it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Warung Aisyah</title>
</head>
<body>
<h1 id="stall-name">Warung Aisyah</h1>
<p class="tagline">Open 8am to 10pm</p>
<ul id="menu">
<li>nasi lemak</li>
<li>roti canai</li>
</ul>
<script src="app.js"></script>
</body>
</html>Step 1 — Look at the tree
Press F12 and open Elements. Click the small triangles to fold and unfold. Notice the shape matches the diagram above: body holds h1, p and ul; ul holds two li.
Hover over any line. The matching part of the page highlights. That is the tree and the screen being the same thing.
Step 2 — Reach the tree from the console
Switch to Console and type:
document.title'Warung Aisyah'Now ask for the whole body:
document.body.children.length4Four: the h1, the p, the ul — and the <script> tag, which is an element too.
Step 3 — Read one element
document.body.children[0] is the first child. Square brackets and index-from-zero, exactly like the arrays in Lesson 9:
const first = document.body.children[0];
console.log(first.tagName);
console.log(first.textContent);H1
Warung Aisyah.textContent is the words inside an element — a key on the object, read with a dot.
Step 4 — Change it and watch Elements
Keep the Elements panel visible, then in the console run:
document.body.children[0].textContent = 'Warung Aisyah — Buka!';The heading changes on screen and in the Elements panel, instantly.
Step 5 — Prove the file is untouched
Now right-click the page and choose View Page Source:
<h1 id="stall-name">Warung Aisyah</h1>What changed? The source still shows the original — because your change went into the DOM, not the file. Refresh the page and your change vanishes. The DOM is rebuilt from the file every time, and everything JavaScript did is forgotten.
Try It Yourself
13 minWork on warung.html. Keep Elements open throughout.
Task 1 — Map your own page
Add a
<footer>with a paragraph inside, and a second<ul>for drinks. Refresh, then draw the tree on paper — every element, and which is whose child.Check your drawing against the Elements panel.
Task 2 — Walk the tree in the console
Without using any new methods, reach the second list item and print its text. Start from
document.body.childrenand use square brackets to step down.Then print how many children your drinks list has.
Task 3 — Break it on purpose
Move the
<script>tag into the<head>. Inapp.js, put a line that readsdocument.body.children.lengthand logs it.Refresh and read the error carefully — name its type as you practised in Lesson 12. Then move the script back and confirm it works.
🔥 Mini-Challenge · The Script That Runs Too Soon
8 minIman's page shows an error and no greeting. Find two mistakes.
<!-- iman-cafe.html — buggy -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Kafe Iman</title>
<script src="app.js"></script>
</head>
<body>
<h1>Kafe Iman</h1>
<p>Best kopi-O in Ipoh</p>
</body>
</html>// app.js — buggy
const heading = document.body.children[0];
console.log('Heading says: ' + heading.textContent);
console.log('Page title: ' + document.Title);It works if: the console prints Heading says: Kafe Iman and Page title: Kafe Iman, with no red errors.
Reveal the answer
Mistake 1 — the script runs before the body exists.
In the <head>, app.js runs while document.body is still null. Reading .children from null throws the same TypeError shape you met in Lesson 11:
TypeError: Cannot read properties of null (reading 'children')Note it says null, not undefined — the browser deliberately says “no body yet”. Move the <script> to just before </body>.
Mistake 2 — a capital letter in a key name.
It is document.title, not document.Title. Key names are case-sensitive, and a missing key gives undefined rather than an error — so this one is silent:
Page title: undefined<!-- iman-cafe.html — fixed -->
<body>
<h1>Kafe Iman</h1>
<p>Best kopi-O in Ipoh</p>
<script src="app.js"></script>
</body>// app.js — fixed
const heading = document.body.children[0];
console.log(`Heading says: ${heading.textContent}`);
console.log(`Page title: ${document.title}`);Heading says: Kafe Iman
Page title: Kafe ImanOne bug shouted, one was silent. That pairing should feel familiar by now — it is exactly the lesson from Section A.
Recap
3 min- The DOM is the live tree of objects the browser builds from your HTML.
- Every tag becomes an element — an object with keys you can read and change.
documentis your way in; it only exists in a browser.- Nesting in HTML becomes parent and child in the tree.
- View Source shows the file; Elements shows the live DOM. They differ once JavaScript runs.
- DOM changes are forgotten on refresh — the tree is rebuilt from the file.
- A script in the
<head>runs before the body exists. Put it last in the<body>.
New words
- DOM — Document Object Model, the page as live objects.
- Element — one node in that tree, made from one tag.
- Parent / child — an element and the ones nested inside it.
- textContent — the words inside an element.
📦 Homework
4 min to brief · ~20 min to doRequired
- Build
myshop.htmlwith a heading, two paragraphs and a list of at least four items. Draw its DOM tree on paper. - In the console, change the heading text and one list item. Screenshot the Elements panel showing your changes, then refresh and note what happened. Bring both to next lesson.
Optional stretch
- Try
document.body.parentElementin the console. What is abovebodyin the tree? - Look up the
deferattribute on<script>. In one sentence, how does it solve the head-versus-body problem?