← El DOM: la web que responde

Sesión 2 · Semana 1

Seleccionar elementos

Hoy · Hoja de ruta

  1. 1. Aprende: Cómo se localiza un elemento y qué devuelve cada forma de buscarlo.
  2. 2. Haz: Prepara tu HTML con puntos de anclaje pensados para el código.
  3. 3. Comprueba: Ninguna de tus selecciones depende de la posición ni de una clase de estilo.

Antes de empezar · 5 minutos, sin apuntes

  1. Si el diseñador cambia la clase .tarjeta por .card, ¿se rompe tu código?
  2. ¿Qué selectores CSS recuerdas de la UD2?
  3. ¿Qué diferencia hay entre «el primero que cumpla» y «todos los que cumplan»?

Los dos métodos que vas a usar

const titulo = document.querySelector("h1");            // el primero, o null
const tarjetas = document.querySelectorAll(".producto"); // todos, siempre una lista

Aceptan cualquier selector CSS, exactamente los que aprendiste en la UD2:

document.querySelector("#buscador");
document.querySelector(".catalogo .producto");
document.querySelector("[data-categoria='teclados']");
document.querySelectorAll("article:not(.agotado)");

Existen métodos más antiguos —getElementById, getElementsByClassName— que verás en tutoriales. Funcionan, pero con dos sirve, y los dos aceptan la misma sintaxis que ya sabes.

Lo que devuelve querySelectorAll no es un array

const tarjetas = document.querySelectorAll(".producto");

tarjetas.length          // sí
tarjetas.forEach(...)    // sí
tarjetas.map(...)        // TypeError: no es una función

[...tarjetas].map(...)   // convertido en array, ya sí

Es una NodeList. Tiene length y forEach, pero no los métodos de la UD3. Los tres puntos la convierten en un array de verdad.

Una lista vacía, además, no es null: si el selector no encuentra nada, querySelectorAll devuelve una lista de longitud cero, mientras que querySelector devuelve null. Confundir esos dos casos es el segundo error más común de la unidad.

Anclajes pensados para el código

No selecciones por clases de estilo ni por posición

Si tu código busca .tarjeta-azul o el tercer elemento de una lista, cualquier retoque de diseño lo romperá, y quien lo rompa no sabrá que lo ha roto.

Usa un atributo data- pensado para eso: data-js="buscador". Así el HTML declara explícitamente «aquí hay un punto de conexión con el código», y las clases quedan libres para el CSS.

<input type="search" id="buscador" data-js="buscador" aria-label="Buscar productos">
<ul class="catalogo" data-js="catalogo"></ul>
<p data-js="resultado" role="status"></p>
const buscador = document.querySelector("[data-js='buscador']");
const catalogo = document.querySelector("[data-js='catalogo']");

Guardar las referencias una sola vez

// Mal: busca en el árbol cada vez que el usuario escribe
function alEscribir() {
  document.querySelector("[data-js='catalogo']").textContent = "";
}

// Bien: se busca una vez, al arrancar
const elementos = {
  buscador: document.querySelector("[data-js='buscador']"),
  catalogo: document.querySelector("[data-js='catalogo']"),
  resultado: document.querySelector("[data-js='resultado']")
};

Además de ser más rápido, agrupa en un sitio todo lo que tu código espera encontrar en la página. Si algo sale null, se ve al arrancar y no en mitad de un evento.

Tarea 2 · Preparar el terreno

Sobre tu página de productos:

  1. Añade atributos data-js a los seis elementos con los que vas a trabajar.
  2. Crea js/dom.js que los seleccione y los exporte en un objeto.
  3. Escribe una comprobación que avise por consola si alguno es null.
  4. Selecciona todas las tarjetas y cuéntalas.
  5. Convierte la NodeList en array y obtén sus textos con map.
Objetivo mínimoSeis anclajes, seleccionados una vez y comprobados.
Si lo tienesHaz que la comprobación diga qué anclaje falta, por su nombre.
RetoEscribe una función que seleccione y lance un error claro si no encuentra el elemento.

Checkpoint · fin de la sesión 2

  • Usas los dos métodos de selección y sabes qué devuelve cada uno.
  • Seleccionas por data-, no por clases de estilo.
  • Conviertes una NodeList en array cuando la necesitas.
  • Guardas las referencias una sola vez.

Antes de cerrar · 2 minutos, sin mirar

  1. ¿Qué devuelve querySelector si no encuentra nada? ¿Y querySelectorAll?
  2. ¿Por qué no seleccionamos por clases de CSS?
  3. ¿Cómo se usa map sobre el resultado de querySelectorAll?
Ver respuestas

1 · null el primero; una lista vacía el segundo.

2 · Porque las clases son del diseño y cambian: el código quedaría atado a decisiones visuales.

3 · Convirtiéndola antes en array con los tres puntos.