4.4 Module 4 · Document Object Model (DOM)

DOM Manipulation

Select, modify, create, and delete HTML elements entirely through JavaScript — the techniques that power every interactive page on the web.

1

Definition

DOM Manipulation refers to the process of selecting HTML elements and dynamically modifying their content, attributes, styles, or structure using JavaScript.

With DOM manipulation you can change text after a button click, apply styles in response to user input, build new elements from data, and remove elements that are no longer needed — all without touching the HTML file or reloading the page.

2

Simple Way

DOM Manipulation means "control your webpage using JavaScript". Four operations cover everything:

Select Find the element you want — by ID, class, tag, or CSS selector
Modify Change its text, HTML, attributes, or styles
Create Build a brand new element and insert it into the page
Remove Delete an element from the DOM entirely
3

Code Examples

Example 1 — Selecting Elements
<h1 id="title">Hello</h1>
<p class="note">First note</p>
<p class="note">Second note</p>

<script>
  // By ID — returns one element
  let h = document.getElementById("title");
  console.log(h.textContent); // "Hello"

  // querySelector — returns FIRST match (CSS selector)
  let first = document.querySelector(".note");
  console.log(first.textContent); // "First note"

  // querySelectorAll — returns ALL matches (NodeList)
  let all = document.querySelectorAll(".note");
  console.log(all.length); // 2
</script>
Live Preview
Explanation
  • getElementById(id) — fastest selector, returns one element by its id
  • querySelector(css) — flexible, returns the first element matching any CSS selector
  • querySelectorAll(css) — returns a NodeList of all matches, iterable with forEach
Example 2 — Modifying Content, Attributes & Styles
<h2 id="heading">Original Heading</h2>
<img id="logo" src="old.png" alt="Logo">

<script>
  let el = document.getElementById("heading");

  // Change text
  el.textContent = "Updated Heading";

  // Change inline style
  el.style.color      = "#f7df1e";
  el.style.background = "#111";
  el.style.padding    = "8px 16px";

  // Change attribute
  document.getElementById("logo").setAttribute("src", "new.png");
  document.getElementById("logo").setAttribute("alt", "New Logo");
</script>
Live Preview
Explanation
  • element.style.propertyName sets inline CSS — camelCase (backgroundColor, not background-color)
  • setAttribute(name, value) sets any HTML attribute — src, href, class, alt
  • getAttribute(name) reads an attribute's current value
Example 3 — Creating & Adding New Elements
<ul id="myList">
  <li>Item 1</li>
</ul>

<script>
  let list = document.getElementById("myList");

  // 1. Create the element
  let newItem = document.createElement("li");

  // 2. Set its content
  newItem.textContent = "Item 2 — added by JavaScript";

  // 3. Append it to the parent
  list.appendChild(newItem);

  // Modern alternative: insertAdjacentHTML
  list.insertAdjacentHTML("beforeend", "<li>Item 3 — via insertAdjacentHTML</li>");
</script>
Live Preview
Explanation
  • createElement(tag) creates a new detached element — it is not visible until you insert it
  • appendChild(element) inserts it as the last child of the parent
  • insertAdjacentHTML(position, html) is a faster shortcut when you have an HTML string ready
Example 4 — Removing Elements
<ul id="items">
  <li id="a">Keep me</li>
  <li id="b">Delete me</li>
  <li id="c">Keep me too</li>
</ul>

<script>
  // Modern way — element removes itself
  document.getElementById("b").remove();

  // Classic way — parent removes child
  // let list   = document.getElementById("items");
  // let target = document.getElementById("b");
  // list.removeChild(target);
</script>
Live Preview
Explanation
  • element.remove() is the modern, clean way — the element removes itself from the DOM
  • parent.removeChild(child) is the older equivalent — requires a reference to both parent and child
  • After removal, the element no longer exists in the DOM — it cannot be clicked, styled, or accessed
4

Real-Life Example

Think of a remote control for your TV — every button maps to a DOM operation:

Select
Selecting a channel — pointing the remote at a specific element
Modify
Changing the volume — updating an element's style or content
Create
Adding a new channel to the guide — inserting a new element
Remove
Deleting a channel from the guide — removing an element permanently
5

HTML + JavaScript Example

Click ▶ Preview to see all four DOM operations — select, modify, add, and remove — working live in one demo.

Live in Browser — Full DOM Manipulation Demo
<!DOCTYPE html>
<html>
<head><title>DOM Demo</title></head>
<body style="font-family:sans-serif;padding:24px;background:#f8f9fa">

  <h2 id="heading">Hello Aman</h2>

  <div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px">
    <button onclick="changeText()"
      style="padding:7px 14px;background:#f7df1e;border:none;border-radius:6px;
             cursor:pointer;font-weight:700">Change Text</button>
    <button onclick="addItem()"
      style="padding:7px 14px;background:#4ade80;border:none;border-radius:6px;
             cursor:pointer;font-weight:700">Add Item</button>
    <button onclick="removeItem()"
      style="padding:7px 14px;background:#f87171;border:none;border-radius:6px;
             cursor:pointer;font-weight:700;color:#fff">Remove Item</button>
  </div>

  <ul id="myList" style="padding-left:20px;line-height:2">
    <li>Item 1</li>
  </ul>

  <script>
    let count = 1;

    function changeText() {
      let h = document.getElementById("heading");
      h.textContent = "Text Changed by JavaScript!";
      h.style.color = "#e07b00";
    }

    function addItem() {
      count++;
      let li = document.createElement("li");
      li.textContent = "Item " + count;
      document.getElementById("myList").appendChild(li);
    }

    function removeItem() {
      let list = document.getElementById("myList");
      if (list.lastElementChild) {
        list.lastElementChild.remove();
        if (count > 1) count--;
      }
    }
  </script>

