DOM — Document Object Model
El DOM es la representación del HTML como un árbol de objetos que JavaScript puede leer y modificar. Es la base de toda interactividad en el navegador.
¿Qué es el DOM?
Cuando el navegador carga una página HTML, construye una estructura en memoria llamada DOM (Document Object Model). Es un árbol de nodos donde cada etiqueta HTML es un objeto que JavaScript puede seleccionar, modificar, crear o eliminar.
<!-- HTML -->
<div id="contenedor">
<h1 class="titulo">Hola</h1>
<p>Primer párrafo</p>
<p>Segundo párrafo</p>
</div>
// JavaScript puede acceder a cualquier elemento
const contenedor = document.getElementById("contenedor");
const titulo = document.querySelector(".titulo");
const parrafos = document.querySelectorAll("p");
document es el objeto raíz del DOM — representa toda la página. A partir de él podés llegar a cualquier elemento.
Seleccionar elementos
// Por ID — devuelve un elemento o null
const titulo = document.getElementById("mi-titulo");
// Por selector CSS — devuelve el PRIMERO que coincide
const primero = document.querySelector(".card");
const input = document.querySelector("input[type='text']");
const h2 = document.querySelector("#seccion h2");
// Por selector CSS — devuelve TODOS (NodeList)
const cards = document.querySelectorAll(".card");
const inputs = document.querySelectorAll("input");
// Iterar sobre una NodeList
cards.forEach(card => {
console.log(card.textContent);
});
// Métodos más antiguos (aún funcionan)
document.getElementsByClassName("card"); // HTMLCollection
document.getElementsByTagName("p"); // HTMLCollection
querySelector acepta cualquier selector CSS — es más flexible. getElementById es más rápido pero solo busca por ID. En la práctica, querySelector se usa para casi todo.
Leer y modificar contenido
const el = document.getElementById("caja");
// Leer
el.textContent; // texto plano (sin HTML)
el.innerHTML; // contenido con etiquetas HTML
el.value; // valor de inputs y textareas
// Modificar
el.textContent = "Nuevo texto";
el.innerHTML = "<strong>Texto en negrita</strong>";
// Atributos
el.getAttribute("class");
el.setAttribute("class", "activo");
el.removeAttribute("disabled");
el.id; // leer el id directamente
el.href; // leer href de un enlace
// Dataset — atributos data-*
// <div data-usuario="ana" data-rol="admin">
el.dataset.usuario; // "ana"
el.dataset.rol; // "admin"
Probá el Ejemplo 2: Modificar contenido y atributos
Modificar estilos y clases
const caja = document.getElementById("caja");
// Estilos inline — directamente sobre el elemento
caja.style.color = "red";
caja.style.backgroundColor = "#f0f0f0"; // camelCase
caja.style.fontSize = "18px";
caja.style.display = "none"; // ocultar
caja.style.display = ""; // restaurar al valor CSS
// Clases — la forma recomendada (separa JS del CSS)
caja.classList.add("activo");
caja.classList.remove("inactivo");
caja.classList.toggle("visible"); // agrega si no está, quita si está
caja.classList.contains("activo"); // true/false
caja.classList.replace("viejo", "nuevo");
// Múltiples clases
caja.classList.add("grande", "rojo", "centrado");
Preferí manipular clases CSS con classList en vez de modificar style directamente. Así mantenés los estilos en el CSS y el JS solo controla la lógica.
Crear y eliminar elementos
// Crear un elemento nuevo
const li = document.createElement("li");
li.textContent = "Nuevo item";
li.className = "item-lista";
// Agregarlo al DOM
const lista = document.getElementById("mi-lista");
lista.appendChild(li); // al final
lista.prepend(li); // al principio
lista.insertBefore(li, lista.children[2]); // antes del 3er hijo
// Forma moderna con insertAdjacentHTML
lista.insertAdjacentHTML("beforeend", "<li>Item con HTML</li>");
lista.insertAdjacentHTML("afterbegin","<li>Primero</li>");
// Eliminar elementos
const item = document.querySelector(".item-a-borrar");
item.remove(); // forma moderna
// item.parentNode.removeChild(item); // forma antigua
// Clonar un elemento
const clon = li.cloneNode(true); // true = clonar también hijos
lista.appendChild(clon);
Probá el Ejemplo 3: Crear y eliminar elementos
Navegar el árbol DOM
const el = document.getElementById("item");
// Subir
el.parentElement; // elemento padre
el.parentElement.parentElement; // abuelo
// Bajar
el.children; // HTMLCollection de hijos directos
el.firstElementChild; // primer hijo
el.lastElementChild; // último hijo
el.children[2]; // tercer hijo
// Ir al costado
el.nextElementSibling; // siguiente hermano
el.previousElementSibling; // hermano anterior
// Buscar dentro de un elemento (no en todo el documento)
const contenedor = document.getElementById("contenedor");
contenedor.querySelector(".item"); // busca solo adentro
contenedor.querySelectorAll("li");
Ejemplo Completo — Lista de tareas dinámica
Una mini app que crea, completa y elimina tareas manipulando el DOM:
function agregarTarea(texto) {
if (!texto.trim()) return;
const li = document.createElement("li");
li.className = "tarea";
const span = document.createElement("span");
span.textContent = texto;
const btnCompletar = document.createElement("button");
btnCompletar.textContent = "✓";
btnCompletar.onclick = () => li.classList.toggle("completada");
const btnBorrar = document.createElement("button");
btnBorrar.textContent = "✕";
btnBorrar.onclick = () => li.remove();
li.append(span, btnCompletar, btnBorrar);
document.getElementById("lista").appendChild(li);
}
// Leer valor de un input y agregar
const input = document.getElementById("nuevaTarea");
document.getElementById("btnAgregar").onclick = () => {
agregarTarea(input.value);
input.value = "";
input.focus();
};
Probá el Ejemplo 4: Lista de tareas
Buenas Prácticas
- querySelector sobre getElementById: más flexible y acepta cualquier selector CSS
- classList sobre style: separá la lógica (JS) del diseño (CSS)
- Guardá referencias en variables: no llames a
getElementByIddentro de un loop — es lento - insertAdjacentHTML para insertar muchos elementos: más eficiente que múltiples appendChild
- Verificá que el elemento existe: antes de manipularlo, comprobá que no sea
null - Delegación de eventos: en vez de poner listeners en cada elemento hijo, poné uno en el padre (lo verás en el tuto de Eventos)