Advanced JavaScript - DOM Manipulation

Code SubtleCode Subtle
10 min read

Complete DOM Manipulation Guide

1. Async vs Defer

Definition

async and defer are attributes used with <script> tags to control when and how JavaScript files are loaded and executed in relation to HTML parsing.

Syntax

<!-- Async: Downloads in parallel, executes immediately when ready -->
<script src="script.js" async></script>

<!-- Defer: Downloads in parallel, executes after HTML parsing is complete -->
<script src="script.js" defer></script>

<!-- Normal: Blocks HTML parsing while downloading and executing -->
<script src="script.js"></script>

Key Differences

  • async: Script executes as soon as it's downloaded, potentially interrupting HTML parsing

  • defer: Script waits until HTML parsing is complete before executing

  • neither: Script blocks HTML parsing while downloading and executing

Example

<!DOCTYPE html>
<html>
<head>
    <!-- This script will execute after DOM is fully parsed -->
    <script src="dom-manipulation.js" defer></script>
</head>
<body>
    <h1 id="title">Hello World</h1>
    <!-- Script can safely access this element because of defer -->
</body>
</html>

2. Select Elements Using ID

Definition

getElementById() is a method that returns the HTML element with the specified ID attribute. IDs must be unique within a document.

Syntax

document.getElementById("elementId")

Example

<!-- HTML -->
<h1 id="main-title">Welcome to My Website</h1>

<script>
// JavaScript
const titleElement = document.getElementById("main-title");
console.log(titleElement.textContent); // Output: "Welcome to My Website"
</script>

3. querySelector

Definition

querySelector() returns the first element that matches a specified CSS selector. It's more flexible than getElementById() as it can select by ID, class, tag, or any valid CSS selector.

Syntax

// Select by ID
document.querySelector("#elementId")

// Select by class
document.querySelector(".className")

// Select by tag
document.querySelector("tagName")

// Select by attribute
document.querySelector("[attribute='value']")

// Complex selectors
document.querySelector("div.container > p:first-child")

Example

<!-- HTML -->
<div class="container">
    <p class="highlight">This is a paragraph</p>
    <button id="myBtn">Click Me</button>
</div>

<script>
// JavaScript
const paragraph = document.querySelector(".highlight");
const button = document.querySelector("#myBtn");
const container = document.querySelector("div.container");

paragraph.style.color = "blue";
</script>

4. textContent & innerText

Definition

Both properties are used to get or set the text content of an element, but they handle whitespace and hidden elements differently.

Syntax

// Get text content
const text = element.textContent;
const visibleText = element.innerText;

// Set text content
element.textContent = "New text content";
element.innerText = "New visible text";

Key Differences

  • textContent: Gets/sets all text including hidden elements and preserves formatting

  • innerText: Gets/sets only visible text, respects styling like display: none

Example

<!-- HTML -->
<div id="content">
    Hello <span style="display: none;">Hidden</span> World
</div>

<script>
// JavaScript
const element = document.getElementById("content");

console.log(element.textContent); // "Hello Hidden World"
console.log(element.innerText);   // "Hello World"

element.textContent = "New content"; // Changes text to "New content"
</script>

5. Change the Styles of Elements Using JS

Definition

The style property allows you to get or set inline CSS styles for an element. Style properties use camelCase instead of kebab-case.

Syntax

// Set individual style properties
element.style.property = "value";

// CSS property names with hyphens become camelCase
element.style.backgroundColor = "red";  // background-color
element.style.fontSize = "20px";        // font-size
element.style.marginTop = "10px";       // margin-top

// Set multiple styles using cssText
element.style.cssText = "color: red; font-size: 20px;";

Example

<!-- HTML -->
<div id="myBox">This is a box</div>
<button onclick="changeStyle()">Change Style</button>

<script>
// JavaScript
function changeStyle() {
    const box = document.getElementById("myBox");

    box.style.backgroundColor = "lightblue";
    box.style.color = "darkblue";
    box.style.padding = "20px";
    box.style.borderRadius = "10px";
    box.style.fontSize = "18px";
}
</script>

6. Get and Set Attributes

Definition

Attributes are additional information provided to HTML elements. JavaScript provides methods to read, modify, add, or remove these attributes.

Syntax

// Get attribute value
const value = element.getAttribute("attributeName");