</body>
</html>
Live Preview
6

Tasks (Practice)

Easy Task 1 — Select and update a heading
Starter code
<h2 id="myHeading">Original Heading</h2>
<button onclick="updateIt()">Update</button>

<script>
  function updateIt() {
    // select #myHeading and change its text
  }
</script>
  • Use getElementById("myHeading") to select the heading
  • Change its textContent to "Updated by JS!"
  • Also change its style.color to "blue"
Medium Task 2 — Add and remove list items
Starter code
<ul id="taskList"></ul>
<button onclick="addTask()">Add Task</button>
<button onclick="removeTask()">Remove Last</button>

<script>
  let n = 0;
  function addTask() {
    // create <li>, set text, append to #taskList
  }
  function removeTask() {
    // remove the last <li> from #taskList
  }
</script>
  • In addTask(): increment n, create a <li>, set text to "Task N", append it
  • In removeTask(): call list.lastElementChild?.remove()
  • Add a guard — if the list is empty, print a message instead of trying to remove
7

MCQs

Q1
Which method selects an element directly by its id?
  • A querySelector
  • B getElementById
  • C getElementsByClassName
  • D select
💡 B is correct. getElementById() is the fastest selector — it looks up a single unique element by its id attribute. querySelector("#id") does the same thing but is slightly slower due to CSS selector parsing.
Q2
What does querySelector(".card") return?
<p class="card">First</p>
<p class="card">Second</p>
<script>
  let el = document.querySelector(".card");
  console.log(el.textContent);
</script>
Live Preview
  • A All elements with class "card"
  • B The first element with class "card"
  • C The last element with class "card"
  • D An array of all matches
💡 B is correct. querySelector() returns only the first matching element in document order. To get all matches use querySelectorAll(), which returns a NodeList you can loop through.
Q3
Which method creates a new HTML element?
let li = document.createElement("li");
li.textContent = "New item";
document.querySelector("ul").appendChild(li);
Output
Run it to verify
  • A appendChild
  • B createElement
  • C removeChild
  • D innerHTML
💡 B is correct. createElement(tag) creates a new detached element that doesn't appear on the page yet. appendChild() then inserts it. You always need both — create first, then attach.
8

Pro Tips & Extra Knowledge

  • 01

    Prefer querySelector and querySelectorAll over the older selection methods — they accept any CSS selector and work consistently:

    querySelector vs older methods
    // Old API — limited and inconsistent
    document.getElementById("title");
    document.getElementsByClassName("card"); // live HTMLCollection
    document.getElementsByTagName("p");      // live HTMLCollection
    
    // Modern API — flexible, consistent, preferred
    document.querySelector("#title");        // by ID
    document.querySelector(".card");         // by class (first match)
    document.querySelectorAll("p.note");     // all <p> with class "note"
    document.querySelector("ul li:last-child"); // any CSS selector!
    Output
    Click ▶ Run to execute
  • 02

    Use element.remove() — the modern self-removal method. The old parent.removeChild(child) requires an extra reference to the parent:

    Modern remove() vs old removeChild()
    // Modern — element removes itself (clean)
    document.querySelector("#item2")?.remove();
    
    // Old — must go through the parent
    let parent = document.querySelector("#myList");
    let child  = document.querySelector("#item2");
    if (child) parent.removeChild(child);
    Output
    Click ▶ Run to execute
  • 03

    Use classList to add, remove, and toggle CSS classes — far cleaner than manually editing style properties:

    classList — the clean way to handle classes
    let el = document.querySelector("#heading");
    
    el.classList.add("highlight");       // add class
    el.classList.remove("highlight");    // remove class
    el.classList.toggle("active");       // add if absent, remove if present
    console.log(el.classList.contains("active")); // true or false
    Output
    Click ▶ Run to execute
  • 04

    Batch DOM writes — every direct DOM change can trigger a browser repaint. Build your elements in memory first, then insert the whole structure at once:

    Batch with DocumentFragment
    let list     = document.querySelector("#output");
    let fragment = document.createDocumentFragment(); // off-screen container
    
    ["Alpha", "Beta", "Gamma"].forEach(name => {
      let li = document.createElement("li");
      li.textContent = name;
      fragment.appendChild(li); // no repaint yet
    });
    
    list.appendChild(fragment); // one repaint, three items inserted
    Output
    Click ▶ Run to execute
Mini Challenge

A list item is created and given text — but will it ever appear on the page? Think about what's missing before checking in the preview.

Will "New Item" appear on screen?
<ul id="list">
  <li>Existing item</li>
</ul>

<script>
  let li = document.createElement("li");
  li.textContent = "New Item";
  // Nothing else...
</script>
Live Preview
Step-by-Step Explanation
// Step 1: document.createElement("li")
//   Creates a new <li> element in memory
//   It exists as a JavaScript object — but NOT in the DOM yet
//   It is completely detached from the page

// Step 2: li.textContent = "New Item"
//   Sets the text of the in-memory element
//   Still NOT attached to the page

// Step 3: Nothing else...
//   The element is created and configured but NEVER inserted
//   The browser only renders elements that are IN the DOM

// Answer: NO — "New Item" will NOT appear on screen.
//   Only "Existing item" is visible because it was in the HTML.

// Fix: you must append the element to the DOM
//   document.getElementById("list").appendChild(li);
//   ← After this line, "New Item" appears on the page

// Key rule:
//   createElement() → creates in memory (invisible)
//   appendChild() / insertAdjacentHTML() → puts it in the DOM (visible)