JavaScript DOM & Browser

The DOM & the Browser

The one thing Python doesn't need: JavaScript is the only language browsers run natively, and the DOM is the API for turning a static page into an app.

Browser APIs ✓ Practical 4 Topics
01

Selecting Elements

The DOM (Document Object Model) is the browser's live, in-memory tree representation of the HTML page. JavaScript reads and rewrites that tree, and the screen updates instantly.

JavaScript — Query Selectors
// modern, CSS-selector based — use these by default
const title = document.querySelector("h1.title");       // first match
const cards = document.querySelectorAll(".card");       // NodeList of all matches

// older, still common in legacy code
document.getElementById("main");
document.getElementsByClassName("card");   // live HTMLCollection

// NodeList isn't an array, but it's iterable
cards.forEach(card => card.classList.add("seen"));
[...cards].map(c => c.textContent);         // spread to get real array methods
querySelectorAll returns a static snapshot — elements added to the DOM afterward won't appear in it. getElementsByClassName returns a live collection that does update.
02

Manipulating the DOM

JavaScript — Create, Update, Remove
const el = document.createElement("div");
el.textContent = "Hello";              // safe — treats it as plain text
el.classList.add("card", "active");
el.dataset.id = "42";                  // sets data-id="42"

document.body.appendChild(el);      // add to the page
el.remove();                          // take it back out

// style & attributes
el.style.color = "cyan";
el.setAttribute("aria-label", "card");
Use .textContent for plain text, never .innerHTML with untrusted input — innerHTML parses and executes markup, which is exactly how XSS happens.
03

Events & Delegation

Events bubble up from the element they fired on through every ancestor. Delegation exploits that: attach one listener to a parent instead of one per child, including children added later.

JavaScript — Listeners & Delegation
button.addEventListener("click", (e) => {
  e.preventDefault();      // stop default behavior (e.g. form submit)
  console.log("clicked", e.target);
});

// Delegation — one listener handles every .item, even ones added later
document.querySelector("#list").addEventListener("click", (e) => {
  if (e.target.matches(".item")) {
    console.log("item clicked:", e.target.textContent);
  }
});

// remove a listener — needs the same function reference
function onClick() { /* ... */ }
button.addEventListener("click", onClick);
button.removeEventListener("click", onClick);
04

The fetch API

fetch() is the browser's built-in HTTP client, no import needed. It returns a Promise that resolves to a Response object — parsing the body is a second, separate step.

JavaScript — GET & POST
async function loadUser(id) {
  const res = await fetch(`/api/users/${id}`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();          // also a Promise — parses the body
}

async function createUser(data) {
  const res = await fetch("/api/users", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data)
  });
  return res.json();
}
fetch only rejects on network failure — a 404 or 500 response still resolves successfully. Always check res.ok before trusting the body.

Quick Quiz

1. Which returns a live collection that updates automatically?
2. Setting untrusted input via innerHTML risks…
3. Event delegation attaches a listener to…
4. fetch() rejects (throws) when…
5. e.preventDefault() on a form submit event…