Este artículo detalla la implementación de un menú deslizante A-Z, una característica común en aplicaciones móviles para facilitar la búsqueda rápida. Se exploran los eventos de desplazamiento y táctiles en JavaScript para crear esta funcionalidad interactiva.
Antes de proceder, es fundamental entender tres propiedades clave del DOM relacionadas con el desplazamiento:
scrollTop: Representa la distancia entre la parte superior de un elemento y la parte superior del área visible. Si no hay barra de desplazamiento vertical, su valor es 0.scrollHeight: Propiedad de solo lectura que indica la altura total del contenido de un elemento, incluyendo áreas no visibles.clientHeight: Propiedad de solo lectura que mide la altura interna de un elemento, considerando relleno pero excluyendo barras de desplazamiento, bordes y márgenes.
Utilizando estos conceptos, primero calculamos las alturas acumuladas de cada sección del menú. El código siguiente recopila las alturas de los elementos de lista y las almacena en un array:
const elementosLista = this.$refs.grupoElementos;
let alturaAcumulada = 0;
this.arrayAlturas.push(alturaAcumulada);
for (let i = 0; i < elementosLista.length; i++) {
alturaAcumulada += elementosLista[i].clientHeight;
this.arrayAlturas.push(alturaAcumulada);
}
Una vez obtenidas las alturas, se configura un oyente de evantos de desplazamiento para sincronizar el menú con la posición actual en la página:
window.addEventListener('scroll', evento => {
const desplazamientoActual = document.documentElement.scrollTop;
for (let idx = 0; idx < this.arrayAlturas.length - 1; idx++) {
const limiteInferior = this.arrayAlturas[idx];
const limiteSuperior = this.arrayAlturas[idx + 1];
if (desplazamientoActual >= limiteInferior && desplazamientoActual < limiteSuperior) {
this.tituloActual = this.letrasMenu[idx];
this.indiceSeleccionado = idx;
}
}
});
Para la interacción táctil, se emplean propiedades del evento touch, como clientY, que indica la coordenada vertical relativa al viewport. A continuación, se muestra cómo manejar el deslizamiento para navegar a la sección correspondiente:
gestionarToque(evento) {
const posicionY = evento.touches[0].clientY;
const offsetElemento = this.$refs.menuLetras.offsetTop;
const alturaPorItem = 20; // Altura fija por ítem del menú
const indiceCalculado = Math.floor((posicionY - offsetElemento) / alturaPorItem);
this.navegarASeccion(indiceCalculado);
}
Finalmente, se implementa la función para desplazarse suavemente a una posición específica, validando previamente el índice:
navegarASeccion(indice) {
if (indice < 0 || indice >= this.arrayAlturas.length) return;
window.scrollTo({
top: this.arrayAlturas[indice],
behavior: 'smooth'
});
this.indiceSeleccionado = indice;
}
Este enfoque permite que el menú A-Z se actualice dinámicamente durante el desplazamiento y ofrezca una experiencia táctil intuitiva en dispositivos móviles.