JavaScript DOM
Selecting Elements
querySelector and querySelectorAll
// Single element
const header = document.querySelector("h1");
const nav = document.querySelector("#main-nav");
const active = document.querySelector(".active");
const link = document.querySelector('a[href="/about"]');
// Multiple elements — returns NodeList
const items = document.querySelectorAll(".item");
items.forEach(item => console.log(item.textContent));
// Convert NodeList to Array for full array methods
const arr = [...document.querySelectorAll("li")];
const filtered = arr.filter(li => li.classList.contains("active"));
querySelector returns the first match or null. querySelectorAll returns a static NodeList.
Modifying Elements
Content, attributes, styles
const el = document.querySelector("#status");
// Content
el.textContent = "Online"; // text only (safe from XSS)
el.innerHTML = "<strong>OK</strong>"; // parses HTML (XSS risk with user input)
// Attributes
el.setAttribute("data-host", "sw01");
el.getAttribute("data-host"); // "sw01"
el.dataset.host; // "sw01" (data-* shorthand)
el.removeAttribute("data-host");
// Classes
el.classList.add("active", "highlight");
el.classList.remove("inactive");
el.classList.toggle("visible");
el.classList.contains("active"); // true
// Styles
el.style.color = "green";
el.style.display = "none";
Prefer textContent over innerHTML when inserting user-provided text — innerHTML creates XSS vulnerabilities.
Creating Elements
Build DOM nodes programmatically
const li = document.createElement("li");
li.textContent = "New item";
li.classList.add("item");
// Append to parent
document.querySelector("ul").appendChild(li);
// Insert at specific position
const list = document.querySelector("ul");
list.insertBefore(li, list.firstChild); // prepend
// Modern: append, prepend, before, after
list.prepend(li);
list.append(li);
el.before(newEl);
el.after(newEl);
// Remove
li.remove();
Event Handling
addEventListener — the modern approach
const button = document.querySelector("#submit");
button.addEventListener("click", (event) => {
event.preventDefault(); // stop default behavior
console.log("clicked:", event.target);
});
// Event delegation — handle events on parent
document.querySelector("ul").addEventListener("click", (e) => {
if (e.target.matches("li")) {
console.log("Clicked:", e.target.textContent);
}
});
// Remove listener
const handler = () => console.log("clicked");
button.addEventListener("click", handler);
button.removeEventListener("click", handler);
// Once — auto-remove after first call
button.addEventListener("click", handler, { once: true });
Event delegation attaches one listener to a parent instead of one per child. This handles dynamically added elements and uses less memory.
Common Events
Events you will use most
// Page lifecycle
window.addEventListener("DOMContentLoaded", init); // DOM ready
window.addEventListener("load", onLoad); // everything loaded
// Form
form.addEventListener("submit", handleSubmit);
input.addEventListener("input", onInput); // every keystroke
input.addEventListener("change", onChange); // on blur
// Keyboard
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") closeModal();
if (e.ctrlKey && e.key === "s") { e.preventDefault(); save(); }
});