The DOM is your HTML page as a live JavaScript object tree. Learn to select, change and create nodes and you can build anything — this is what frameworks automate, and what interviews test.
Select with document.querySelector("css selector") (first match) or querySelectorAll (all). Change text with el.textContent, classes with el.classList.add/remove/toggle, and build new elements with document.createElement + append.
const title = document.querySelector("h1"); // first h1
const btn = document.querySelector("#saveBtn"); // by id
const cards = document.querySelectorAll(".card"); // all matches
cards.forEach(card => card.classList.add("ready"));
// querySelector returns null if nothing matches — check it:
if (btn) btn.disabled = false;const box = document.querySelector("#msg");
box.textContent = "Saved ✓"; // treats input as TEXT — safe
// innerHTML parses as HTML — never feed it user input:
box.innerHTML = "<strong>Done</strong>"; // ok: your own HTML
// box.innerHTML = userInput; // ✗ XSS vulnerability!const card = document.querySelector(".card");
card.classList.add("active");
card.classList.remove("hidden");
card.classList.toggle("open"); // on/off each call
card.classList.contains("active"); // true
// prefer classes over inline styles, but when needed:
card.style.setProperty("--accent", "#2de8c0");
card.style.transform = "translateY(-4px)";const list = document.querySelector("#todo");
const item = document.createElement("li");
item.textContent = "Learn the DOM";
item.classList.add("todo-item");
list.append(item); // add at end
list.prepend(item.cloneNode(true)); // copy at start
item.remove(); // gone
// build many? use a fragment — one repaint instead of N:
const frag = document.createDocumentFragment();
for (const t of ["a", "b", "c"]) {
const li = document.createElement("li");
li.textContent = t;
frag.append(li);
}
list.append(frag);const link = document.querySelector("a.download");
link.setAttribute("href", "/files/guide.pdf");
link.getAttribute("href");
// custom data lives in data-* attributes:
// <div id="user" data-user-id="42" data-role="admin">
const el = document.querySelector("#user");
console.log(el.dataset.userId); // "42" (camelCased!)
console.log(el.dataset.role); // "admin"The Document Object Model — the browser's live object representation of your HTML, which JavaScript can read and modify; changes appear on screen instantly.
querySelector covers every case with CSS selector syntax and is the modern standard. getElementById is marginally faster but only does one thing.
textContent sets plain text (safe, fast); innerHTML parses the string as HTML (needed for markup, dangerous with user input).
Either the selector has a typo, or the script ran before that element was parsed — move the script below the element or add the defer attribute.