DOM
Selecting elements, handling events, and updating the page with the Document Object Model.
What you'll learn
- What the DOM is and how the browser builds it from HTML
- Selecting elements with querySelector and getElementById
- Modifying content with textContent and innerHTML
- Handling events with addEventListener
- Creating and appending new elements
Concept
What Is the DOM?
The Document Object Model (DOM) is a live, tree-like representation of your HTML that JavaScript can read and modify. When the browser loads a page, it parses the HTML and builds this tree. Every HTML element becomes a node you can access via document.
document
└── html
├── head
│ └── title
└── body
├── h1
├── p
└── button
Selecting Elements
// By ID — returns a single element or null
const title = document.getElementById("main-title");
// By CSS selector — first match only
const button = document.querySelector(".btn-primary");
// All matches — returns a NodeList
const items = document.querySelectorAll("li");
querySelector and querySelectorAll accept any CSS selector, so they are the most flexible and are the modern default.
Modifying Content
const heading = document.querySelector("h1");
heading.textContent = "Updated Title"; // safe — sets plain text
heading.innerHTML = "<span>HTML</span>"; // parses HTML — XSS risk!
Prefer textContent when you only need plain text. innerHTML parses the string as HTML, which can introduce cross-site scripting (XSS) vulnerabilities if the content includes user input.
Handling Events
const button = document.querySelector("button");
button.addEventListener("click", (event) => {
console.log("Clicked!", event.target);
});
Common events: click, input, change, submit, keydown, mouseover. The callback receives an event object with details about what happened.
Creating and Appending Elements
const list = document.querySelector("ul");
const newItem = document.createElement("li");
newItem.textContent = "A new item";
newItem.classList.add("highlight");
list.appendChild(newItem);
classList for Styling
const card = document.querySelector(".card");
card.classList.add("active");
card.classList.remove("hidden");
card.classList.toggle("selected"); // add if missing, remove if present
A Note on Frameworks
Modern apps often use React, Vue, or Svelte instead of touching the DOM directly. But understanding the DOM is essential — frameworks are abstractions over it, and you will still need it for browser extensions, vanilla scripts, and understanding how frameworks work under the hood.
Example
// Select the button and the output area
const button = document.querySelector("#counter-btn");
const display = document.querySelector("#count-display");
let count = 0;
// Update the display
function updateDisplay() {
display.textContent = `Count: ${count}`;
// Toggle a CSS class based on the count
display.classList.toggle("even", count % 2 === 0);
}
// Handle clicks
button.addEventListener("click", () => {
count++;
updateDisplay();
// Dynamically create a log entry
if (count <= 5) {
const log = document.createElement("p");
log.textContent = `Clicked ${count} time(s)`;
document.querySelector("#log").appendChild(log);
}
});
// Handle keyboard shortcuts
document.addEventListener("keydown", (e) => {
if (e.key === "r") {
count = 0;
updateDisplay();
}
});
updateDisplay(); // initialize
A working counter: selects elements, updates textContent safely, toggles a CSS class, creates and appends log entries, and listens for keyboard shortcuts. Paste this into a page with matching elements.
Try it
- HTML ↔ Markdown
Convert between HTML and Markdown — both are DOM representations.
- SVG Optimizer
Optimize SVG markup that the DOM renders.
Common mistakes
The mistake
Using innerHTML with user input and creating an XSS vulnerability
The fix
Never put untrusted data into innerHTML. Use textContent for plain text, or sanitize the HTML first. Frameworks like React escape values by default for this reason.
The mistake
Calling querySelector before the element exists in the DOM
The fix
Put your script at the end of the body, or wrap it in DOMContentLoaded: document.addEventListener('DOMContentLoaded', () => { ... }). Otherwise querySelector returns null.
Related Resources
Related Snippets
- HTML Form Snippet
Form elements you will wire up with DOM events.
Related Cheatsheets
- HTML Cheatsheet
HTML elements and attributes that the DOM represents.
- CSS Cheatsheet
CSS selectors used by querySelector and classList.
Practice DOM
2 exercises
Look up unfamiliar terms
A beginner-friendly glossary explains jargon in plain English — variables, functions, DOM, Promise, and more.
Build real projects
Apply what you learned by building guided projects with starter code and solutions.
Decode error messages
Plain-English explanations of common errors — what they mean, why they happen, and how to fix them.