// Set attribute value
element.setAttribute("attributeName", "value");

// Remove attribute
element.removeAttribute("attributeName");

// Check if attribute exists
const hasAttribute = element.hasAttribute("attributeName");

Example

<!-- HTML -->
<img id="myImage" src="old-image.jpg" alt="Old Image" data-category="nature">
<button onclick="updateImage()">Update Image</button>

<script>
// JavaScript
function updateImage() {
    const img = document.getElementById("myImage");

    // Get current attributes
    console.log(img.getAttribute("src"));         // "old-image.jpg"
    console.log(img.getAttribute("data-category")); // "nature"

    // Set new attributes
    img.setAttribute("src", "new-image.jpg");
    img.setAttribute("alt", "New Image");
    img.setAttribute("data-category", "landscape");
}
</script>

7. Select Multiple Elements and Loop Through Them

Definition

Methods like querySelectorAll(), getElementsByClassName(), and getElementsByTagName() return collections of elements that can be iterated over using loops.

Syntax

// Select multiple elements
const elements = document.querySelectorAll("selector");
const elementsByClass = document.getElementsByClassName("className");
const elementsByTag = document.getElementsByTagName("tagName");

// Loop methods
// 1. forEach (only works with NodeList from querySelectorAll)
elements.forEach(element => { /* code */ });

// 2. for...of loop (works with both NodeList and HTMLCollection)
for (const element of elements) { /* code */ }

// 3. traditional for loop
for (let i = 0; i < elements.length; i++) { /* code */ }

Example

<!-- HTML -->
<ul>
    <li class="item">Item 1</li>
    <li class="item">Item 2</li>
    <li class="item">Item 3</li>
</ul>
<button onclick="highlightItems()">Highlight All Items</button>

<script>
// JavaScript
function highlightItems() {
    const items = document.querySelectorAll(".item");

    // Using forEach
    items.forEach((item, index) => {
        item.style.backgroundColor = "yellow";
        item.style.fontWeight = "bold";
        item.textContent += ` (Highlighted ${index + 1})`;
    });
}
</script>

8. innerHTML

Definition

innerHTML gets or sets the HTML content inside an element. Unlike textContent, it can parse and render HTML tags.

Syntax

// Get HTML content
const htmlContent = element.innerHTML;

// Set HTML content
element.innerHTML = "<p>New HTML content</p>";

// Append HTML content
element.innerHTML += "<span>Additional content</span>";

Security Note

Be careful with innerHTML when using user input, as it can lead to XSS attacks. Use textContent for plain text.

Example

<!-- HTML -->
<div id="container">
    <p>Original content</p>
</div>
<button onclick="updateHTML()">Update HTML</button>

<script>
// JavaScript
function updateHTML() {
    const container = document.getElementById("container");

    // Get current HTML
    console.log(container.innerHTML); // "<p>Original content</p>"

    // Set new HTML content
    container.innerHTML = `
        <h2>New Title</h2>
        <p>This is <strong>bold</strong> text</p>
        <ul>
            <li>Item 1</li>
            <li>Item 2</li>
        </ul>
    `;
}
</script>

9. DOM Tree, Root Node, Element Nodes, Text Nodes

Definition

The DOM (Document Object Model) represents HTML as a tree structure where each part of the document is a node. Understanding this hierarchy is crucial for DOM navigation.

Node Types

  • Document Node: The root of the entire document

  • Element Nodes: HTML tags like <div>, <p>, <span>

  • Text Nodes: The actual text content inside elements

  • Attribute Nodes: Attributes of HTML elements

Syntax

// Access the root document node
const rootNode = document.getRootNode();

// Access HTML element (document element)
const htmlElement = document.documentElement;

// Access body element
const bodyElement = document.body;

// Node relationships
const parent = element.parentNode;
const children = element.childNodes;      // Includes text nodes
const elementChildren = element.children; // Only element nodes
const firstChild = element.firstChild;
const lastChild = element.lastChild;
const nextSibling = element.nextSibling;
const previousSibling = element.previousSibling;

Example

<!-- HTML -->
<div id="parent">
    <h1>Title</h1>
    Some text content
    <p>Paragraph</p>
</div>

<script>
// JavaScript
const parent = document.getElementById("parent");

