En esta página

DOM - Selección y modificación

15 min lectura TextoCap. 3 — DOM y eventos

Qué es el DOM?

El DOM (Document Object Model) es la representacion en memoria de la estructura HTML de una página. JavaScript puede leer y modificar esta estructura para crear interfaces interactivas.

El navegador convierte cada etiqueta HTML en un nodo del arbol DOM. Cada nodo es un objeto JavaScript con propiedades y métodos.

Seleccionar elementos

Los dos métodos principales son:

  • querySelector(selector) — Retorna el primer elemento que coincida con el selector CSS
  • querySelectorAll(selector) — Retorna todos los elementos como un NodeList
// Selectores CSS validos
document.querySelector('.clase');
document.querySelector('#id');
document.querySelector('div > p:first-child');
document.querySelector('[data-role="admin"]');

NodeList vs Array

querySelectorAll retorna un NodeList, no un array. Soporta forEach, pero no map ni filter. Para usar esos métodos, convertilo a array con el spread operator:

const items = [...document.querySelectorAll('.item')];

Desde cualquier elemento puedes navegar a sus vecinos:

Propiedad Retorna
parentElement Elemento padre
children Hijos directos (elementos)
firstElementChild Primer hijo elemento
lastElementChild Último hijo elemento
nextElementSibling Hermano siguiente
previousElementSibling Hermano anterior

Modificar contenido

  • textContent — Establece texto plano. Seguro contra XSS
  • innerHTML — Establece contenido HTML. Peligroso con datos del usuario

Modificar clases CSS

La propiedad classList ofrece métodos para manipular clases:

Método Accion
add('clase') Agrega una o más clases
remove('clase') Elimina una o más clases
toggle('clase') Alterna la clase
replace('vieja', 'nueva') Reemplaza una clase
contains('clase') Verifica si existe (boolean)

Atributos y dataset

Para atributos genericos usa setAttribute / getAttribute. Para datos personalizados, los data attributes son la forma estandar:

<div data-user-id="42" data-role="admin">...</div>
const el = document.querySelector('[data-user-id]');
el.dataset.userId;  // '42' (camelCase automático)
el.dataset.role;    // 'admin'

Crear y eliminar elementos

Para agregar contenido dinámico, crea elementos con createElement, configuralos, y luego insertalos en el DOM con appendChild, prepend o insertBefore.

Para eliminar un elemento, simplemente llama element.remove().


Práctica

  1. Selecciona y modifica elementos: Usa querySelector para seleccionar un <h1> y cambia su textContent. Luego selecciona todos los <li> con querySelectorAll, conviertelos a array y filtra los que tienen la clase 'activo'.
  2. Manipula clases y atributos: Selecciona un elemento por su clase, usa classList.toggle para alternar una clase 'destacado', y establece un data-attribute personalizado con dataset.
  3. Crea elementos dinamicamente: Crea una funcion que reciba un array de textos y genere un <ul> con un <li> por cada texto usando createElement, textContent y appendChild. Insertalo en el DOM.

En la siguiente leccion aprenderemos sobre eventos y el patrón de delegación.

Evita innerHTML cuando sea posible
Usar innerHTML con contenido del usuario puede causar ataques XSS (Cross-Site Scripting). Prefiere textContent para texto plano y createElement para elementos nuevos.
dataset para datos personalizados
Usa data attributes (data-id, data-precio) para almacenar datos personalizados en elementos HTML. Accedelos con element.dataset.nombre sin el prefijo data-.
javascript
// === SELECCION DE ELEMENTOS ===

// querySelector - primer elemento que coincida
const título = document.querySelector('h1');
const boton = document.querySelector('.btn-primary');
const formulario = document.querySelector('#login-form');

// querySelectorAll - todos los que coincidan (NodeList)
const items = document.querySelectorAll('.menu-item');
const párrafos = document.querySelectorAll('article p');

// Iterar NodeList
items.forEach(item => {
  console.log(item.textContent);
});

// Convertir NodeList a array (para usar map, filter, etc.)
const listaArray = [...document.querySelectorAll('li')];
const activos = listaArray.filter(li =>
  li.classList.contains('activo')
);

// Buscar dentro de un elemento
const nav = document.querySelector('nav');
const enlaces = nav.querySelectorAll('a');

// Navegar el DOM
const padre = título.parentElement;
const siguiente = título.nextElementSibling;
const hijos = nav.children; // HTMLCollection
javascript
// === MODIFICAR CONTENIDO ===
const título = document.querySelector('h1');

// textContent - texto plano (seguro)
título.textContent = 'Nuevo título';

// innerHTML - HTML (cuidado con XSS!)
// título.innerHTML = '<em>Título</em> con HTML';

// === CLASES CSS ===
const card = document.querySelector('.card');

card.classList.add('activa', 'destacada');
card.classList.remove('oculta');
card.classList.toggle('expandida');
card.classList.replace('vieja', 'nueva');
const esActiva = card.classList.contains('activa'); // true

// === ATRIBUTOS ===
const enlace = document.querySelector('a');
enlace.setAttribute('href', 'https://bemorex.com');
enlace.setAttribute('target', '_blank');
enlace.setAttribute('rel', 'noopener noreferrer');
const url = enlace.getAttribute('href');
enlace.removeAttribute('title');

// Data attributes
const producto = document.querySelector('[data-id]');
const id = producto.dataset.id;        // data-id
const precio = producto.dataset.precio; // data-precio

// === CREAR Y AGREGAR ELEMENTOS ===
const lista = document.querySelector('.lista');
const nuevoItem = document.createElement('li');
nuevoItem.textContent = 'Nuevo item';
nuevoItem.classList.add('item');

// Diferentes posiciones
lista.appendChild(nuevoItem);                          // al final
lista.prepend(nuevoItem);                              // al inicio
lista.insertBefore(nuevoItem, lista.children[2]);     // antes del 3ro

// Eliminar
nuevoItem.remove();