Skip to content
Laviyx Learn

Try

JavaScript DOM and Async Cheat Sheet

Selecting and changing elements, events and delegation, forms, storage, timers, promises, async/await and fetch.

Updated

Selecting elements#

JavaScript
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#

JavaScript
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-id

Creating and removing#

JavaScript
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#

JavaScript
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#

JavaScript
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#

JavaScript
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 tab

Never store secrets in storage: any script on the page can read it.

Timers and the event loop#

JavaScript
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#

JavaScript
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 fulfil

async / await#

JavaScript
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 one

fetch#

JavaScript
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 →