Selecting and Manipulating the DOM
Finding elements with querySelector and changing what's on the page.
2 min read
Working with the DOM comes down to two steps: find the element you want, then change something about it. This lesson covers both.
Selecting elements
document.getElementById("app"); // one element, by id
document.querySelector(".card"); // first match, any CSS selector
document.querySelectorAll(".card"); // all matches, as a NodeListquerySelector and querySelectorAll accept the same selector syntax you'd write in CSS (#id, .class, div > p, [data-active]), which makes them the most flexible and generally the preferred way to select elements. querySelectorAll returns a static NodeList, not a live one — it doesn't automatically update if the DOM changes after you call it.
const cards = document.querySelectorAll(".card");
cards.forEach(card => console.log(card)); // NodeList supports forEach directlyReading and changing content
const heading = document.querySelector("h1");
heading.textContent; // reads plain text, ignoring any HTML tags
heading.textContent = "New title"; // sets plain text safely
heading.innerHTML; // reads content including HTML markup
heading.innerHTML = "<em>New</em>"; // parses the string as HTMLPrefer textContent over innerHTML when you're inserting plain text, especially text that came from user input — innerHTML parses its argument as markup, which opens the door to XSS attacks if that string contains untrusted <script> content.
Changing attributes and styles
const link = document.querySelector("a");
link.getAttribute("href");
link.setAttribute("href", "/new-page");
link.classList.add("active");
link.classList.remove("hidden");
link.classList.toggle("expanded");
link.style.color = "red"; // inline style, for one-off changesPrefer toggling a CSS class over setting style properties directly — it keeps styling rules in your CSS file rather than scattering them through JavaScript.
Creating and inserting new elements
const newItem = document.createElement("li");
newItem.textContent = "New item";
const list = document.querySelector("ul");
list.appendChild(newItem); // add to the end
list.prepend(newItem); // add to the start
newItem.remove(); // remove it entirelyPutting it together
const list = document.querySelector("#todo-list");
["Buy milk", "Write code", "Walk the dog"].forEach(text => {
const item = document.createElement("li");
item.textContent = text;
list.appendChild(item);
});That loop reads naturally: for each string, create an <li>, set its text, and append it — the same pattern (create, configure, insert) behind most direct DOM manipulation.
Selecting and changing elements is only half the picture — the next lesson covers making the page respond to what the user actually does.