Hoy · Hoja de ruta
- 1. Aprende: Cómo se crea un elemento, cómo se inserta y cómo se quita.
- 2. Haz: Genera una tarjeta de producto desde un objeto de datos.
- 3. Comprueba: El HTML generado es tan semántico como el que escribes a mano.
Antes de empezar · 5 minutos, sin apuntes
- Escribe el HTML de una tarjeta de producto tuya, de memoria.
- ¿Qué partes cambian de un producto a otro y cuáles no?
- Si generas HTML desde código, ¿quién garantiza que sigue siendo semántico?
Crear, rellenar, insertar
const item = document.createElement("li");
item.className = "producto";
item.dataset.id = producto.id;
const titulo = document.createElement("h3");
titulo.textContent = producto.nombre;
item.append(titulo);
catalogo.append(item); // al final
catalogo.prepend(item); // al principio
| Método | Qué hace |
|---|---|
append |
Añade al final del contenido |
prepend |
Añade al principio |
before / after |
Inserta como hermano |
remove |
Se elimina a sí mismo |
replaceChildren |
Sustituye la totalidad del contenido en una sola operación |
Vaciar un contenedor
catalogo.replaceChildren(); // lo deja vacío
catalogo.innerHTML = ""; // funciona, pero pasa por el analizador
replaceChildren es más claro y más seguro, y admite también los nuevos hijos: catalogo.replaceChildren(...tarjetas).
Insertar de una vez
Añadir cincuenta elementos uno a uno hace que el navegador recalcule la página cincuenta veces. Se construyen aparte y se insertan juntos:
const fragmento = document.createDocumentFragment();
for (const producto of productos) {
fragmento.append(crearTarjeta(producto));
}
catalogo.replaceChildren(fragmento);
El HTML generado también se audita
Lo que genera tu código pasa las mismas normas de la UD1
Es fácil que la lista de productos acabe siendo una pila de contenedores genéricos con clases. Si al escribirlo a mano usabas una lista de artículos con su encabezado, su imagen con texto alternativo y su precio, el código tiene que generar exactamente eso.
La comprobación: abre Elements, copia el marcado generado, pégalo en el validador del W3C. La jerarquía de encabezados sigue siendo exigible sobre ese marcado generado.
Una función por tarjeta
export function crearTarjeta(producto) {
const item = document.createElement("li");
item.className = "producto";
item.dataset.id = producto.id;
const titulo = document.createElement("h3");
titulo.textContent = producto.nombre;
const imagen = document.createElement("img");
imagen.src = producto.imagen;
imagen.alt = producto.textoAlternativo;
imagen.loading = "lazy";
const precio = document.createElement("p");
precio.className = "precio";
precio.textContent = formatearPrecio(producto.precio);
item.append(imagen, titulo, precio);
return item;
}
Devuelve el elemento y no lo inserta: quien la llama decide dónde va. Es la misma regla de la UD3 —calcular y devolver— aplicada al DOM.
Tarea 6 · La tarjeta generada
- Escribe
crearTarjeta(producto)enjs/render.js. - Genera con ella las tarjetas de tres productos y añádelas con un fragmento.
- Compara el marcado generado con el que tenías escrito a mano.
- Valida el resultado copiándolo desde Elements.
- Añade un botón de acción con sus atributos
data-. - Escribe
vaciarCatalogo()y comprueba que las escuchas delegadas siguen funcionando.
template del HTML y compara los dos enfoques.Cierre de la semana 2
- Tu página responde al ratón y al teclado.
- Usas una sola escucha delegada por contenedor.
- Generas elementos con marcado semántico y válido.
- Insertas en bloque, no de uno en uno.
Ver respuestas
1 · Porque cada inserción individual obliga al navegador a recalcular la página.
2 · replaceChildren() sin argumentos.
3 · Copiando el marcado desde Elements y pasándolo por el validador del W3C.
Microprueba semanal 2 · 5–10 minutos
Individual, sin IA y sin apuntes.
- Escribe la escucha que impide que un formulario recargue la página.
- Explica por qué una escucha delegada funciona con elementos que aún no existen.
- ¿Qué diferencia hay entre
targetycurrentTarget?