El DOM: seleccionar y manipular elementos
Aprende a seleccionar elementos del DOM, leer y cambiar su contenido, atributos y estilos, y crear o eliminar nodos dinámicamente.
El DOM (Document Object Model) es la representación en memoria de la página HTML que el navegador construye al cargar el documento. JavaScript lo usa para leer, modificar y crear elementos en tiempo real sin recargar la página.
Seleccionar elementos
// Un solo elemento — devuelve el primero que coincide o null
document.querySelector('.card')
document.querySelector('#header')
document.querySelector('input[type="email"]')
// Todos los elementos — devuelve NodeList (iterable)
document.querySelectorAll('.card')
document.querySelectorAll('li')
// Métodos clásicos (siguen siendo útiles)
document.getElementById('header') // por ID — el más rápido
document.getElementsByClassName('card') // HTMLCollection viva
querySelector y querySelectorAll aceptan cualquier selector CSS válido. Son los más usados en código moderno.
// Buscar dentro de un elemento (no en todo el documento)
const form = document.querySelector('#formulario');
const inputs = form.querySelectorAll('input'); // solo inputs dentro del form
Leer y modificar contenido
const titulo = document.querySelector('h1');
// Texto plano — seguro, no interpreta HTML
titulo.textContent // leer
titulo.textContent = 'Nuevo título' // escribir
// HTML interno — interpreta etiquetas (cuidado con XSS)
titulo.innerHTML // leer
titulo.innerHTML = '<span>Nuevo</span> título' // escribir
// Valor de inputs y selects
const input = document.querySelector('input');
input.value // leer valor actual
input.value = '' // limpiar
Nunca uses
innerHTMLcon datos que vengan del usuario sin sanitizar. Es la principal puerta de entrada a ataques XSS. Para texto sin etiquetas, usa siempretextContent.
Leer y modificar atributos
const enlace = document.querySelector('a');
enlace.getAttribute('href') // leer cualquier atributo
enlace.setAttribute('href', '/nueva') // escribir
enlace.removeAttribute('disabled') // eliminar
enlace.hasAttribute('disabled') // boolean
// Atributos estándar como propiedades directas
enlace.href
enlace.id
enlace.className
// Atributos data-*
const el = document.querySelector('[data-id]');
el.dataset.id // lee data-id
el.dataset.userId // lee data-user-id (camelCase automático)
el.dataset.id = '5' // escribe
Clases
const caja = document.querySelector('.caja');
caja.classList.add('activo') // añadir
caja.classList.remove('activo') // quitar
caja.classList.toggle('activo') // si está la quita, si no la añade
caja.classList.contains('activo') // boolean
caja.classList.replace('old', 'new') // reemplazar
// toggle con fuerza (true = añadir, false = quitar)
caja.classList.toggle('visible', condicion)
Estilos
const caja = document.querySelector('.caja');
// Estilos inline (directos en el elemento)
caja.style.backgroundColor = '#ff0000' // camelCase
caja.style.display = 'none'
caja.style.setProperty('--color', 'red') // variables CSS
// Leer el estilo calculado (incluyendo lo que viene de CSS)
const estilos = getComputedStyle(caja);
estilos.getPropertyValue('background-color') // '#ff0000'
estilos.getPropertyValue('--color') // variables CSS
Crear y eliminar elementos
// Crear
const li = document.createElement('li');
li.textContent = 'Nuevo elemento';
li.classList.add('lista__item');
// Insertar
const ul = document.querySelector('ul');
ul.appendChild(li) // al final
ul.prepend(li) // al principio
ul.insertBefore(li, ul.children[2]) // antes de un elemento
// Métodos modernos — muy expresivos
ul.append(li) // al final (acepta strings también)
ul.before(li) // antes del propio ul (hermano)
ul.after(li) // después del propio ul (hermano)
const referencia = document.querySelector('.referencia');
referencia.insertAdjacentElement('beforebegin', li) // antes del elemento
referencia.insertAdjacentElement('afterbegin', li) // primer hijo
referencia.insertAdjacentElement('beforeend', li) // último hijo
referencia.insertAdjacentElement('afterend', li) // después del elemento
// Eliminar
li.remove() // elimina el propio elemento
ul.removeChild(li) // forma clásica
// Clonar
const clon = li.cloneNode(true) // true = clonar también los hijos
Recorrer el DOM
const el = document.querySelector('.card');
// Relaciones familiares
el.parentElement // padre
el.children // hijos (solo elementos, no texto)
el.firstElementChild // primer hijo elemento
el.lastElementChild // último hijo elemento
el.nextElementSibling // hermano siguiente
el.previousElementSibling // hermano anterior
// Iterar hijos
for (const hijo of el.children) {
console.log(hijo.tagName);
}
// NodeList de querySelectorAll es iterable
document.querySelectorAll('li').forEach(li => {
li.classList.add('procesado');
});
En la siguiente lección aprendemos a reaccionar a lo que hace el usuario: el sistema de eventos del navegador.