Skip to content

L67 - Seleccionar y Manipular el DOM

Para trabajar con el DOM necesitamos dos pasos: seleccionar elementos y luego manipularlos (cambiar su contenido, atributos, clases o estilos).

Los métodos más modernos y flexibles. Aceptan cualquier selector CSS.

// Selecciona el PRIMER elemento que coincida
const header = document.querySelector('header');
const boton = document.querySelector('.btn-primary');
const primerItem = document.querySelector('#lista li:first-child');
// Selecciona TODOS los elementos que coincidan (NodeList estática)
const items = document.querySelectorAll('.item');
const celdas = document.querySelectorAll('table td');
// Se puede iterar directamente con forEach
items.forEach(item => {
console.log(item.textContent);
});

El más rápido para seleccionar por ID:

const logo = document.getElementById('logo');
// Equivale a: document.querySelector('#logo')

⚠️ querySelectorAll devuelve una NodeList (estática). getElementsByClassName o getElementsByTagName devuelven HTMLCollection (viva, se actualiza automáticamente si el DOM cambia).

// HTMLCollection viva vs NodeList estática
const divsVivos = document.getElementsByTagName('div'); // se actualiza solo
const divsEstaticos = document.querySelectorAll('div'); // no cambia

Interpreta el contenido como HTML (peligroso si incluye datos del usuario):

const div = document.querySelector('#contenido');
// Interpreta etiquetas HTML
div.innerHTML = '<strong>Texto en negrita</strong>';
// Resultado: Texto en negrita (en negrita visualmente)
// ⚠️ Peligro: XSS si el contenido viene del usuario
const usuario = '<script>alert("hackeado")</script>';
div.innerHTML = usuario; // ¡Ejecuta el script!

Trata todo como texto plano (seguro):

div.textContent = '<strong>Texto en negrita</strong>';
// Resultado: <strong>Texto en negrita</strong> (se ve literal)
// Seguro con input del usuario
const comentario = '<script>alert("xss")</script>';
div.textContent = comentario; // Se muestra como texto, no se ejecuta
innerHTMLtextContent
Interpreta HTML✅ Sí❌ No
Seguridad⚠️ Riesgo XSS✅ Seguro
RendimientoMás lento (parsea HTML)Más rápido
Caso de usoCuando necesitas HTMLCuando solo quieres texto
const link = document.querySelector('a');
// Establecer atributos
link.setAttribute('href', 'https://ejemplo.com');
link.setAttribute('target', '_blank');
// Leer atributos
console.log(link.getAttribute('href'));
// Verificar si existe
console.log(link.hasAttribute('target')); // true
// Eliminar
link.removeAttribute('target');
// Atributos data-* (dataset)
link.dataset.id = '123';
link.dataset.tipo = 'externo';
console.log(link.dataset); // { id: '123', tipo: 'externo' }

Algunos atributos tienen su propiedad correspondiente en el objeto DOM:

const input = document.querySelector('input');
// Atributo (HTML)
input.setAttribute('value', 'texto inicial');
// Propiedad (JavaScript, valor actual)
input.value = 'texto modificado';
// ⚠️ No siempre se sincronizan
console.log(input.getAttribute('value')); // 'texto inicial'
console.log(input.value); // 'texto modificado'

La forma moderna de manejar clases CSS:

const elemento = document.querySelector('.mi-elemento');
// Añadir clase
elemento.classList.add('activo');
// Quitar clase
elemento.classList.remove('inactivo');
// Alternar (toggle)
elemento.classList.toggle('visible');
// Reemplazar
elemento.classList.replace('old-class', 'new-class');
// Verificar si tiene una clase
console.log(elemento.classList.contains('activo')); // true
// Múltiples clases a la vez
elemento.classList.add('clase1', 'clase2', 'clase3');
// ⚠️ className sobrescribe TODAS las clases
elemento.className = 'nueva-clase';
// Para añadir sin perder las existentes
elemento.className += ' otra-clase';

Manipular estilos en línea (equivalente al atributo style en HTML):

const caja = document.querySelector('.caja');
// Propiedades individuales (camelCase en JS)
caja.style.backgroundColor = 'blue';
caja.style.fontSize = '18px';
caja.style.border = '2px solid red';
// Propiedades con prefijo
caja.style.webkitTransform = 'rotate(45deg)'; // -webkit-transform
// Leer estilos computados (no los de style)
const estilos = getComputedStyle(caja);
console.log(estilos.backgroundColor); // rgb(0, 0, 255)
console.log(estilos.fontSize); // 18px
// Varias propiedades de una vez
caja.style.cssText = 'background: red; color: white; padding: 20px;';
// ⚠️ Esto SOBRESCRIBE todos los estilos en línea previos
// Seleccionar
const tarjeta = document.querySelector('.tarjeta');
const titulo = tarjeta.querySelector('.titulo');
const descripcion = tarjeta.querySelector('.descripcion');
// Manipular contenido
titulo.textContent = 'Nuevo título';
descripcion.innerHTML = 'Contenido con <strong>negrita</strong>';
// Clases
tarjeta.classList.add('destacado', 'animado');
tarjeta.classList.remove('antiguo');
// Atributos
tarjeta.setAttribute('data-id', '42');
tarjeta.dataset.status = 'activo';
// Estilos
tarjeta.style.borderRadius = '8px';
tarjeta.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';

🎯 Regla de oro: usa querySelector/querySelectorAll para seleccionar (son los más versátiles), textContent para texto plano (más seguro), classList para clases y style.propiedad para estilos en línea puntuales.