Casa en venta
Jairo
Si el HTML es el “esqueleto” de tu web, el DOM es el árbol vivo que el navegador construye para que JavaScript pueda leerlo y modificarlo. Cuando empecé, lo que de verdad me desbloqueó fue entender que tocar nodos es tocar la interfaz en tiempo real: cada cambio se refleja sin recargar la página.
Con el DOM puedo seleccionar “cajitas” (nodos), leer o cambiar su contenido/atributos/estilos, escuchar eventos y crear o eliminar elementos bajo demanda. Esta base basta para construir desde una lista de tareas hasta un panel de filtros avanzado. En mi día a día, si quiero un elemento único, tiro de getElementById("id"); si necesito selectores CSS, uso querySelector o querySelectorAll. Y cuando solo voy a imprimir texto del usuario, textContent me evita sustos frente a innerHTML.
Idea clave: el DOM no es solo “modificar etiquetas”; es pensar en nodos + atributos + eventos con foco en UX, seguridad y rendimiento.
<h1 id="heroTitle">DOM 101</h1> <ul id="todos"></ul>
// Único por id const title = document.getElementById("heroTitle"); // Selectores CSS potentes const activePrice = document.querySelector(".card.active [data-price]"); const items = document.querySelectorAll(".todo-item"); // NodeList items.forEach(li => li.classList.add("highlight"));
Consejo personal: cuando sé el id, voy directo. Si la estructura puede cambiar, querySelector me da libertad para apuntar a clases, atributos ([data-*]) y jerarquías. Esto me ha evitado roturas al refactorizar HTML.
Si solo voy a escribir texto, uso textContent; mantiene el texto literal y previene inyecciones HTML. En cambio, innerHTML inyecta HTML (útil para plantillas controladas por mí, no para entradas del usuario).
title.textContent = "Manipulación del DOM: ejemplos reales"; // seguro para texto
// Atributos
title.setAttribute("data-section", "intro");
title.setAttribute("aria-live", "polite"); // accesibilidad básica
Mi regla práctica: “si no necesito etiquetas, no uso innerHTML”. Ese pequeño hábito me ha ahorrado bugs y riesgos de XSS.
Prefiero clases a estilos inline. Con classList puedo alternar estados sin pelearme con CSS:
const panel = document.querySelector(".panel");
panel.classList.add("is-open");
panel.classList.toggle("is-animated");
// En emergencias puntuales:
panel.style.maxHeight = "320px"; // evita abusar de .style
Comparativa práctica (sin tabla):
Un flujo que uso a diario: crear → configurar → insertar. Es limpio y predecible.
<input id="todoInput" placeholder="Nueva tarea" /> <button id="addBtn">Añadir</button> <ul id="todoList" aria-live="polite"></ul>
const input = document.getElementById("todoInput"); const addBtn = document.getElementById("addBtn"); const list = document.getElementById("todoList"); addBtn.addEventListener("click", () => { const text = input.value.trim(); if (!text) return; const li = document.createElement("li"); li.className = "todo-item"; li.textContent = text; // seguro const removeBtn = document.createElement("button"); removeBtn.className = "remove"; removeBtn.textContent = "✕"; removeBtn.setAttribute("aria-label", `Eliminar ${text}`); li.appendChild(removeBtn); list.appendChild(li); input.value = ""; input.focus(); });
Por qué funciona bien:
Yo suelo describirlo así: “Crear con createElement y montar con appendChild es mi combo para listas dinámicas; elimino con remove() cuando ya no se necesita”.
list.addEventListener("click", (e) => {
if (e.target.matches("button.remove")) {
const li = e.target.closest("li");
li.remove(); // simple y moderno
}
});
Notas express:
Cuando creo elementos nuevos, prefiero delegar en un contenedor estable. Así no registro listeners por cada nodo y mejoro rendimiento/memoria.
list.addEventListener("click", (e) => {
if (e.target.matches(".todo-item")) {
e.target.classList.toggle("done");
}
});
Comparativa breve:
Manipular el DOM puede disparar reflows (cambio de layout) y paints (repintado). Para suavizar:
const frag = document.createDocumentFragment();
for (let i = 0; i < 500; i++) {
const li = document.createElement("li");
li.textContent = `Item ${i + 1}`;
frag.appendChild(li);
}
list.appendChild(frag); // un solo reflow grande, mejor que 500 pequeños
const t0 = performance.now();
// ... crear/insertar muchos nodos
const t1 = performance.now();
console.log(`Render tomó ${(t1 - t0).toFixed(2)}ms`);
function fadeIn(el) {
el.style.opacity = 0;
let o = 0;
function step() {
o += 0.05;
el.style.opacity = o;
if (o < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
En pruebas reales, pasar de 500 inserciones una a una a usar DocumentFragment me redujo el tiempo de render de “se nota el lag” a “fluido”. No doy milisegundos exactos porque varían por equipo, pero el patrón se siente en cualquier máquina.
Tres hábitos que aplico siempre que manipulo la interfaz:
Resultado: menos frustración y una interfaz que “habla” cuando el DOM cambia.
// Malo si viene de usuario:
list.innerHTML = `<li>${userText}</li>`; // riesgo XSS
// Bueno:
const li = document.createElement("li");
li.textContent = userText;
list.appendChild(li);
Checklist: ¿mides con performance.now()? ¿evitas innerHTML con texto de usuario? ¿usaste aria-* y foco? ¿centralizaste estilos con clases?
No hay comentarios aún. ¡Sé el primero en comentar!
🍪 Utilizamos cookies para mejorar tu experiencia de navegación, analizar el tráfico del sitio y personalizar el contenido. Al continuar navegando, aceptas nuestro uso de cookies. Más información