๐beginner
DOM Manipulation
The DOM (Document Object Model) is JavaScript's interface to the HTML page. Learn to select, create, modify, and remove elements programmatically.
What is the DOM?
When the browser loads an HTML page, it creates a tree of objects called the Document Object Model (DOM). Every HTML element becomes a Node in this tree that JavaScript can read and modify.
hljs html
<html>
<body>
<h1 id="title">Hello</h1>
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
</ul>
</body>
</html>
JavaScript can access and change every part of this tree.
Selecting Elements
hljs javascript
// By ID (returns single element or null)
const title = document.getElementById("title");
// By CSS selector โ single element
const first = document.querySelector(".list li"); // first match
const btn = document.querySelector("#submit-btn");
// By CSS selector โ all matches (NodeList)
const allItems = document.querySelectorAll(".list li");
const allBtns = document.querySelectorAll("button");
// Convert NodeList to Array for array methods
const itemsArray = Array.from(allItems);
// or: [...allItems]
// Older methods (still work)
document.getElementsByClassName("list"); // HTMLCollection
document.getElementsByTagName("li"); // HTMLCollection
Reading and Modifying Content
hljs javascript
const el = document.querySelector("#title");
// Text content (safe โ no HTML parsing)
el.textContent; // get
el.textContent = "New Title"; // set
// HTML content (careful with user input โ XSS risk!)
el.innerHTML; // get
el.innerHTML = "<strong>Bold Title</strong>"; // set
// Form input values
const input = document.querySelector("input");
input.value; // current value
input.value = "default"; // set value
โ ๏ธNever use innerHTML with user input
innerHTML parses the string as HTML. If you set it to user-provided content, you risk XSS (Cross-Site Scripting) attacks. Always use textContent for user data, or sanitize the HTML first.
Modifying Attributes and Classes
hljs javascript
const img = document.querySelector("img");
// Attributes
img.getAttribute("src"); // get
img.setAttribute("src", "/new.png"); // set
img.removeAttribute("alt"); // remove
img.hasAttribute("data-id"); // check
// Direct property (faster than getAttribute/setAttribute for standard attrs)
img.src = "/new.png";
img.alt = "Description";
img.disabled = true; // form elements
img.href = "..."; // links
// Classes
el.classList.add("active");
el.classList.remove("hidden");
el.classList.toggle("open"); // add if absent, remove if present
el.classList.contains("active"); // true/false
el.classList.replace("old", "new");
// All classes as a string
el.className; // "class1 class2 class3"
Modifying Styles
hljs javascript
const box = document.querySelector(".box");
// Inline styles
box.style.color = "red";
box.style.backgroundColor = "#1e293b"; // camelCase!
box.style.fontSize = "16px";
box.style.display = "none"; // hide
box.style.display = ""; // remove inline style (revert to CSS)
// Read computed style (what's actually applied, including CSS)
const computed = getComputedStyle(box);
console.log(computed.color); // "rgb(255, 0, 0)"
console.log(computed.fontSize); // "16px"
Creating and Inserting Elements
hljs javascript
// Create element
const newItem = document.createElement("li");
newItem.textContent = "New item";
newItem.classList.add("list-item");
// Insert
const list = document.querySelector("ul");
list.appendChild(newItem); // add at end
list.prepend(newItem); // add at start
list.insertBefore(newItem, list.firstChild); // before specific child
// Modern: insertAdjacentElement
list.insertAdjacentElement("beforeend", newItem); // inside, at end
list.insertAdjacentElement("afterbegin", newItem); // inside, at start
list.insertAdjacentElement("beforebegin", newItem); // before the element
list.insertAdjacentElement("afterend", newItem); // after the element
// Insert HTML string
list.insertAdjacentHTML("beforeend", "<li>HTML item</li>");
// Create fragment (efficient for multiple insertions)
const fragment = document.createDocumentFragment();
["a", "b", "c"].forEach(text => {
const li = document.createElement("li");
li.textContent = text;
fragment.appendChild(li);
});
list.appendChild(fragment); // single DOM update
Removing Elements
hljs javascript
const el = document.querySelector("#to-remove");
// Modern
el.remove();
// Older (still works)
el.parentNode.removeChild(el);
Traversing the DOM
hljs javascript
const child = document.querySelector(".child");
// Parent
child.parentElement; // parent element (null if none)
child.parentNode; // parent node (could be document)
// Children
child.children; // HTMLCollection of child elements
child.childNodes; // NodeList of all child nodes (includes text nodes)
child.firstElementChild; // first child element
child.lastElementChild; // last child element
// Siblings
child.nextElementSibling; // next sibling element
child.previousElementSibling; // previous sibling element
// Closest ancestor matching selector
child.closest(".container"); // walks up DOM to find matching ancestor
Data Attributes
Custom data stored in HTML:
hljs javascript
// HTML: <div data-user-id="42" data-role="admin">
const el = document.querySelector("[data-user-id]");
// Access
el.dataset.userId; // "42" (camelCase access to data-user-id)
el.dataset.role; // "admin"
// Set
el.dataset.status = "active"; // creates data-status attribute
// Read all
for (const [key, value] of Object.entries(el.dataset)) {
console.log(key, value);
}
โถTry it yourself
Key Takeaways
querySelector/querySelectorAllare the go-to selectors (CSS syntax)- Use
textContentfor user data (safe);innerHTMLonly for trusted HTML classListmethods (.add(),.remove(),.toggle()) are the clean way to manage classescreateDocumentFragmentbatches DOM insertions for better performanceel.datasetaccessesdata-*attributes as camelCase properties- Traverse the DOM with
parentElement,children,nextElementSibling
Ready to test your knowledge?
Take a quiz on what you just learned.