Maquetación Web Dinámica / JavaScript para maquetadores: darle vida al DOM
Render desde datos: crear elementos dinámicamente
Las apps modernas no tienen su contenido escrito a mano en el HTML: tienen DATOS (un array de noticias, productos, tareas) y GENERAN el HTML a partir de ellos. Cambian los datos, se redibuja la interfaz. Este patrón —render desde datos— es el corazón de React, Vue y toda app seria, y hoy lo haces con JavaScript puro para entenderlo desde los cimientos.
Los datos mandan; la pantalla obedece
Dos formas de crear elementos
// 1. createElement: preciso, seguro, un poco verboso
const li = document.createElement("li");
li.className = "tarea";
li.textContent = "Estudiar"; // textContent: seguro con cualquier texto
contenedor.appendChild(li);
// 2. innerHTML con plantilla de texto: rápido para bloques enteros
contenedor.innerHTML = `
<li class="tarea">Estudiar</li>
<li class="tarea">Practicar</li>
`;createElement construye nodo a nodo (más control, más seguro);
innerHTML reemplaza el interior de golpe con una plantilla de texto (más
rápido de escribir para listas enteras). Para render de datos, innerHTML
con .map().join("") es el patrón cómodo — con una advertencia importante
que viene abajo.
El patrón render(): datos → HTML
<div class="app">
<input id="buscar" type="search" placeholder="Filtrar noticias..." aria-label="Filtrar">
<div id="lista" class="lista"></div>
</div>body { font-family: system-ui; padding: 20px; background: #f8fafc; }
.app { max-width: 380px; display: grid; gap: 12px; }
#buscar { padding: 10px 12px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 15px; }
.lista { display: grid; gap: 8px; }
.noticia { background: white; border: 1px solid #e2e8f0; border-radius: 10px; padding: 12px 14px; }
.cat { font-size: 11px; font-weight: 700; text-transform: uppercase; color: #6d28d9; letter-spacing: 0.04em; }
.noticia h3 { margin: 4px 0 0; font-size: 15px; color: #1e293b; }
.vacio { color: #64748b; font-size: 14px; padding: 8px; }// LOS DATOS: la única fuente de verdad
const noticias = [
{ titulo: "El páramo que fabrica agua", categoria: "Ambiente" },
{ titulo: "Nueva ciclorruta conecta el norte", categoria: "Ciudad" },
{ titulo: "Festival de cine arranca en Bogotá", categoria: "Cultura" },
{ titulo: "Cómo ahorrar agua en casa", categoria: "Ambiente" },
];
const lista = document.querySelector("#lista");
const buscar = document.querySelector("#buscar");
// render(): convierte un array de datos en HTML
function render(items) {
if (items.length === 0) {
lista.innerHTML = "<p class='vacio'>Sin resultados</p>";
return;
}
lista.innerHTML = items.map((n) =>
"<article class='noticia'><span class='cat'>" + n.categoria +
"</span><h3>" + n.titulo + "</h3></article>"
).join("");
}
render(noticias); // primer dibujo
// al filtrar: NO tocamos el DOM a mano, RE-renderizamos desde los datos
buscar.addEventListener("input", (event) => {
const q = event.target.value.toLowerCase();
const filtradas = noticias.filter((n) => n.titulo.toLowerCase().includes(q));
render(filtradas);
});Escribe en el filtro: la lista se regenera desde el array en cada tecla. Lo importante es lo que NO hicimos — nunca ocultamos ni borramos tarjetas a mano. Filtramos los DATOS y volvimos a renderizar. Los datos son la verdad; la pantalla es su reflejo. Este bucle "cambia datos → re-renderiza" es, literalmente, la idea que React industrializó.
La advertencia: innerHTML y seguridad
Para mostrar una lista de comentarios que escriben los usuarios, ¿cómo insertas el texto de cada comentario de forma segura?
Mini-reto
Convierte "El Observador" en data-driven: mueve sus noticias a un array de
objetos ({ titulo, categoria, resumen }) y escribe un render() que
genere las tarjetas. Luego agrega botones de categoría (Ambiente, Ciudad,
Cultura) que filtren re-renderizando. Cuando lo tengas, cambia un dato del
array y observa cómo la página se actualiza sin que toques el HTML: acabas
de separar datos de presentación, la idea más importante del desarrollo
de interfaces.
Qué sigue
Sabes reaccionar a clics y a escritura. Falta reaccionar al SCROLL de forma
eficiente: revelar elementos al entrar en pantalla, cargar imágenes solo
cuando se ven, cambiar el navbar. La próxima lección trae la herramienta
perfecta para eso —IntersectionObserver— el mejor amigo del maquetador.