JavaScript DOM Manipulation
Select, edit, style, and create DOM elements with vanilla JavaScript and handle user events.
TL;DR
- Select elements with
querySelector()andgetElementById()before reading or editing them. - Edit content with
textContent, and toggle styles withclassList. - Attach
addEventListener()to respond to clicks and other user actions.
Selecting Elements and Editing Content
getElementById()Faster than querySelector, but only matches by unique ID.
document.getElementById('title');querySelector()Finds the first element that matches any valid CSS selector.
document.querySelector('.btn');querySelectorAll()Gets every matching element as a static NodeList for looping.
document.querySelectorAll('.item');NodeList methodsSupports forEach; use Array.from() for full array methods.
Array.from(els).map(e => e.textContent);textContentEscapes everything assigned, unlike innerHTML.
title.textContent = 'New Title';innerHTMLInserts HTML markup; use only with trusted content.
title.innerHTML = '<em>New Title</em>';insertAdjacentHTML()Inserts markup at a position without replacing existing content.
list.insertAdjacentHTML('beforeend', h);Template literalsEmbed values in markup cleanly.
el.innerHTML = `<em>${n}</em> online`;Styling Elements
Inline stylesWork well for one-off changes, but classList methods scale better overall.
btn.style.backgroundColor = 'tomato';classList.add()Adds a CSS class to the element for cleaner styling control.
btn.classList.add('active');classList.toggle()Toggles a class on and off with a single method call.
btn.classList.toggle('highlight');classList.remove()Removes a class when the state changes back to normal.
btn.classList.remove('active');Creating and Removing
createElement()Builds a new element that isn't yet attached to the DOM.
const newDiv = document.createElement('div');
newDiv.textContent = 'Hello!';appendChild() / append()Inserts the new element into the DOM; append() also accepts strings and multiple arguments.
document.body.appendChild(newDiv);remove()Removes an element from the DOM by calling remove() on it directly.
newDiv.remove();insertBefore() / prepend()Use these to control the exact position where new elements land.
list.prepend(newItem); // inserts firstTraversing the DOM
parentElementAccesses the direct parent of the current element, or null.
const parent = btn.parentElement;childrenAccesses all direct children of an element as a live HTMLCollection.
const items = list.children; // live collectionSibling propertiesMove to the next or previous sibling at the same level.
const next = el.nextElementSibling;
const prev = el.previousElementSibling;closest()Finds the nearest matching ancestor starting from any element, or null.
const card = btn.closest('.card');Tips
- Use
textContentinstead ofinnerHTMLwhen inserting user-provided text, since it prevents HTML injection and runs faster. - Attach one
addEventListener()call to a parent element instead of many on children, so new elements work automatically through delegation.
Warnings
- Adding many elements one by one causes slow page reflows, so use a
DocumentFragmentfor batch inserts in large lists. - Setting
innerHTMLwith untrusted or user-supplied content opens the door to script injection, so sanitize it or usetextContentinstead.
In Practice
Creates new list items dynamically and uses one delegated click listener on the parent to handle removal for every item.
- addTodo() creates a list item and appends a Remove button with createElement().
- One listener on the parent handles clicks for current and future items.
- event.target identifies the clicked button, and closest('li') finds its row.
- textContent keeps todo text separate from HTML markup.
const list = document.querySelector('#todo-list');
function addTodo(text) {
const li = document.createElement('li');
li.textContent = text;
const button = document.createElement('button');
button.textContent = 'Remove';
button.className = 'remove-btn';
li.append(button);
list.append(li);
}
list.addEventListener('click', ({ target }) => {
if (target.matches('.remove-btn')) target.closest('li').remove();
});FAQ
Use getElementById() for a known ID and querySelector() for any CSS selector, such as a class, tag, or attribute.
Use classList.add(), classList.remove(), and classList.toggle() to change classes without overwriting the existing list.
Create it with document.createElement(), set its properties, then add it with parentElement.append() or appendChild().
Listeners bind to elements that exist at setup time. Attach one to a stable parent and inspect event.target to use event delegation.