Skip to content

DOM Manipulation

The DOM (Document Object Model) is the in-memory representation of HTML created by the browser.

JavaScript interacts with this structure to:

  • Read content
  • Modify elements
  • Respond to user actions

graph TD A[HTML File] --> B[HTML Parsing] B --> C[DOM Tree] C --> D[CSS Parsing] D --> E[Render Tree] E --> F[Layout] F --> G[Paint]
  • DOM Tree → Structure of HTML
  • Render Tree → DOM + CSS combined
  • Layout → Calculates positions
  • Paint → Displays pixels on screen


Dynamic UI

Update content without page reload

User Interaction

Handle clicks, inputs, keyboard events

Data Rendering

Convert API data into UI

Real Apps

Forms, dashboards, modals, lists


// Old ways
document.getElementById("id");
document.getElementsByClassName("class");
// Modern, flexible
document.querySelector(".card");
document.querySelectorAll(".btn");

getElementById

Fastest, returns single element

querySelector

Uses CSS selectors, flexible

querySelectorAll

Returns NodeList (not array)


element.textContent;
element.innerText;
element.innerHTML;

element.setAttribute("id", "main");
element.getAttribute("id");
element.classList.add("active");
element.classList.remove("hidden");
element.classList.toggle("open");

const div = document.createElement("div");
div.textContent = "Hello";
document.body.append(div);

graph LR A[Create Element] --> B[Set Content] B --> C[Append to DOM] C --> D[Rendered]

parent.append(child);
parent.prepend(child);
element.before(newNode);
element.after(newNode);

element.remove();
parent.removeChild(child);

oldEl.replaceWith(newEl);

graph TD A[Window] --> B[Document] B --> C[Parent] C --> D[Target] D --> E[Bubble Back]

  1. Capture phase (top → target)
  2. Target phase
  3. Bubble phase (target → top)

Instead of attaching listeners to many elements:

document.querySelector("#list").addEventListener("click", (e) => {
if (e.target.tagName === "LI") {
console.log("Item clicked");
}
});

DOM updates are expensive.

for (let i = 0; i < 1000; i++) {
document.body.append(document.createElement("div"));
}
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
fragment.append(document.createElement("div"));
}
document.body.append(fragment);

graph TD A[DOM Change] --> B{Layout Change?} B -->|Yes| C[Reflow] B -->|No| D[Repaint]
  • Reflow → layout recalculation (expensive)
  • Repaint → visual update only

const users = ["A", "B", "C"];
const ul = document.querySelector("#users");
ul.innerHTML = "";
users.forEach((user) => {
const li = document.createElement("li");
li.textContent = user;
ul.append(li);
});

element.innerHTML = userInput; // dangerous

  1. Cache DOM queries
  2. Minimize DOM updates
  3. Use event delegation
  4. Prefer textContent over innerHTML
  5. Use fragments for bulk updates