18. DOM Manipulation
`append` accepts multiple nodes and strings at once. `prepend` puts them at the front.
What you'll learn
- 1Change the tree with `createElement`, `appendChild`, `prepend`, `remove`.
- 2Add/remove/toggle classes with `classList`.
- 3Set inline styles via the `style` property.
- 4Use a DocumentFragment to insert many nodes efficiently.
- 5Set text and attributes safely.
Overview
`append` accepts multiple nodes and strings at once. `prepend` puts them at the front.
Core Concepts
1. Create and insert elements
const li = document.createElement("li");
li.textContent = "new item";
list.appendChild(li);`append` accepts multiple nodes and strings at once. `prepend` puts them at the front.
2. Remove
target.remove();
parent.removeChild(target); // older API3. classList
el.classList.add("active");
el.classList.remove("hidden");
el.classList.toggle("open");
el.classList.contains("active");Be careful: `className = "..."` overwrites every existing class.
4. style
el.style.color = "red";
el.style.backgroundColor = "yellow";CSS `background-color` becomes camelCase `backgroundColor` in JS.
5. DocumentFragment
When inserting many nodes at once, use a fragment to reduce reflows.
const frag = document.createDocumentFragment();
for (let i = 0; i < 100; i += 1) {
const li = document.createElement("li");
li.textContent = `item ${i}`;
frag.appendChild(li);
}
list.appendChild(frag);Examples
| File | What it covers |
|---|---|
| index.html | Example HTML |
| 01_create_element.js | createElement + appendChild |
| 02_append_remove.js | append/prepend/remove |
| 03_classlist.js | classList add/remove/toggle |
| 04_style.js | Setting style properties |
src/01_create_element.js
/**
* Create a new element and append it to the list.
*/
const list = document.querySelector("#list");
const li = document.createElement("li");
li.textContent = "new item (createElement)";
list.appendChild(li);
src/02_append_remove.js
/**
* Use append/prepend/remove.
*/
const list = document.querySelector("#list");
list.append("a string node", document.createElement("hr"));
const first = document.createElement("li");
first.textContent = "front item";
list.prepend(first);
// Remove the first item after a delay
setTimeout(() => {
first.remove();
console.log("removed first item");
}, 1000);
src/03_classlist.js
/**
* Add/remove/toggle classes with classList.
*/
const title = document.querySelector("#title");
title.classList.add("active");
const btn = document.querySelector("#btn");
btn.classList.toggle("hidden");
console.log("btn hidden?", btn.classList.contains("hidden"));
btn.classList.toggle("hidden"); // restore
src/04_style.js
/**
* Apply inline styles via the style property.
*/
const box = document.querySelector("#box");
box.style.color = "white";
box.style.backgroundColor = "steelblue";
box.style.padding = "12px";
box.style.borderRadius = "8px";
src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DOM manipulation</title>
<style>
.active { color: white; background: tomato; }
.hidden { display: none; }
</style>
</head>
<body>
<h1 id="title">DOM manipulation example</h1>
<ul id="list">
<li>existing item</li>
</ul>
<button id="btn">button</button>
<p id="box">box</p>
<script src="01_create_element.js"></script>
<script src="02_append_remove.js"></script>
<script src="03_classlist.js"></script>
<script src="04_style.js"></script>
</body>
</html>
Common Mistakes
- Passing a string to `appendChild` β it only accepts nodes (use `append` instead).
- Appending to the parent inside a loop repeatedly and hurting performance.
- Setting `className = "x"` and wiping every existing class.
- Forgetting CSS units in `style` (e.g. `px`).
- appendChild-ing the same node into a second place β it just moves rather than copies.
FAQ
Q1. appendChild vs append?
`append` accepts multiple nodes/strings and returns nothing. `appendChild` takes one node and returns it.
Q2. Why is classList better?
It changes one class at a time without touching the others.
Q3. Inline style or a CSS class?
Toggle classes when you can; use inline style only for dynamically computed values (e.g. positions).
Practice
Build a page where clicking a button appends a new item to a list.
homework/README.md
Build a page where pressing the button adds the value from the text input as a new `<li>`. Skip empty values.
See `answer/homework_01.html` and `answer/homework_01.js`.
homework/answer/homework_01.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Homework 18-1</title>
</head>
<body>
<input id="text" type="text" placeholder="todo" />
<button id="add">Add</button>
<ul id="todos"></ul>
<script src="homework_01.js"></script>
</body>
</html>
homework/answer/homework_01.js
/**
* Append a new item using the input value.
*/
const input = document.querySelector("#text");
const addBtn = document.querySelector("#add");
const todos = document.querySelector("#todos");
addBtn.addEventListener("click", () => {
const value = input.value.trim();
if (!value) return;
const li = document.createElement("li");
li.textContent = value;
todos.appendChild(li);
input.value = "";
input.focus();
});
Next Lecture
[19_Event_Handling](../19_μ΄λ²€νΈ_μ²λ¦¬/) β Handling user interactions.
All lecture materials and example code are openly available on GitHub.
View on GitHub β