console.log("Child nodes (includes text):", parent.childNodes.length); // 5 nodes
console.log("Element children only:", parent.children.length);          // 2 elements

// Navigate the DOM tree
const firstElement = parent.children[0]; // <h1>
const paragraph = parent.children[1];    // <p>

console.log("First element:", firstElement.tagName);  // "H1"
console.log("Its parent:", firstElement.parentNode.id); // "parent"
</script>

10. classList

Definition

classList is a property that provides methods to manipulate CSS classes on an element. It's more convenient than directly modifying the className property.

Syntax

// Add class
element.classList.add("className");

// Remove class
element.classList.remove("className");

// Toggle class (add if not present, remove if present)
element.classList.toggle("className");

// Check if class exists
const hasClass = element.classList.contains("className");

// Replace one class with another
element.classList.replace("oldClass", "newClass");

// Get all classes as array
const classArray = Array.from(element.classList);

Example

<!-- HTML -->
<style>
    .highlight { background-color: yellow; }
    .large-text { font-size: 20px; }
    .hidden { display: none; }
</style>

<div id="myDiv" class="original-class">Click the button to toggle styles</div>
<button onclick="toggleStyles()">Toggle Styles</button>

<script>
// JavaScript
function toggleStyles() {
    const div = document.getElementById("myDiv");

    // Toggle multiple classes
    div.classList.toggle("highlight");
    div.classList.toggle("large-text");

    // Check if class exists
    if (div.classList.contains("highlight")) {
        console.log("Element is highlighted!");
    }

    // Add class conditionally
    if (div.textContent.includes("Click")) {
        div.classList.add("interactive");
    }
}
</script>

11. Add New Elements to Page

Definition

There are multiple ways to add new elements to a webpage: innerHTML, createElement() with appendChild(), and insertAdjacentHTML().

Syntax

// Method 1: innerHTML (simple but replaces existing content)
element.innerHTML += "<p>New paragraph</p>";

// Method 2: createElement + appendChild (more control, better performance)
const newElement = document.createElement("tagName");
newElement.textContent = "Content";
parentElement.appendChild(newElement);

// Method 3: insertAdjacentHTML (flexible positioning)
element.insertAdjacentHTML("position", "<p>New content</p>");
// Positions: "beforebegin", "afterbegin", "beforeend", "afterend"

Example

<!-- HTML -->
<div id="container">
    <h2>Existing Content</h2>
</div>
<button onclick="addElements()">Add Elements</button>

<script>
// JavaScript
function addElements() {
    const container = document.getElementById("container");

    // Method 1: innerHTML
    container.innerHTML += "<p>Added with innerHTML</p>";

    // Method 2: createElement
    const newDiv = document.createElement("div");
    newDiv.textContent = "Added with createElement";
    newDiv.style.color = "blue";
    container.appendChild(newDiv);

    // Method 3: insertAdjacentHTML
    container.insertAdjacentHTML("beforeend", "<span>Added with insertAdjacentHTML</span>");
}
</script>

12. Create Elements

Definition

createElement() creates a new HTML element that exists in memory but isn't yet part of the document. You must append it to the DOM to make it visible.

Syntax

// Create element
const element = document.createElement("tagName");

// Set properties
element.textContent = "Text content";
element.innerHTML = "<strong>HTML content</strong>";
element.id = "elementId";
element.className = "className";

// Set attributes
element.setAttribute("data-value", "123");

// Add to DOM
parentElement.appendChild(element);

Example

<!-- HTML -->
<div id="todoList"></div>
<input type="text" id="todoInput" placeholder="Enter todo">
<button onclick="addTodo()">Add Todo</button>

<script>
// JavaScript
function addTodo() {
    const input = document.getElementById("todoInput");
    const todoList = document.getElementById("todoList");

    if (input.value.trim() === "") return;

    // Create new todo item
    const todoItem = document.createElement("div");
    todoItem.className = "todo-item";
    todoItem.style.padding = "10px";
    todoItem.style.border = "1px solid #ccc";
    todoItem.style.margin = "5px 0";

    // Create text span
    const todoText = document.createElement("span");
    todoText.textContent = input.value;

    // Create delete button
    const deleteBtn = document.createElement("button");
    deleteBtn.textContent = "Delete";
    deleteBtn.onclick = () => todoItem.remove();

    // Assemble todo item
    todoItem.appendChild(todoText);
    todoItem.appendChild(deleteBtn);
    todoList.appendChild(todoItem);

    // Clear input
    input.value = "";
}
</script>

