¿Qué es el DOM?
El DOM (Document Object Model) es la representación en memoria de un documento HTML o XML. Cuando el navegador carga una página web, convierte todo el HTML en un árbol de objetos JavaScript que podemos leer y modificar.
En palabras simples: el DOM es el puente entre tu código JavaScript y lo que el usuario ve en pantalla. Sin él, JavaScript sería ciego ante el contenido de la página.
jsdom).
¿Cómo funciona?
El navegador sigue este proceso al cargar una página:
HTML texto plano
↓
Parsing (análisis) por el navegador
↓
DOM Tree (árbol de nodos)
↓
JavaScript puede leerlo y modificarlo
↓
El navegador re-renderiza los cambios
La Estructura de Árbol
Todo en el DOM es un nodo. El documento es el nodo raíz, y cada elemento HTML, texto o comentario es un nodo hijo.
<!DOCTYPE html> <html> <head> <title>Mi Página</title> </head> <body> <h1 id="titulo">Hola Mundo</h1> <p class="texto">Primer párrafo</p> </body> </html>
Este HTML se convierte en el siguiente árbol de nodos:
document └─ html ├─ head │ └─ title │ └─ "Mi Página" ← nodo de texto └─ body ├─ h1 id="titulo" │ └─ "Hola Mundo" └─ p class="texto" └─ "Primer párrafo"
Tipos de Nodos
<div>, <p>, <span>. Son los más comunes.<p>Hola</p> es un nodo de texto.document raíz. Punto de entrada a todo el DOM.<!-- así -->. También son nodos en el árbol.Seleccionar Elementos
Antes de modificar un elemento, primero hay que encontrarlo. JavaScript ofrece varios métodos para esto, cada uno con sus ventajas:
Los 4 métodos esenciales
// ── Por ID (devuelve 1 elemento o null) ── const titulo = document.getElementById('titulo'); // ── Por clase CSS (devuelve HTMLCollection) ── const tarjetas = document.getElementsByClassName('tarjeta'); // ── Por selector CSS, el primero que coincida ── const primer_boton = document.querySelector('button.activo'); // ── Por selector CSS, TODOS los que coincidan ── const todos_botones = document.querySelectorAll('.btn');
querySelector y querySelectorAll en la mayoría de casos. Aceptan cualquier selector CSS, lo que los hace muy poderosos y flexibles.
Navegación entre nodos
Una vez que tienes un nodo, puedes moverte por el árbol usando estas propiedades:
const lista = document.querySelector('ul'); lista.parentElement // → elemento padre lista.children // → hijos elementos (HTMLCollection) lista.firstElementChild // → primer hijo elemento lista.lastElementChild // → último hijo elemento lista.nextElementSibling // → hermano siguiente lista.previousElementSibling // → hermano anterior
Manipular el DOM
Leer y modificar contenido
const elem = document.querySelector('#caja'); // Leer/escribir texto (seguro, escapa HTML) elem.textContent; // → "texto actual" elem.textContent = 'Nuevo texto'; // Leer/escribir HTML interno (¡cuidado con XSS!) elem.innerHTML; // → "<b>html</b>" elem.innerHTML = '<b>Negrita</b>'; // Valor de inputs y formularios document.querySelector('input').value; // → "lo que escribió el usuario"
Atributos y clases CSS
const img = document.querySelector('img'); // ── Atributos ── img.getAttribute('src'); // lee img.setAttribute('src', 'nueva.jpg'); // escribe img.removeAttribute('alt'); // elimina img.hasAttribute('loading'); // verifica (true/false) // ── Clases CSS (la forma moderna) ── elem.classList.add('activo'); // agrega clase elem.classList.remove('activo'); // quita clase elem.classList.toggle('activo'); // alterna clase elem.classList.contains('activo'); // → true / false
Estilos inline
const caja = document.querySelector('.caja'); caja.style.backgroundColor = '#7c3aed'; // camelCase en JS caja.style.fontSize = '18px'; caja.style.display = 'none'; // ocultar elemento caja.style.cssText = 'color: red; font-size: 20px'; // múltiples a la vez
Crear e insertar elementos
// 1. Crear el elemento const nuevoItem = document.createElement('li'); nuevoItem.textContent = 'Nueva tarea'; nuevoItem.classList.add('item'); // 2. Insertarlo en el DOM const lista = document.querySelector('#lista'); lista.appendChild(nuevoItem); // al final lista.prepend(nuevoItem); // al inicio lista.insertBefore(nuevoItem, lista.children[1]); // posición específica lista.remove(); // eliminar la lista entera nuevoItem.remove(); // eliminar el item
Eventos del DOM
Los eventos permiten que tu código reaccione a las acciones del usuario. Son el núcleo de la interactividad web.
const boton = document.querySelector('#btn'); // addEventListener es la forma correcta y moderna boton.addEventListener('click', (event) => { console.log('¡Clic!', event); event.preventDefault(); // evita el comportamiento por defecto event.stopPropagation(); // evita que el evento suba al padre }); // Remover el listener function handler() { /* ... */ } boton.addEventListener('click', handler); boton.removeEventListener('click', handler);
Eventos más usados
input dispara en cada tecla; change solo al perder el foco.event.key dice cuál fue.preventDefault().document, no en un elemento.Delegación de eventos
En vez de poner un listener en cada elemento hijo, ponlo en el padre y usa event.target:
// ❌ Ineficiente: un listener por cada botón document.querySelectorAll('.btn').forEach(btn => { btn.addEventListener('click', handler); }); // ✅ Eficiente: un solo listener en el padre document.querySelector('#contenedor').addEventListener('click', (e) => { if (e.target.matches('.btn')) { handler(e); } });
App de Tareas
Una aplicación completa que usa todos los conceptos del DOM: createElement addEventListener classList.toggle querySelector remove()
📄 El código que hace funcionar esta app
Cada vez que interactúas con la app, este código del DOM se ejecuta:
// ── 1. Seleccionar elementos del DOM ── const input = document.querySelector('#taskInput'); const addBtn = document.querySelector('#addBtn'); const taskList = document.querySelector('#taskList'); // ── 2. Escuchar el evento "click" en el botón ── addBtn.addEventListener('click', () => { const texto = input.value.trim(); if (!texto) return; // ── 3. Crear nuevo elemento ── const item = document.createElement('div'); item.classList.add('task-item'); item.innerHTML = ` <div class="task-checkbox"></div> <span class="task-text">${texto}</span> <button class="btn btn-danger">Eliminar</button> `; // ── 4. Insertar en el DOM ── taskList.appendChild(item); input.value = ''; // limpiar input }); // ── 5. Delegación: escuchar clics en la lista ── taskList.addEventListener('click', (e) => { // Completar tarea if (e.target.matches('.task-checkbox')) { e.target.classList.toggle('checked'); e.target.nextElementSibling.classList.toggle('done'); } // Eliminar tarea if (e.target.matches('.btn-danger')) { e.target.closest('.task-item').remove(); } });