22 minLesson 12 of 40
JavaScript for Web
DOM Manipulation Mastery
DOM Manipulation Mastery
The Document Object Model is JavaScript's interface to the HTML page. In web development, you'll use DOM manipulation to build interactive UIs, update content dynamically, and respond to user actions — without a page reload.
Selecting Elements
// querySelector — recommended for everything
const header = document.querySelector("header");
const submitBtn = document.querySelector("#submit");
const firstCard = document.querySelector(".card");
const emailInput = document.querySelector('input[type="email"]');
// querySelectorAll — returns NodeList
const allCards = document.querySelectorAll(".card");
const navLinks = document.querySelectorAll(".nav a");
// Convert NodeList to array for array methods
const cardArray = Array.from(allCards);
const links = [...navLinks];
// Contextual search (search within an element)
const list = document.querySelector(".todo-list");
const items = list.querySelectorAll(".todo-item");
Modifying Content and Attributes
const title = document.querySelector("h1");
// Text content (safe — no HTML parsing, XSS-safe)
title.textContent = "New Title";
title.textContent; // read current text
// Inner HTML (careful with user content!)
const container = document.querySelector(".content");
container.innerHTML = `<p>Hello <strong>World</strong></p>`;
// Attributes
const img = document.querySelector("img");
img.setAttribute("alt", "New description");
img.getAttribute("src");
img.removeAttribute("hidden");
img.hasAttribute("required");
// data-* attributes
const card = document.querySelector("[data-id]");
card.dataset.id; // read "data-id"
card.dataset.userId = "42"; // set "data-user-id"
// Direct property access (faster for common attributes)
input.value = "hello";
input.disabled = true;
input.checked = false;
link.href = "/new-page";
img.src = "/new-image.jpg";
CSS Classes and Styles
const el = document.querySelector(".box");
// classList methods
el.classList.add("active", "highlighted");
el.classList.remove("hidden");
el.classList.toggle("selected"); // add if missing, remove if present
el.classList.replace("old-class", "new");
el.classList.contains("active"); // boolean
// Inline styles (prefer CSS classes over inline styles)
el.style.backgroundColor = "#4a90e2";
el.style.setProperty("--custom-var", "value"); // CSS variables
el.style.removeProperty("color");
// Read computed styles (what's actually applied)
const computed = window.getComputedStyle(el);
computed.getPropertyValue("font-size");
computed.getPropertyValue("--primary-color");
Creating and Inserting Elements
// Create
const card = document.createElement("div");
card.className = "card";
card.dataset.id = "42";
const title = document.createElement("h3");
title.textContent = "Card Title";
const button = document.createElement("button");
button.textContent = "View More";
button.className = "btn";
// Build the structure
card.append(title, button);
// Insert into DOM
const grid = document.querySelector(".grid");
grid.appendChild(card); // last child
grid.prepend(card); // first child
grid.insertBefore(card, grid.firstElementChild);
// Modern positional insertion
existingCard.after(newCard); // after sibling
existingCard.before(newCard); // before sibling
// insertAdjacentHTML — fast string HTML insertion
grid.insertAdjacentHTML("beforeend", `
<div class="card">
<h3>${escapeHtml(title)}</h3>
<p>${escapeHtml(body)}</p>
</div>
`);
function escapeHtml(str) {
const div = document.createElement("div");
div.textContent = str;
return div.innerHTML;
}
Removing and Replacing
// Remove
element.remove();
// Replace
oldElement.replaceWith(newElement);
// Clear all children
container.innerHTML = "";
container.replaceChildren(); // modern, cleaner
Efficient Batch Updates
// Inefficient — one DOM update per item
items.forEach(item => {
list.appendChild(createItemEl(item));
});
// Efficient — one DOM update total
const fragment = document.createDocumentFragment();
items.forEach(item => fragment.appendChild(createItemEl(item)));
list.appendChild(fragment);
// Also efficient — single innerHTML set
list.innerHTML = items.map(item => `
<li class="item" data-id="${item.id}">
${escapeHtml(item.text)}
</li>
`).join("");
Traversing the DOM
const el = document.querySelector(".selected");
el.parentElement;
el.children; // HTMLCollection of direct children
el.firstElementChild;
el.lastElementChild;
el.nextElementSibling;
el.previousElementSibling;
el.closest(".container"); // walk up to find nearest ancestor
// Check relationships
el.contains(child); // is child a descendant?
el.matches(".active"); // does el match this selector?
Real-World: Dynamic Table
function renderTable(data, columns, container) {
const headers = columns.map(col => `<th>${col.label}</th>`).join("");
const rows = data.map(row =>
`<tr>${columns.map(col => `<td>${row[col.key] ?? ""}</td>`).join("")}</tr>`
).join("");
container.innerHTML = `
<table>
<thead><tr>${headers}</tr></thead>
<tbody>${rows}</tbody>
</table>
`;
}
renderTable(
[{ id: 1, name: "Alice", role: "Admin" }, { id: 2, name: "Bob", role: "User" }],
[{ key: "id", label: "ID" }, { key: "name", label: "Name" }, { key: "role", label: "Role" }],
document.querySelector("#user-table")
);
Next lesson: Event Handling & Delegation — responding to user interactions.
📱
Get Notes Free →Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises