DOM Manipulation
Learn how to interact with and modify web pages using JavaScript and the Document Object Model (DOM).
What is the DOM?
The DOM (Document Object Model) is a representation of your HTML page that JavaScript can interact with. It's like a tree structure of all the elements on your page.
DOM Tree Structure
Document (root)
└── html
├── head
│ ├── title
│ └── meta
└── body
├── h1
├── p
└── div
└── button
Selecting Elements
getElementById
Select element by ID:
const header = document.getElementById('header');
HTML:
<div id="header">Header Content</div>
querySelector
Select first matching element (modern, recommended):
const button = document.querySelector('.my-button');
const header = document.querySelector('#header');
const paragraph = document.querySelector('p');
querySelectorAll
Select all matching elements:
const paragraphs = document.querySelectorAll('p');
const buttons = document.querySelectorAll('.button');
Returns a NodeList (array-like object).
Other Selection Methods
// Get elements by class name
const items = document.getElementsByClassName('item');
// Get elements by tag name
const divs = document.getElementsByTagName('div');
Modifying Content
textContent
Get or set text content:
const heading = document.querySelector('h1');
heading.textContent = 'New Heading';
console.log(heading.textContent); // 'New Heading'
innerHTML
Get or set HTML content:
const div = document.querySelector('.content');
div.innerHTML = '<p>New paragraph</p>';
!!! warning "Security Risk"
innerHTML can be dangerous if used with user input. Use textContent for user-generated content.
innerText
Get or set visible text (respects CSS):
const element = document.querySelector('p');
element.innerText = 'New text';
Modifying Attributes
getAttribute / setAttribute
const link = document.querySelector('a');
// Get attribute
const href = link.getAttribute('href');
// Set attribute
link.setAttribute('href', 'https://example.com');
link.setAttribute('target', '_blank');
Direct Property Access
const image = document.querySelector('img');
// Set properties
image.src = 'new-image.jpg';
image.alt = 'New image';
image.width = 300;
Modifying Styles
style Property
Change CSS styles:
const element = document.querySelector('.box');
element.style.color = 'red';
element.style.backgroundColor = 'blue';
element.style.fontSize = '20px';
element.style.display = 'none';
Note: Use camelCase for CSS properties (backgroundColor not background-color).
classList
Add, remove, or toggle CSS classes:
const button = document.querySelector('button');
// Add class
button.classList.add('active');
// Remove class
button.classList.remove('active');
// Toggle class
button.classList.toggle('active');
// Check if has class
if (button.classList.contains('active')) {
console.log('Button is active');
}
Creating Elements
createElement
Create new HTML elements:
const newParagraph = document.createElement('p');
newParagraph.textContent = 'This is a new paragraph';
appendChild
Add element to page:
const container = document.querySelector('.container');
const newDiv = document.createElement('div');
newDiv.textContent = 'New div';
container.appendChild(newDiv);
insertBefore
Insert element before another:
const container = document.querySelector('.container');
const newDiv = document.createElement('div');
const existingDiv = document.querySelector('.existing');
container.insertBefore(newDiv, existingDiv);
removeChild
Remove element:
const element = document.querySelector('.to-remove');
element.parentNode.removeChild(element);
// Modern way (ES6+)
element.remove();
Complete Examples
Change Text Content
<h1 id="title">Original Title</h1>
<button onclick="changeTitle()">Change Title</button>
<script>
function changeTitle() {
const title = document.getElementById('title');
title.textContent = 'New Title';
}
</script>
Add New Element
<div id="container"></div>
<button onclick="addItem()">Add Item</button>
<script>
function addItem() {
const container = document.getElementById('container');
const newItem = document.createElement('div');
newItem.textContent = 'New Item';
newItem.className = 'item';
container.appendChild(newItem);
}
</script>
Toggle Visibility
<div id="content">This content can be hidden</div>
<button onclick="toggleContent()">Toggle</button>
<script>
function toggleContent() {
const content = document.getElementById('content');
if (content.style.display === 'none') {
content.style.display = 'block';
} else {
content.style.display = 'none';
}
}
// Better way using classList
function toggleContent() {
const content = document.getElementById('content');
content.classList.toggle('hidden');
}
</script>
<style>
.hidden {
display: none;
}
</style>
Change Multiple Elements
<p class="text">Paragraph 1</p>
<p class="text">Paragraph 2</p>
<p class="text">Paragraph 3</p>
<button onclick="changeAll()">Change All</button>
<script>
function changeAll() {
const paragraphs = document.querySelectorAll('.text');
paragraphs.forEach(p => {
p.style.color = 'blue';
p.style.fontSize = '20px';
});
}
</script>
Dynamic List
<ul id="list"></ul>
<input type="text" id="itemInput" placeholder="Add item">
<button onclick="addListItem()">Add</button>
<script>
function addListItem() {
const input = document.getElementById('itemInput');
const list = document.getElementById('list');
if (input.value.trim() !== '') {
const li = document.createElement('li');
li.textContent = input.value;
list.appendChild(li);
input.value = ''; // Clear input
}
}
</script>
Traversing the DOM
parentNode
Get parent element:
const child = document.querySelector('.child');
const parent = child.parentNode;
children
Get child elements:
const container = document.querySelector('.container');
const children = container.children;
nextSibling / previousSibling
Get adjacent elements:
const element = document.querySelector('.middle');
const next = element.nextSibling;
const previous = element.previousSibling;
Best Practices
- Cache selections: Store selected elements in variables
- Use querySelector: Modern and flexible
- Prefer classList: Over direct style manipulation
- Use textContent: For user-generated content (security)
- Check if element exists: Before manipulating
- Use event delegation: For dynamic content
Common Mistakes
1. Not Waiting for DOM to Load
// ❌ Wrong
const element = document.getElementById('myElement');
element.textContent = 'Hello'; // Element might not exist yet
// ✅ Correct
document.addEventListener('DOMContentLoaded', function() {
const element = document.getElementById('myElement');
element.textContent = 'Hello';
});
2. Using innerHTML with User Input
// ❌ Wrong - Security risk!
const userInput = '<script>alert("XSS")</script>';
element.innerHTML = userInput;
// ✅ Correct
element.textContent = userInput;
3. Selecting Non-Existent Elements
// ❌ Wrong
const element = document.getElementById('nonexistent');
element.textContent = 'Hello'; // Error!
// ✅ Correct
const element = document.getElementById('nonexistent');
if (element) {
element.textContent = 'Hello';
}
Practice Exercise
Create a page with:
- A heading that changes when a button is clicked
- A button that adds new paragraphs to a container
- A button that toggles a div's visibility
- An input field that adds items to a list
- Buttons that change text color of all paragraphs
- A counter that increments when clicked
What's Next?
Now that you can manipulate the DOM, learn to:
- Handle Events - Respond to clicks, inputs, and other user actions
- Form Validation - Validate user input
- Create Interactive UIs - Build dynamic user interfaces
- Work with APIs - Fetch and display data
Previous Tutorial: Control Flow
Next Tutorial: Events and Interactivity