← thecodex.expert · The Codex Family of Knowledge
The Codex / JavaScript / DOM & Events

DOM & Events

Making web pages interactive — selecting elements, changing content, responding to clicks and keyboard input.

What it is, in plain English: The DOM (Document Object Model) is JavaScript's view of a web page — every heading, paragraph, button, and image is a node in a tree that JavaScript can read and modify. Events are things that happen: a user clicks a button, presses a key, or the page finishes loading. Together, the DOM and events are how JavaScript makes web pages interactive. This is browser-only: Node.js has no DOM.
Where this bites you

getElementsByClassName returns a live collection that updates itself as the page changes. Loop over it while removing that class, and each element drops out of the collection the moment you change it, so the indexes shift and the loop skips every other element. Half the items stay untouched, with no error.

const pending = document.getElementsByClassName("pending");   // a LIVE collection

for (let i = 0; i < pending.length; i++) {
  pending[i].classList.remove("pending");   // the element leaves the collection
}

console.log(document.querySelectorAll(".pending").length);
// 2   -- with four <li class="pending">, items 2 and 4 are still pending (Chromium 141)

Making pages respond to users

Browser only. Everything on this page applies to JavaScript running in a browser. Node.js has no document, no window, and no DOM.

The DOM — JavaScript's view of your HTML

When a browser loads an HTML page, it builds a tree of objects called the DOM (Document Object Model). Every element — every <h1>, <button>, <p> — becomes a node in this tree. JavaScript can read and modify any of these nodes to change what the user sees.

Selecting elements

// querySelector — the modern, flexible selector (like CSS selectors)
const title   = document.querySelector("h1");           // first h1
const btn     = document.querySelector("#submit-btn");  // element with id="submit-btn"
const warning = document.querySelector(".warning");     // first with class="warning"
const input   = document.querySelector("form input[type='email']"); // specific input

// querySelectorAll — returns ALL matching elements (a NodeList)
const allButtons = document.querySelectorAll("button");
const listItems  = document.querySelectorAll(".menu li");

// Loop over them:
allButtons.forEach(btn => {
  console.log(btn.textContent);
});

querySelectorAll, used above, returns a static NodeList: a snapshot taken once, which doesn't change while you modify the page. Loop over that (or copy a live collection first with [...pending]), and every element gets visited:

const pending = document.querySelectorAll(".pending");   // a STATIC snapshot

for (const el of pending) {
  el.classList.remove("pending");
}

console.log(document.querySelectorAll(".pending").length);   // 0

Reading and changing content

const heading = document.querySelector("h1");

// textContent — plain text (safe, recommended):
console.log(heading.textContent);    // current text
heading.textContent = "New Heading"; // change the text

// innerHTML — can include HTML tags (use carefully — XSS risk with user data):
const div = document.querySelector(".message");
div.innerHTML = "<strong>Bold message</strong> and normal text";

// NEVER do this with user input — it's an XSS vulnerability:
// div.innerHTML = userInput;  // ✗ dangerous if userInput contains <script>

// Safe way to insert user content:
div.textContent = userInput;   // ✓ always treated as plain text

Changing styles and classes

const box = document.querySelector(".box");

// classList — the right way to manage CSS classes:
box.classList.add("active");           // add a class
box.classList.remove("hidden");        // remove a class
box.classList.toggle("selected");      // add if absent, remove if present
box.classList.contains("active");      // true/false check
box.classList.replace("old", "new");   // replace one class with another

// Inline styles (use classes when possible — CSS is more maintainable):
box.style.color       = "red";
box.style.fontSize    = "18px";
box.style.display     = "none";   // hide the element
box.style.display     = "";       // restore (remove inline override)

Responding to events

An event is something that happens — a click, a keystroke, the page loading. You listen for events and run a function (the event handler) when they occur.

const button = document.querySelector("#my-button");

// addEventListener — the correct, modern way:
button.addEventListener("click", function(event) {
  console.log("Button clicked!");
  console.log("Clicked element:", event.target);
  console.log("Mouse position:", event.clientX, event.clientY);
});

// Arrow function works too:
button.addEventListener("click", (e) => {
  e.target.textContent = "Clicked!";   // change the button text
  e.target.disabled = true;             // disable after clicking
});

// Common events:
document.addEventListener("DOMContentLoaded", () => {
  // Runs when HTML is fully parsed — safe to access elements here
  console.log("Page ready");
});

const input = document.querySelector("input");
input.addEventListener("input", (e) => {
  console.log("Current value:", e.target.value);
});

input.addEventListener("keydown", (e) => {
  if (e.key === "Enter") {
    console.log("Enter pressed!");
  }
});

window.addEventListener("scroll", () => {
  console.log("Scrolled to:", window.scrollY);
});

Creating and inserting elements

// Create a new element:
const li = document.createElement("li");
li.textContent = "New list item";
li.classList.add("item");

// Insert into the page:
const list = document.querySelector("ul");
list.appendChild(li);                    // add at end
list.prepend(li);                        // add at start
list.insertBefore(li, list.children[2]); // add at specific position

// Modern insertion methods:
list.append(li);                          // like appendChild, also accepts strings
list.insertAdjacentHTML("beforeend", "<li>Another item</li>");

// Remove an element:
li.remove();   // remove from DOM
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.