After this lesson, you will be able to: Make a webpage interactive by selecting elements, listening for events, and updating the page in real time using the DOM.
The DOM (Document Object Model) is the bridge between your JavaScript code and your HTML page. This lesson covers selecting elements, reading and changing them, and listening for user events like clicks and form submissions, the foundations of every interactive webpage.
When the browser loads your HTML, it builds a tree of objects, one for each element. That tree is the DOM. Your JavaScript can read and change any node in the tree, and the page updates instantly. The DOM is what makes JavaScript powerful in the browser.
Diagram coming soon!
Tree diagram of the DOM: html at the top, branching to head and body, body branching to header, main, footer, each with their own children
querySelector accepts any CSS selector. It's the only selector function you really need.
// Single element (first match)const title = document.querySelector("h1");const btn = document.querySelector("#submit-btn");const card = document.querySelector(".card");// Multiple elements (NodeList)const allButtons = document.querySelectorAll("button");allButtons.forEach((b) => console.log(b.textContent));
Once selected, you can read and write properties.
const heading = document.querySelector("h1");// Readconsole.log(heading.textContent); // text insideconsole.log(heading.classList); // list of classes// Writeheading.textContent = "New title";heading.style.color = "#FF4848";heading.classList.add("highlighted");heading.classList.toggle("hidden");
addEventListener attaches a function that runs when the event happens.
const btn = document.querySelector("#greet-btn");const out = document.querySelector("#output");btn.addEventListener("click", () => {out.textContent = "Hello, world!";});// Form submitconst form = document.querySelector("form");form.addEventListener("submit", (event) => {event.preventDefault(); // stop the page from reloadingconst value = form.querySelector("input[name='email']").value;console.log("Submitted:", value);});
Create a tiny app that counts button clicks.
Create a button with id="counter" and text "Clicks: 0"
In JS, select the button and create a let count = 0
Add a click event listener that increments count and updates btn.textContent
Reload the page and click around to verify
Bonus: add a reset button that sets count back to 0
Buttons and forms are half the DOM story. The other half is loading data from a server and putting it on the page. The browser's `fetch` API plus `async`/`await` is the standard pattern. You'll dive into the API side properly in the next lesson; here you'll see how a fetch call wires up to a click handler so the page actually updates.
When the user clicks the button, fetch a user from a public test API and render their name into a paragraph. Notice the try/catch for network errors and the response.ok check for HTTP errors.
<button id="load-btn">Load user</button><p id="out"></p><script>const btn = document.querySelector("#load-btn");const out = document.querySelector("#out");btn.addEventListener("click", async () => {out.textContent = "Loading...";try {const response = await fetch("https://jsonplaceholder.typicode.com/users/1");if (!response.ok) throw new Error(`HTTP ${response.status}`);const user = await response.json();// Use textContent (not innerHTML) when inserting untrusted dataout.textContent = `${user.name} — ${user.email}`;} catch (error) {out.textContent = `Failed to load: ${error.message}`;}});</script>
Hint: think about what the browser does by default when a form is submitted.
Sign in and purchase access to unlock this lesson.