JavaScript DOM Manipulation

Change Text, Classes, Attributes, and Structure

JavaScript DOM Manipulation

Once you've selected an element, you can change its text, toggle classes, set attributes, and add or remove children.

6 min read Level 2/5 #DOM#textContent#classList
What you'll learn
  • Update text and HTML safely
  • Toggle classes and read/write attributes
  • Create elements and add them to the tree

The DOM is live. Setting a property re-renders the page on the next frame — there’s no separate flush step.

Text vs HTML

textContent — plain text script.js
const h = document.querySelector("h1");
h.textContent = "New title";   // safe — text only
▶ Preview: console
innerHTML — parsed as HTML script.js
const card = document.querySelector(".card");
card.innerHTML = "<b>Hello</b>"; // parsed and inserted as markup
▶ Preview: console

Classes With classList

classList is the modern way to manage class names — no string manipulation needed.

Toggle, add, remove script.js
const btn = document.querySelector("button");

btn.classList.add("primary");
btn.classList.remove("disabled");
btn.classList.toggle("open");           // flip
btn.classList.toggle("open", true);     // force on
console.log(btn.classList.contains("primary")); // true
▶ Preview: console

Attributes

Two ways: direct properties for common attributes, and getAttribute / setAttribute for anything custom.

Reading and writing attributes script.js
const a = document.querySelector("a");

a.href = "/about";                     // direct property
a.target = "_blank";

a.setAttribute("data-track", "click"); // custom attribute
console.log(a.getAttribute("data-track")); // "click"
a.removeAttribute("data-track");
▶ Preview: console

data-* attributes also show up on el.dataset:

// <div data-user-id="42">
const div = document.querySelector("div");
console.log(div.dataset.userId);  // "42"  ← camelCase

Styling Inline (Rarely the Best Tool)

You can set styles directly, but for anything more than one-off tweaks prefer toggling a class.

Inline style — fine for animations script.js
const box = document.querySelector(".box");
box.style.background = "tomato";
box.style.borderRadius = "8px";   // camelCase, not "border-radius"
▶ Preview: console

Creating and Inserting Elements

Build a node, then attach it script.js
const li = document.createElement("li");
li.textContent = "New task";
li.classList.add("todo__item");

const list = document.querySelector(".todo");
list.append(li);                  // add as last child
// list.prepend(li);              // add as first child
// existing.before(li);           // insert before a sibling
// existing.after(li);            // insert after a sibling
▶ Preview: console

append / prepend accept multiple nodes AND strings, so you can write:

list.append("Footer:", document.createElement("hr"));

Removing Things

Drop a node script.js
const el = document.querySelector(".banner");
el?.remove();                          // gone
▶ Preview: console

Batch With a DocumentFragment

Appending one node at a time inside a loop causes layout work on every step. A DocumentFragment collects nodes off-screen and attaches them in one go.

One reflow instead of N script.js
const frag = document.createDocumentFragment();
for (const name of ["Ada", "Grace", "Linus"]) {
  const li = document.createElement("li");
  li.textContent = name;
  frag.append(li);
}
document.querySelector("ul").append(frag);  // one DOM write
▶ Preview: console

Up Next

Reading and writing isn’t enough — you also need to react to user input. Events.

JavaScript DOM Events →