Level 3, Interactive Building, Chapter 10 of 24
The DOM — Making Pages Come Alive
Why this matters
So far, your HTML has been static: it loads once and stays exactly as written. But nearly every app you use daily, a chat app, a shopping cart, a to-do list, changes what's on screen constantly without reloading the page. Text appears, elements get added, colors change, all in response to what's happening. That's not a different technology, it's the same HTML and CSS you already know, being manipulated live by JavaScript.
The bridge that makes this possible is the DOM, the Document Object Model. The DOM is the browser's live, in-memory representation of your page as a tree of objects, and JavaScript can read from that tree and write to it at any time. Learning the DOM is the moment your pages stop being fixed documents and start being interactive programs.
The lesson
The DOM is a tree, not just text
When a browser loads an HTML file, it doesn't just display the text, it parses it into a tree of nodes, where each element, attribute, and piece of text becomes an object with a place in that tree. A div containing a paragraph becomes a parent node with a child node, mirroring the nesting you already write in HTML. JavaScript can access this tree through the global document object, which represents the entire page. Because the DOM is a live structure kept in memory, changing it immediately changes what the user sees, there's no separate step to 'save' or 're-render' anything the way you might expect from working with a plain text file.
1const heading = document.querySelector("h1");2console.log(heading.textContent);Selecting elements
document.querySelector(selector) returns the first element matching a CSS selector, or null if nothing matches. document.querySelectorAll(selector) returns every matching element as a NodeList, which behaves like an array for looping purposes, so you can use forEach on it directly. Because these methods accept the same selectors you already write in CSS, class selectors, id selectors, descendant combinators, and more, there's very little new syntax to learn here: the hard part isn't the JavaScript, it's knowing exactly which element you want, which is a skill you've already been building since Level 1.
1const items = document.querySelectorAll(".task");23items.forEach((item) => {4 console.log(item.textContent);5});Reading and changing content
Once you have a reference to an element, several properties let you read or change what it displays. textContent gets or sets the plain text inside an element, while innerHTML gets or sets its contents as raw HTML, including tags, which is powerful but should be used carefully since inserting untrusted text as HTML can create security problems. You can also read and write attributes directly, such as element.src or element.href, or use the more general element.setAttribute(name, value) and element.getAttribute(name) for any attribute at all, including custom ones.
1const status = document.querySelector("#status");2status.textContent = "Connected";3status.setAttribute("data-state", "online");Changing styles and classes
You can change an element's inline styles directly through its style property, such as element.style.color = "red", but the more maintainable approach, and the one that plays nicely with everything you learned about CSS, is to toggle classes instead. element.classList.add("name"), .remove("name"), and .toggle("name") let JavaScript switch an element between CSS states you've already defined in your stylesheet, keeping your visual rules in CSS where they belong and letting JavaScript simply decide when those rules apply. This separation, JavaScript deciding 'what' and CSS deciding 'how it looks', tends to produce far cleaner code than setting individual style properties from JavaScript everywhere.
- document.querySelector and document.querySelectorAll find elements using ordinary CSS selectors.
- textContent reads or writes plain text; innerHTML reads or writes raw HTML markup.
- setAttribute and getAttribute work with any HTML attribute, including custom data- attributes.
- classList.add/remove/toggle is usually a better tool for visual changes than setting style properties directly.
Creating and inserting new elements
Beyond changing existing elements, the DOM lets you build entirely new ones from scratch with document.createElement(tagName), which returns a new, empty element that exists in memory but isn't on the page yet. You set its content and attributes just like any other element, then attach it to the visible page with methods like parentElement.appendChild(newElement) or the more flexible parentElement.append(newElement). This pattern, create, configure, then insert, is exactly how dynamic lists, chat messages, and to-do items get added to a page without a full reload, and it's the foundation you'll build on heavily once you start responding to user events in the next chapter.
1const list = document.querySelector("#task-list");2const item = document.createElement("li");3item.textContent = "Buy groceries";4list.appendChild(item);Try it yourself
Select the heading and paragraph already in the page, change their text with JavaScript, then create a brand-new list item and append it to the list.
Chapter boss project
Boss project: A Dynamic Profile Card
Build a small profile card in HTML with a placeholder name, bio, and status indicator. Using JavaScript and the DOM, write code that updates the name and bio text, adds a CSS class that changes the status indicator's color, and appends a new list item to a 'skills' list on the card.
The visual states, like what an 'online' versus 'offline' status looks like, should be defined in your CSS as classes. Your JavaScript's job is only to decide which class applies and to add it with classList, not to set colors directly from JavaScript.
Aim to select each element only once and store it in a variable, rather than calling querySelector repeatedly for the same element throughout your script.
- Define .status.online and .status.offline classes in your CSS first, with different colors, before writing any JavaScript.
- Use classList.add to apply whichever status class matches the current state, and classList.remove for the other one.
- Build the new skill list item with document.createElement("li") and appendChild, just like the sandbox example.
- If something doesn't update, check the browser console for errors and confirm your selector actually matches an element.
Level-up checklist
Tick these off once each one is true for you.
