Select elements on the page, react to clicks, and adopt event delegation for performant code.
Open this lesson in KodokonThe DOM is the living representation of your HTML page: manipulating it is how JavaScript makes an interface interactive. The essential duo: select an element, then listen to what happens to it. Let's start with a small initial structure.
<button id="save-btn" class="btn">Save</button>
<ul class="task-list">
<li>Buy groceries</li>
<li>Call the client</li>
</ul>querySelector accepts any CSS selector (#id, .class, ul li, [data-id]) and returns the first matching element, or null. querySelectorAll returns all matching elements in a NodeList, which you can iterate over with forEach.
const button = document.querySelector("#save-btn");
const firstTask = document.querySelector(".task-list li");
const tasks = document.querySelectorAll(".task-list li");
console.log(tasks.length); // 2
console.log(firstTask.textContent); // "Buy groceries"To react to a user action, addEventListener attaches a function to an event type: click, input, submit, keydown... The function receives an event object describing what happened. You can then change content with textContent and styling with classList.
const button = document.querySelector("#save-btn");
button.addEventListener("click", () => {
button.textContent = "Saved!";
button.classList.add("success");
});A good professional habit: a list of 200 items does not deserve 200 listeners. Attach a single listener to the parent and identify the clicked element with event.target. This is event delegation: it even works for elements added later on.
const list = document.querySelector(".task-list");
list.addEventListener("click", (event) => {
const item = event.target.closest("li");
if (item) {
item.classList.toggle("done");
}
});document.querySelector(".btn") return if several elements have the btn class?addEventListener?event.target represent?