13. Insert Adjacent Elements

Definition

insertAdjacentElement() and insertAdjacentHTML() provide precise control over where new content is inserted relative to an existing element.

Syntax

// Insert element
targetElement.insertAdjacentElement(position, newElement);

// Insert HTML string
targetElement.insertAdjacentHTML(position, htmlString);

// Insert text (safer than HTML)
targetElement.insertAdjacentText(position, textString);

// Positions:
// "beforebegin" - before the target element
// "afterbegin"  - inside target, before first child
// "beforeend"   - inside target, after last child  
// "afterend"    - after the target element

Position Visualization

<!-- beforebegin -->
<div id="target">
  <!-- afterbegin -->
  existing content
  <!-- beforeend -->
</div>
<!-- afterend -->

Example

<!-- HTML -->
<div id="main-content">
    <h2>Main Content</h2>
    <p>This is the main paragraph.</p>
</div>
<button onclick="insertContent()">Insert Content</button>

<script>
// JavaScript
function insertContent() {
    const mainContent = document.getElementById("main-content");

    // Insert before the entire div
    mainContent.insertAdjacentHTML("beforebegin", "<header>Header inserted before</header>");

    // Insert at the beginning inside the div
    mainContent.insertAdjacentHTML("afterbegin", "<p><em>Inserted at beginning</em></p>");

    // Insert at the end inside the div
    mainContent.insertAdjacentHTML("beforeend", "<p><strong>Inserted at end</strong></p>");

    // Insert after the entire div
    mainContent.insertAdjacentHTML("afterend", "<footer>Footer inserted after</footer>");
}
</script>

14. Clone Nodes

Definition

cloneNode() creates a copy of an existing DOM node. You can choose to make a shallow copy (element only) or deep copy (element with all children).

Syntax

// Shallow clone (element only, no children)
const shallowClone = element.cloneNode(false);

// Deep clone (element with all children and their content)
const deepClone = element.cloneNode(true);

// After cloning, you need to append it to the DOM
parentElement.appendChild(clonedElement);

Example

<!-- HTML -->
<div id="original">
    <h3>Original Card</h3>
    <p>This is the original content</p>
    <button onclick="alert('Original button clicked')">Original Button</button>
</div>
<button onclick="cloneCard()">Clone Card</button>

<script>
// JavaScript
function cloneCard() {
    const original = document.getElementById("original");

    // Deep clone the entire card with all its children
    const clone = original.cloneNode(true);

    // Modify the clone to make it different
    clone.id = "clone-" + Date.now(); // Give unique ID
    const cloneTitle = clone.querySelector("h3");
    cloneTitle.textContent = "Cloned Card";

    const cloneButton = clone.querySelector("button");
    cloneButton.onclick = () => alert("Cloned button clicked");
    cloneButton.textContent = "Cloned Button";

    // Add some styling to distinguish the clone
    clone.style.border = "2px solid blue";
    clone.style.margin = "10px";
    clone.style.padding = "10px";

    // Append the clone to the document
    document.body.appendChild(clone);
}
</script>

Summary

These DOM manipulation techniques form the foundation of interactive web development:

  1. Selection: Use getElementById() and querySelector() to find elements

  2. Content: Modify text with textContent/innerText and HTML with innerHTML

  3. Styling: Change appearance with style property and classList methods

  4. Attributes: Read and modify element attributes with getAttribute()/setAttribute()

  5. Creation: Build new elements with createElement() and add them with appendChild()

  6. Positioning: Use insertAdjacentHTML() for precise placement

  7. Duplication: Clone existing elements with cloneNode()

Understanding these concepts enables you to create dynamic, interactive web applications that respond to user input and update content without page reloads.

8
Subscribe to my newsletter

Read articles from Code Subtle directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Code Subtle
Code Subtle

At Code Subtle, we empower aspiring web developers through personalized mentorship and engaging learning resources. Our community bridges the gap between theory and practice, guiding students from basics to advanced concepts. We offer expert mentorship and write interactive, user-friendly articles on all aspects of web development. Join us to learn, grow, and build your future in tech!