JavaScript DOM and Async Cheat Sheet
Selecting and changing elements, events and delegation, forms, storage, timers, promises, async/await and fetch.
Updated
Selecting elements#
document.querySelector("#title"); // first match or null
document.querySelectorAll(".card"); // NodeList (forEach, for...of)
[...document.querySelectorAll("li")].map((li) => li.textContent);
document.getElementById("title");
card.querySelector("h3"); // search inside an element
button.closest(".card"); // nearest matching ancestor
el.matches(".active"); // true or false
el.parentElement; el.children; el.nextElementSibling;Load scripts with defer or type="module" so elements exist when the code runs.
Changing elements#
el.textContent = "Safe text"; // use for user data
el.innerHTML = "<strong>Trusted</strong> markup only"; // never with user input (XSS)
el.classList.add("open"); el.classList.remove("open");
el.classList.toggle("open"); el.classList.contains("open");
el.style.width = `${percent}%`;
el.setAttribute("aria-expanded", "true");
el.hidden = true;
input.value; checkbox.checked; button.disabled = true;
el.dataset.productId; // data-product-idCreating and removing#
const li = document.createElement("li");
li.textContent = "New item";
list.append(li); // also: prepend, before, after, replaceWith
li.remove();
list.replaceChildren(); // remove all children
list.replaceChildren(...items); // replace with new nodes
const card = template.content.cloneNode(true); // from <template>Events#
button.addEventListener("click", (event) => {
event.target; // where the event started
event.currentTarget; // where the listener is
});
input.addEventListener("input", () => console.log(input.value));
document.addEventListener("keydown", (e) => { if (e.key === "Escape") close(); });
link.addEventListener("click", (e) => e.preventDefault());
el.addEventListener("scroll", onScroll, { passive: true });
el.addEventListener("click", once, { once: true });
el.removeEventListener("click", handler); // same function reference
// Delegation: one listener for many (and future) children
list.addEventListener("click", (e) => {
const button = e.target.closest(".delete");
if (button) button.closest("li").remove();
});Forms#
form.addEventListener("submit", (event) => {
event.preventDefault(); // no page reload
const data = Object.fromEntries(new FormData(form)); // values are strings
console.log(Number(data.qty));
form.reset();
});
field.setCustomValidity("Passwords do not match"); // "" when valid
form.checkValidity(); form.reportValidity();Storage#
localStorage.setItem("theme", "dark");
localStorage.getItem("theme"); // string or null
localStorage.setItem("cart", JSON.stringify(cart));
const saved = JSON.parse(localStorage.getItem("cart") ?? "[]");
localStorage.removeItem("theme");
sessionStorage.setItem("step", "2"); // lasts for the tabNever store secrets in storage: any script on the page can read it.
Timers and the event loop#
const id = setTimeout(() => console.log("later"), 500);
clearTimeout(id);
const tick = setInterval(update, 1000);
clearInterval(tick);Order: synchronous code → all microtasks (promises) → next task (timers, events).
Promises#
const wait = (ms, value) => new Promise((resolve) => setTimeout(() => resolve(value), ms));
wait(100, "done")
.then((v) => v.toUpperCase())
.catch((error) => console.error(error))
.finally(() => console.log("cleanup"));
Promise.all([p1, p2]); // all values; rejects on first failure
Promise.allSettled([p1, p2]); // every { status, value | reason }
Promise.race([p1, p2]); // first to settle
Promise.any([p1, p2]); // first to fulfilasync / await#
async function loadUser(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) throw new Error(`HTTP ${response.status}`); // fetch does not reject on 404/500
return await response.json();
} catch (error) {
console.error("Could not load user:", error.message);
return null;
} finally {
hideSpinner();
}
}
const [profile, orders] = await Promise.all([getProfile(), getOrders()]); // parallel
for (const id of ids) await process(id); // one by onefetch#
const res = await fetch("https://api.example.com/items?" + new URLSearchParams({ page: 2 }));
const items = await res.json();
await fetch("/api/items", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Pen" }),
signal: AbortSignal.timeout(5000),
});Use textContent (not innerHTML) for API data, keep API keys on the server, and remember that CORS is configured on the server.
Want the full explanations? Go to the Learn JavaScript course →