On this page
DOM - Selection and modification
What is the DOM?
The DOM (Document Object Model) is the in-memory representation of an HTML page's structure. JavaScript can read and modify this structure to create interactive interfaces.
The browser converts each HTML tag into a node in the DOM tree. Each node is a JavaScript object with properties and methods.
Selecting elements
The two main methods are:
querySelector(selector)— Returns the first element that matches the CSS selectorquerySelectorAll(selector)— Returns all matching elements as aNodeList
// Valid CSS selectors
document.querySelector('.class');
document.querySelector('#id');
document.querySelector('div > p:first-child');
document.querySelector('[data-role="admin"]');NodeList vs Array
querySelectorAll returns a NodeList, not an array. It supports forEach, but not map or filter. To use those methods, convert it to an array with the spread operator:
const items = [...document.querySelectorAll('.item')];DOM navigation
From any element you can navigate to its neighbors:
| Property | Returns |
|---|---|
parentElement |
Parent element |
children |
Direct children (elements) |
firstElementChild |
First child element |
lastElementChild |
Last child element |
nextElementSibling |
Next sibling |
previousElementSibling |
Previous sibling |
Modifying content
textContent— Sets plain text. Safe against XSSinnerHTML— Sets HTML content. Dangerous with user data
Modifying CSS classes
The classList property provides methods to manipulate classes:
| Method | Action |
|---|---|
add('class') |
Adds one or more classes |
remove('class') |
Removes one or more classes |
toggle('class') |
Toggles the class |
replace('old', 'new') |
Replaces a class |
contains('class') |
Checks if it exists (boolean) |
Attributes and dataset
For generic attributes use setAttribute / getAttribute. For custom data, data attributes are the standard way:
<div data-user-id="42" data-role="admin">...</div>const el = document.querySelector('[data-user-id]');
el.dataset.userId; // '42' (automatic camelCase)
el.dataset.role; // 'admin'Creating and removing elements
To add dynamic content, create elements with createElement, configure them, and then insert them into the DOM with appendChild, prepend, or insertBefore.
To remove an element, simply call element.remove().
Practice
- Select and modify elements: Use
querySelectorto select an<h1>and change itstextContent. Then select all<li>elements withquerySelectorAll, convert them to an array, and filter those that have the class'active'. - Manipulate classes and attributes: Select an element by its class, use
classList.toggleto toggle a'highlighted'class, and set a customdata-attributewithdataset. - Create elements dynamically: Create a function that receives an array of texts and generates a
<ul>with one<li>per text usingcreateElement,textContent, andappendChild. Insert it into the DOM.
In the next lesson we will learn about events and the delegation pattern.
// === SELECTING ELEMENTS ===
// querySelector - first matching element
const title = document.querySelector('h1');
const button = document.querySelector('.btn-primary');
const form = document.querySelector('#login-form');
// querySelectorAll - all matching elements (NodeList)
const items = document.querySelectorAll('.menu-item');
const paragraphs = document.querySelectorAll('article p');
// Iterating a NodeList
items.forEach(item => {
console.log(item.textContent);
});
// Convert NodeList to array (to use map, filter, etc.)
const listArray = [...document.querySelectorAll('li')];
const activeItems = listArray.filter(li =>
li.classList.contains('active')
);
// Search within an element
const nav = document.querySelector('nav');
const links = nav.querySelectorAll('a');
// Navigate the DOM
const parent = title.parentElement;
const next = title.nextElementSibling;
const children = nav.children; // HTMLCollection
// === MODIFYING CONTENT ===
const title = document.querySelector('h1');
// textContent - plain text (safe)
title.textContent = 'New title';
// innerHTML - HTML (beware of XSS!)
// title.innerHTML = '<em>Title</em> with HTML';
// === CSS CLASSES ===
const card = document.querySelector('.card');
card.classList.add('active', 'featured');
card.classList.remove('hidden');
card.classList.toggle('expanded');
card.classList.replace('old', 'new');
const isActive = card.classList.contains('active'); // true
// === ATTRIBUTES ===
const link = document.querySelector('a');
link.setAttribute('href', 'https://bemorex.com');
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'noopener noreferrer');
const url = link.getAttribute('href');
link.removeAttribute('title');
// Data attributes
const product = document.querySelector('[data-id]');
const id = product.dataset.id; // data-id
const price = product.dataset.price; // data-price
// === CREATING AND ADDING ELEMENTS ===
const list = document.querySelector('.list');
const newItem = document.createElement('li');
newItem.textContent = 'New item';
newItem.classList.add('item');
// Different positions
list.appendChild(newItem); // at the end
list.prepend(newItem); // at the start
list.insertBefore(newItem, list.children[2]); // before the 3rd
// Remove
newItem.remove();
Sign in to track your progress