Finding elements
Every DOM change starts the same way: find the node, then change it. The finding half reuses a skill you already have — the selector language from unit 4 does double duty as JavaScript's query language.
document.querySelector(sel) returns the first element matching a CSS selector, the exact selectors you learned in lesson 4-1:
const title = document.querySelector("#site-title"); const firstCard = document.querySelector(".card"); const navLink = document.querySelector("nav a");
document.querySelectorAll(".card") returns all matches, which you can loop with for...of.
If nothing matches, querySelector returns null, and reading a property of null crashes with the single most common browser error: TypeError: Cannot read properties of null. When you see it, your selector missed. Check the spelling, and check that your script runs after parsing (defer, lesson 8-1).
Changing elements
Once you hold a node, change it:
title.textContent = "Sold out!"; // replace the text title.classList.add("highlight"); // add a class, CSS does the rest title.classList.remove("hidden"); title.classList.toggle("open"); // add if absent, remove if present title.style.color = "crimson"; // inline style, for one-offs img.setAttribute("src", "/new.jpg"); // any attribute
The pattern that keeps CSS in charge: define each visual state as a class (like .hidden { display: none; } from lesson 5-2), then have JavaScript only add and remove classes. element.style.x writes an inline style, and lesson 4-3 told you inline beats every stylesheet rule. That power is exactly why you should use it sparingly.
Quiz
Your script crashes with: Cannot read properties of null (reading 'textContent'). What is the most likely cause?
The JS pane runs inside the page, so document is available. Three tasks: 1) select the h1 with querySelector and change its textContent to Tickets sold out, 2) add the class sold-out to it with classList.add, 3) select the .status paragraph and set its textContent to Check back tomorrow.
Code exercise · javascript
How does querySelector decide whether a node matches? Build the core of it. Write matches(node, selector) for a toy node: "#x" matches the id, ".x" matches one of the classes, and a bare name matches the tag.