Events are how pages come alive — every click, keypress and form submit fires one. Master the listener pattern plus delegation and you can wire up any interface.
Attach with el.addEventListener("click", handler). The handler receives an event object: e.target is what was clicked, e.preventDefault() stops default behavior (like form submission reloading the page).
const btn = document.querySelector("#save");
btn.addEventListener("click", () => {
console.log("saved!");
});
function onHover() { this.classList.add("hot"); }
btn.addEventListener("mouseenter", onHover);
btn.removeEventListener("mouseenter", onHover); // same reference!document.addEventListener("click", (e) => {
console.log(e.target); // the exact element clicked
console.log(e.clientX, e.clientY); // mouse position
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") closeModal();
if (e.ctrlKey && e.key === "s") {
e.preventDefault(); // stop browser save dialog
saveDraft();
}
});const form = document.querySelector("#signup");
form.addEventListener("submit", (e) => {
e.preventDefault(); // stop the page reload!
const data = new FormData(form);
console.log(data.get("email"));
});
const input = document.querySelector("#name");
input.addEventListener("input", (e) => {
preview.textContent = e.target.value; // live as they type
});Instead of a listener per item (which breaks for items added later), listen on the parent and check what was clicked. Essential for dynamic lists.
const list = document.querySelector("#todos");
list.addEventListener("click", (e) => {
const del = e.target.closest(".delete-btn");
if (del) del.closest("li").remove(); // works for items
}); // added ANY time
// closest() climbs up from the click target to find a matchaddEventListener("click", handle()) runs it now — pass handle without parenthesese.target is the innermost element actually clicked; e.currentTarget is the element the listener is attached to. In delegation you filter e.target.
It cancels the browser's built-in reaction — form submission reload, link navigation, checkbox toggle — leaving your JS in control.
Events travel up from the clicked element through its ancestors — that's why a parent can catch children's clicks, which is what makes delegation possible.
Put your script at the end of body, or use the defer attribute, or listen for DOMContentLoaded.