← El DOM: la web que responde

Sesión 11 · Semana 4

Filtros, orden y búsqueda en vivo

Hoy · Hoja de ruta

  1. 1. Aprende: Cómo se combinan varios filtros y cómo se evita trabajar de más.
  2. 2. Haz: Monta el panel de filtros completo de tu catálogo.
  3. 3. Comprueba: Los filtros se combinan bien y el resultado se anuncia.

Antes de empezar · 5 minutos, sin apuntes

  1. Si hay búsqueda y categoría a la vez, ¿deben cumplirse las dos o basta una?
  2. Al escribir «teclado» se disparan siete eventos. ¿Importa?
  3. ¿Cómo se entera de que hay tres resultados quien no ve la pantalla?

Combinar filtros

Los filtros se aplican en cadena: cada uno reduce lo que dejó el anterior, y el resultado son los productos que cumplen todo a la vez. Ese encadenamiento ya lo escribiste ayer en aplicarFiltros, y es la razón de que añadir un filtro nuevo sea añadir tres líneas.

Dos decisiones de producto que hay que tomar a conciencia:

Situación Decisión razonable
Búsqueda vacía No filtra nada
Categoría «todas» No filtra nada
Precio máximo vacío Sin límite, no cero
Ningún resultado Mensaje con salida: «quita algún filtro»

No trabajar de más

Filtrar cuatrocientos productos con cada tecla es trabajo repetido. Se limita con una función que espera a que la persona deje de escribir:

function retrasar(funcion, milisegundos = 250) {
  let temporizador;
  return (...argumentos) => {
    clearTimeout(temporizador);
    temporizador = setTimeout(() => funcion(...argumentos), milisegundos);
  };
}

elementos.buscador.addEventListener("input", retrasar((evento) => {
  estado.busqueda = evento.target.value;
  actualizar();
}, 250));

Debounce

Agrupar una ráfaga de eventos en una sola ejecución, la última. Con un buscador local su efecto es reducido; en la semana 5, cuando cada pulsación implique una petición al servidor, resultará obligatorio.

Fíjate en que retrasar es una función que devuelve otra función: exactamente lo que practicaste en la sesión 8 de la UD3.

Anunciar el resultado

<p data-js="resumen" role="status" aria-live="polite"></p>
export function pintarResumen(visibles, total, destino) {
  destino.textContent = visibles === total
    ? `${total} productos`
    : `${visibles} de ${total} productos`;
}

Un cambio que no se anuncia, para algunas personas no ocurre

Cuando el catálogo se filtra, quien ve la pantalla percibe el cambio al instante. Quien usa un lector de pantalla no se entera de nada, porque el foco sigue en el campo de búsqueda.

Una región con aria-live="polite" hace que el lector anuncie el nuevo texto sin interrumpir. Es una línea de HTML y cambia por completo la experiencia.

Tarea 11 · El panel completo

  1. Añade al menos tres controles: búsqueda, categoría y orden.
  2. Genera las opciones de categoría desde los datos, no a mano.
  3. Añade una casilla de «solo disponibles».
  4. Aplica el retraso a la búsqueda y comprueba la diferencia en consola.
  5. Anuncia el número de resultados en una región activa.
  6. Añade un botón de limpiar que restaure el estado inicial.
Objetivo mínimoTres filtros combinables, resumen anunciado y botón de limpiar.
Si lo tienesRango de precio con dos campos y validación de que el mínimo no supera al máximo.
RetoMuestra las «pastillas» de filtros activos, cada una con su botón de quitar.

Checkpoint · fin de la sesión 11

  • Los filtros se combinan y ninguno pisa a otro.
  • Las opciones se generan desde los datos.
  • La búsqueda no recalcula con cada tecla.
  • El número de resultados se anuncia a los lectores de pantalla.

Antes de cerrar · 2 minutos, sin mirar

  1. ¿Qué hace un debounce?
  2. ¿Qué debe hacer un precio máximo vacío?
  3. ¿Para qué sirve aria-live?
Ver respuestas

1 · Esperar a que pare la ráfaga de eventos y ejecutar una sola vez.

2 · No filtrar: significa «sin límite», no cero.

3 · Para que un lector de pantalla anuncie los cambios de esa zona sin que haya que moverse hasta ella.