Advanced JavaScript - DOM Manipulation

Table of contents
- Complete DOM Manipulation Guide
- 1. Async vs Defer
- 2. Select Elements Using ID
- 3. querySelector
- 4. textContent & innerText
- 5. Change the Styles of Elements Using JS
- 6. Get and Set Attributes
- 7. Select Multiple Elements and Loop Through Them
- 8. innerHTML
- 9. DOM Tree, Root Node, Element Nodes, Text Nodes
- 10. classList
- 11. Add New Elements to Page
- 12. Create Elements
- 13. Insert Adjacent Elements
- 14. Clone Nodes
- Summary

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:
Selection: Use
getElementById()
andquerySelector()
to find elementsContent: Modify text with
textContent
/innerText
and HTML withinnerHTML
Styling: Change appearance with
style
property andclassList
methodsAttributes: Read and modify element attributes with
getAttribute()
/setAttribute()
Creation: Build new elements with
createElement()
and add them withappendChild()
Positioning: Use
insertAdjacentHTML()
for precise placementDuplication: 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.
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!