Follow AiTechWorlds on LinkedIn for professional AI content!Follow Now →
22 minLesson 17 of 35
DOM & Browser APIs

DOM Selection & Manipulation

DOM Selection & Manipulation

The DOM (Document Object Model) is how JavaScript sees and interacts with HTML. Every element on the page is a node in a tree, and JavaScript can select, create, modify, and delete these nodes. This is what makes web pages interactive.

Selecting Elements

// Select a single element (returns first match or null)
const header = document.querySelector("h1");
const btn = document.querySelector("#submit-btn");
const input = document.querySelector(".form-input");
const active = document.querySelector("[data-active='true']");

// Select all matching elements (returns NodeList)
const allLinks = document.querySelectorAll("a");
const cards = document.querySelectorAll(".card");

// Convert NodeList to array for array methods
const cardArray = [...cards];
const linkHrefs = [...allLinks].map(a => a.href);

// Legacy selectors (still useful)
const byId = document.getElementById("main");        // fastest
const byClass = document.getElementsByClassName("btn"); // live HTMLCollection
const byTag = document.getElementsByTagName("p");

// Traversal
const parent = element.parentElement;
const children = element.children;         // HTMLCollection of direct children
const firstChild = element.firstElementChild;
const nextSib = element.nextElementSibling;
const prevSib = element.previousElementSibling;
const closest = element.closest(".container"); // walk up to find ancestor

Reading & Modifying Content

const el = document.querySelector(".message");

// Text content
el.textContent;           // get text (safe — never executes scripts)
el.textContent = "Hello"; // set text

// HTML content (be careful with user data — XSS risk!)
el.innerHTML;
el.innerHTML = "<strong>Bold</strong> text";  // parses HTML

// Safer HTML insertion for user content
el.textContent = userInput;  // always escape user input with textContent

// outerHTML — includes the element itself
el.outerHTML;  // "<div class='message'>Hello</div>"

Attributes

const img = document.querySelector("img");

// Read
img.getAttribute("src");     // "/path/to/image.jpg"
img.getAttribute("alt");

// Write
img.setAttribute("alt", "Product photo");
img.setAttribute("data-id", "42");

// Remove
img.removeAttribute("hidden");

// Check
img.hasAttribute("required");

// data-* attributes via dataset
const card = document.querySelector("[data-user-id]");
card.dataset.userId;          // "42" (always string)
card.dataset.userId = "99";   // sets data-user-id="99"

// Boolean attributes
input.disabled = true;
input.checked = true;
input.required = true;

Styling

const box = document.querySelector(".box");

// Inline styles
box.style.backgroundColor = "blue";
box.style.fontSize = "16px";
box.style.marginTop = "20px";

// Read computed styles (includes CSS rules)
const styles = window.getComputedStyle(box);
styles.getPropertyValue("background-color");

// CSS classes — best practice for styling
box.classList.add("active");
box.classList.remove("hidden");
box.classList.toggle("selected");       // add if missing, remove if present
box.classList.replace("old", "new");
box.classList.contains("active");       // true/false
box.classList;                           // DOMTokenList

// Replace all classes
box.className = "card card-primary";

Creating & Inserting Elements

// Create an element
const div = document.createElement("div");
div.className = "card";
div.textContent = "New card";

// Insert into DOM
document.body.appendChild(div);          // append as last child
parent.prepend(div);                     // first child
parent.insertBefore(div, referenceNode); // before a specific child
referenceNode.after(div);               // after a specific sibling
referenceNode.before(div);              // before a specific sibling

// insertAdjacentHTML — faster for HTML strings
parent.insertAdjacentHTML("beforeend", `<li class="item">${text}</li>`);
// positions: "beforebegin", "afterbegin", "beforeend", "afterend"

// Modern: replaceWith, prepend, append accept multiple nodes
parent.append(node1, node2, "text string");

Removing Elements

element.remove();                    // remove the element
parent.removeChild(child);           // remove a child (older API)

// Clear all children
parent.innerHTML = "";               // works but triggers parse
while (parent.firstChild) {
    parent.removeChild(parent.firstChild);  // clean but verbose
}
parent.replaceChildren();            // cleanest modern way

Efficient DOM Updates

Frequent DOM manipulation is expensive. Batch your updates:

// Slow — causes reflow on each iteration
for (const item of items) {
    const li = document.createElement("li");
    li.textContent = item;
    list.appendChild(li);  // 100 DOM updates!
}

// Fast — one DOM update using DocumentFragment
const fragment = document.createDocumentFragment();
for (const item of items) {
    const li = document.createElement("li");
    li.textContent = item;
    fragment.appendChild(li);  // builds in memory
}
list.appendChild(fragment);  // ONE DOM update

// Also fast — innerHTML with template literal
list.innerHTML = items.map(item => `<li>${item}</li>`).join("");
// But be careful: destroys existing event listeners, and XSS risk with user data

Practical: Building a Todo List

function TodoApp(container) {
    const input = container.querySelector(".todo-input");
    const addBtn = container.querySelector(".add-btn");
    const list = container.querySelector(".todo-list");
    let items = [];
    
    function render() {
        list.innerHTML = items.map((item, i) => `
            <li class="todo-item ${item.done ? 'done' : ''}" data-index="${i}">
                <input type="checkbox" ${item.done ? "checked" : ""}>
                <span>${item.text}</span>
                <button class="delete-btn">✕</button>
            </li>
        `).join("");
    }
    
    addBtn.addEventListener("click", () => {
        const text = input.value.trim();
        if (!text) return;
        items.push({ text, done: false });
        input.value = "";
        render();
    });
    
    list.addEventListener("click", (e) => {
        const li = e.target.closest(".todo-item");
        if (!li) return;
        const i = parseInt(li.dataset.index);
        
        if (e.target.type === "checkbox") items[i].done = !items[i].done;
        if (e.target.classList.contains("delete-btn")) items.splice(i, 1);
        render();
    });
}

Next lesson: Event Listeners & Event Delegation — handling user interactions efficiently.

📱

Get this course's notes on Telegram!

Free cheat sheets, summaries & practice exercises

Get Notes Free →
!