What is the DOM?
When the browser loads your HTML, it turns every tag into a live object you can reach from JavaScript. That tree of objects is the DOM (Document Object Model). Change a DOM object and the page updates instantly — no reload.
Select
Find the element(s) you want with querySelector.
Change
Edit text, HTML, styles, or classes on that element.
Listen
Run a function when the user clicks, types, or submits.
Respond
Update the page in response — that's interactivity.
Select elements
querySelector takes any CSS selector (yes, the ones you already know!) and returns the
first match. querySelectorAll returns all of them.
// By id, class, or any CSS selector const title = document.querySelector("#title"); const first = document.querySelector(".card"); // first .card const all = document.querySelectorAll(".card"); // every .card const byId = document.getElementById("title"); // classic, fast
Change what's on the page
Once you've selected an element, set its textContent, swap a class with
classList, or tweak its style. Click the buttons to change the box below.
const box = document.querySelector("#stage"); box.textContent = "You changed me! ✨"; // change the text box.classList.add("active"); // add a CSS class box.classList.toggle("active"); // on/off box.style.background = "#22c55e"; // inline style
<div class="stage-box" id="stage">I'm a normal element.</div>
.stage-box {
margin-top: 14px; padding: 22px; border-radius: 10px;
background: #16161c; border: 1px solid rgba(255,255,255,.1);
text-align: center; font-size: 1.1rem; font-weight: 600;
color: #e2e8f0; transition: all .2s;
}classList over style. Keep the look in
your CSS and just toggle a class from JS — cleaner and easier to maintain.Listen for events
addEventListener runs a function when something happens. The big ones:
click, input (typing), submit (forms), and
keydown. Type below and watch input fire on every keystroke.
const field = document.querySelector("#nameField"); const mirror = document.querySelector("#mirror"); // Runs on every keystroke field.addEventListener("input", (event) => { const value = event.target.value; // what's typed mirror.textContent = value ? `Hello, ${value}! 👋` : "Hello there! 👋"; });
<input class="field" id="nameField" type="text" placeholder="Type your name…"> <div class="mirror" id="mirror">Hello there! 👋</div>
.field {
width: 100%; max-width: 340px; padding: 10px 12px;
border-radius: 8px; background: #0d0d12;
border: 1px solid rgba(255,255,255,.14); color: #f5f5f7; font: inherit;
}
.mirror { margin-top: 12px; font-size: 1.1rem; color: #86efac; min-height: 1.5em; }Put it together: a like button
Select, listen, and change — the full loop. Click the heart: a variable updates, a class toggles, and the count re-renders. This is exactly how real UI works.
let likes = 0; let liked = false; const btn = document.querySelector("#likeBtn"); const count = document.querySelector("#likeCount"); btn.addEventListener("click", () => { liked = !liked; // flip true/false likes += liked ? 1 : -1; btn.textContent = liked ? "❤️" : "🤍"; count.textContent = likes; });
<div class="d-row"> <button class="btn ghost" id="likeBtn">🤍</button> <span class="count-big" id="likeCount">0</span> <span>likes</span> </div>
.d-row { display: flex; align-items: center; gap: 14px; }
.btn { padding: 10px 18px; border-radius: 8px; border: none; cursor: pointer;
font: inherit; font-weight: 700;
background: linear-gradient(135deg,#22c55e,#14b8a6); color: #06281b; }
.btn.ghost { background: transparent; border: 1px solid #22c55e; color: #86efac; font-size: 1.3rem; }
.count-big { font-size: 2rem; font-weight: 800; color: #86efac; min-width: 56px; text-align: center; }