7.1 — The DOM tree
Six phases of JavaScript — and not one pixel changed on a page. That ends now. The bridge between your code and what the human sees is the DOM — the Document Object Model: when the browser reads an HTML file, it doesn't keep it as text. It parses it into a living tree of objects — one node per tag, per piece of text — and hands your JavaScript the root: document.
Everything a page ever does — a menu opening, a like counter ticking, a todo appearing — is JavaScript editing this tree. And everything Playwright ever automates is this tree being found, clicked, and asserted on. This phase is literally titled your hunting ground; today you learn the terrain.
<!-- the HTML the server sent (just text!) -->
<body>
<h1>My List</h1>
<ul id="items">
<li class="todo">buy milk</li>
<li class="todo done">call mom</li>
</ul>
</body>
// in JS: the tree grown from that text
document.querySelector("#items")
// → the <ul> ELEMENT OBJECT, liveThe server sends TEXT — angle brackets, just characters (4.13 taught you: wires carry text). The browser’s parser reads it once and GROWS the tree. The text is scaffolding; the tree is the building.
The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”
The DOM is not part of JavaScript — it's a browser API handed to JS (the spec calls the world of document, fetch and friends "Web APIs" — the same environment side of the 6.2 machine). That's why Node.js (Phase 9) has no document: no page, no tree. One language, different toolbelts per environment.
Every node object comes packed with navigation (parentElement, children, nextElementSibling) and data (tagName, id, classList, textContent).
Under the hood they're prototype chains (5.5 in the wild): an li is an HTMLLIElement → HTMLElement → Element → Node — shared methods living once, high on the chain.
And your exercise models the tree as plain { tag, children } objects on purpose: tree-walking logic is identical either way, and serialized node trees are exactly what Playwright passes around when it snapshots a page. Learn the walk on paper; drive it on the real tree from 7.3 on.
⌨️ walk a tree like the browser does
The sandbox has no page — so model a DOM as plain nested objects and walk it RECURSIVELY (3.9, welcome back): the exact shape of every DOM traversal you’ll ever write.
requirements:
- Model this page as nested objects, each node shaped
{ tag, children: [] }: abodycontaining anh1(no children) and aulcontaining twolinodes. - Write
countNodes(node): 1 for the node itself plus the counts of all its children — computed recursively, no manual adding. - Print
countNodes(body), then print the tag of the ul's SECOND child.
when you press RUN, the console must show exactly:
✏️ Quick check 1
The browser parses HTML text into a tree of ___. Type the word.
✏️ Quick check 2
querySelector returns the HTML text of the element, or a live reference to the element object? Type: text or reference.
✏️ Quick check 3
In <li>buy milk</li> — the words "buy milk" live in the tree as a ___ node, child of the li. Type the kind.
🗣️ Now teach it back
Explain to a friend what the DOM actually is — what the browser does with HTML text, what document gives you, what querySelector hands back, and why the DevTools Elements panel isn’t the same as “View Source.”
Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.