JavaScript DOM Manipulation: A Practical Guide
The Document Object Model (DOM) is a programming interface that represents HTML as a tree of objects. JavaScript can interact with this tree to change the content, structure, and style of web pages dynamically.
Selecting Elements
getElementById
Select a single element by its ID:
const title = document.getElementById('title');
querySelector
Select the first element matching a CSS selector:
const button = document.querySelector('.btn');
const firstParagraph = document.querySelector('p');
const navLink = document.querySelector('nav a.active');
querySelectorAll
Select all elements matching a CSS selector (returns NodeList):
const allButtons = document.querySelectorAll('.btn');
const allParagraphs = document.querySelectorAll('p');// Loop through NodeList
allButtons.forEach(button => {
console.log(button.textContent);
});
Other Selection Methods
// By class name (returns HTMLCollection)
const items = document.getElementsByClassName('item');// By tag name (returns HTMLCollection)
const divs = document.getElementsByTagName('div');
Modifying Content
textContent vs innerHTML
const element = document.getElementById('content');// textContent - plain text (safer)
element.textContent = 'Hello, World!';
// innerHTML - can include HTML (be careful with user input!)
element.innerHTML = 'Hello, World!';
// innerText - similar to textContent, respects CSS hiding
element.innerText = 'Visible text only';
Modifying Attributes
const link = document.querySelector('a');// Get attribute
const href = link.getAttribute('href');
// Set attribute
link.setAttribute('href', 'https://proliveeditor.com');
link.setAttribute('target', '_blank');
// Remove attribute
link.removeAttribute('target');
// Direct property access (for standard attributes)
link.href = 'https://proliveeditor.com';
link.id = 'main-link';
Working with Classes
const element = document.querySelector('.card');// Add class
element.classList.add('active');
// Remove class
element.classList.remove('hidden');
// Toggle class
element.classList.toggle('expanded');
// Check if class exists
if (element.classList.contains('active')) {
console.log('Element is active');
}
// Replace class
element.classList.replace('old-class', 'new-class');
Modifying Styles
const box = document.querySelector('.box');// Direct style modification
box.style.backgroundColor = 'blue';
box.style.padding = '20px';
box.style.borderRadius = '8px';
// Multiple styles at once
Object.assign(box.style, {
backgroundColor: 'blue',
padding: '20px',
borderRadius: '8px'
});
// Get computed styles
const styles = getComputedStyle(box);
console.log(styles.backgroundColor);
Creating and Removing Elements
Creating Elements
// Create a new element
const newDiv = document.createElement('div');
newDiv.textContent = 'I am new!';
newDiv.className = 'new-element';// Add to the page
document.body.appendChild(newDiv);
// Insert at specific position
const container = document.querySelector('.container');
container.appendChild(newDiv);
// Insert before another element
const reference = document.querySelector('.reference');
container.insertBefore(newDiv, reference);
Modern Insertion Methods
const element = document.querySelector('.target');// Insert adjacent HTML
element.insertAdjacentHTML('beforebegin', '
Before element
');
element.insertAdjacentHTML('afterbegin', 'First child
');
element.insertAdjacentHTML('beforeend', 'Last child
');
element.insertAdjacentHTML('afterend', 'After element
');// Insert adjacent element
const newElement = document.createElement('span');
element.insertAdjacentElement('afterend', newElement);
Removing Elements
const elementToRemove = document.querySelector('.remove-me');// Modern way
elementToRemove.remove();
// Old way (still works)
elementToRemove.parentNode.removeChild(elementToRemove);
Event Handling
addEventListener
const button = document.querySelector('.btn');button.addEventListener('click', function(event) {
console.log('Button clicked!');
console.log('Event:', event);
console.log('Target:', event.target);
});
// Arrow function
button.addEventListener('click', (e) => {
e.preventDefault(); // Prevent default action
console.log('Clicked!');
});
Common Events
// Mouse events
element.addEventListener('click', handler);
element.addEventListener('dblclick', handler);
element.addEventListener('mouseenter', handler);
element.addEventListener('mouseleave', handler);// Keyboard events
element.addEventListener('keydown', handler);
element.addEventListener('keyup', handler);
// Form events
input.addEventListener('input', handler);
input.addEventListener('change', handler);
input.addEventListener('focus', handler);
input.addEventListener('blur', handler);
form.addEventListener('submit', handler);
// Window events
window.addEventListener('load', handler);
window.addEventListener('resize', handler);
window.addEventListener('scroll', handler);
Event Delegation
Handle events on dynamically created elements:
const list = document.querySelector('.list');// Instead of adding listeners to each item...
list.addEventListener('click', (e) => {
if (e.target.matches('.list-item')) {
console.log('Clicked item:', e.target.textContent);
}
});
Practical Example: Todo List
Try building this in ProLiveEditor:
Todo List
.todo-app {
max-width: 400px;
margin: 20px auto;
padding: 20px;
background: #f9f9f9;
border-radius: 8px;
}#todo-form {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
#todo-input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 10px 20px;
background: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.todo-item {
display: flex;
justify-content: space-between;
padding: 10px;
background: white;
margin-bottom: 5px;
border-radius: 4px;
}
.delete-btn {
background: #e74c3c;
padding: 5px 10px;
}
const form = document.getElementById('todo-form');
const input = document.getElementById('todo-input');
const list = document.getElementById('todo-list');form.addEventListener('submit', (e) => {
e.preventDefault();
if (input.value.trim()) {
addTodo(input.value);
input.value = '';
}
});
function addTodo(text) {
const li = document.createElement('li');
li.className = 'todo-item';
li.innerHTML =
${text}
;
list.appendChild(li);
}
// Event delegation for delete buttons
list.addEventListener('click', (e) => {
if (e.target.classList.contains('delete-btn')) {
e.target.parentElement.remove();
}
});
This covers the essentials of DOM manipulation. Practice these concepts in ProLiveEditor to build interactive web pages!