The DOM

Your HTML file loads once, and then the page sits there. But a search box that suggests results as you type, a menu that opens on click, a counter that ticks up, none of that is in the HTML file. Something changes what is on the page after it has loaded, and that something is JavaScript reaching into the page through the DOM. This chapter is about that reach: how JavaScript finds the parts of a page and changes them so the page updates in front of the reader.
What the DOM is
When the browser loads your page, it reads your HTML and builds a tree of objects out of it: one object for the page, one for the <body>, one for each heading, paragraph, and button inside. That tree is the DOM, short for Document Object Model. Your JavaScript can read this tree and change it, and when it does, the page you see updates straight away.
The part worth holding onto: the DOM is not your HTML file. It is the live version of the page, sitting in the browser's memory. Your .html file is the starting recipe; the DOM is the finished dish the browser is serving, and JavaScript can rearrange the plate while everyone is still eating.
Every element in the DOM is an object, the same kind you met in objects, with properties you can read and change. That is the whole trick: because the page is objects, and you already know how to work with objects, changing the page is changing object properties.
Selecting elements
Before you can change an element, you have to find it in the tree. You point at it the same way CSS does, with a selector, and the browser hands you back the matching object.
The workhorse is document.querySelector. You give it a CSS selector, the same kind of pattern you use in CSS, and it returns the first element that matches:
const card = document.querySelector(".card"); // first element with class="card"
const total = document.querySelector("#total"); // the element with id="total".card matches by class, #total matches by id, and a plain word like "button" matches by tag name. querySelector gives you the first match and stops there. When you want every match instead, use querySelectorAll, which returns a list you can loop over:
const cards = document.querySelectorAll(".card"); // all elements with class="card"
console.log(cards.length); // how many it foundIf nothing matches, querySelector returns null, which is JavaScript's way of saying "there is nothing here".
document.querySelector a CSS selector like .card or #total, and it gives you the first match. Use querySelectorAll when you want all of them as a list. If nothing matches you get null, which means "nothing here". Reading and changing elements
Once you hold an element, you read and change it through its properties, the same way you read and change any object. This is where the page actually starts moving.
The property you will use most is textContent, the text inside an element. You can read it or set it:
const total = document.querySelector("#total");
total.textContent = "42 items"; // the page now shows "42 items"To change how something looks, you usually add or remove a class and let CSS do the styling. classList has three methods for that:
const card = document.querySelector(".card");
card.classList.add("selected"); // add a class
card.classList.remove("selected"); // take it away
card.classList.toggle("selected"); // add if missing, remove if presentYou can also set a single style directly through .style, and set an attribute like src or href with setAttribute:
card.style.color = "crimson"; // one inline style
const avatar = document.querySelector(".avatar");
avatar.setAttribute("src", "priya.jpg"); // set the image sourceReach for classList first and .style only for one-off tweaks, because keeping your styling in CSS keeps it in one place.
textContent, and change its look by adding or removing a class with classList.add, remove, and toggle. Use .style for a one-off tweak and setAttribute for things like an image source. Lean on classes so your styling stays in your CSS. Creating and removing elements
Changing elements that already exist gets you far, but sometimes there is nothing there yet: a to-do you are adding, a search result arriving. For that you build new elements and put them into the tree, and take old ones out.
You make a new element with document.createElement, give it some content, then add it to the page with append:
const list = document.querySelector(".todo-list");
const item = document.createElement("li"); // a new <li>, not on the page yet
item.textContent = "Buy oat milk"; // give it some text
list.append(item); // now it shows up, at the end of the listA new element from createElement exists only in memory until you append it somewhere; that is the step that puts it on the page. To take an element off the page, call remove on it:
item.remove(); // gone from the pagedocument.createElement, give it text with textContent, and put it on the page with append. A fresh element lives only in memory until you append it, so that step is what makes it show up. To take one off the page, call remove on it. Where the DOM goes from here
Selecting, reading, changing, creating, and removing cover most of what JavaScript does to a page, and all of it is the same move underneath: find an object in the tree and change its properties. Because the DOM is objects, everything you learned in objects applies directly here, and the small set of methods in this chapter (querySelector, textContent, classList, createElement, append) is most of the toolkit.
What is missing so far is timing. Every example here runs once, top to bottom, but a real page changes in response to what the reader does: a click, a keystroke, a submitted form. Wiring your DOM changes to those moments is events, the next chapter, where addEventListener connects "the user did this" to "so the page does that". Once selecting and changing sit alongside responding to events, you can build the interactive pages the rest of this handbook is aimed at.

