Borra tus funciones de tiempo de espera y elimina sus errores. Aquí tienes el evento que realmente necesitas: scrollend.
Antes del evento scrollend, no había una forma confiable de detectar que se había completado un desplazamiento. Esto significaba que los eventos se activaban tarde o mientras el dedo de un usuario aún estaba en la pantalla. Esta falta de confiabilidad para saber cuándo finalizó el desplazamiento realmente generó errores y una mala experiencia para el usuario.
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
Lo mejor que puede hacer esta estrategia de setTimeout() es saber si la función de desplazamiento se detuvo para 100ms. Esto hace que se parezca más a un evento de pausa del desplazamiento que a un evento de finalización del desplazamiento.
Después del evento scrollend, el navegador realiza toda esta difícil evaluación por ti.
document.onscrollend = event => {…}
Eso es lo bueno. Se cronometran y se completan con condiciones significativas antes de emitirse.
Pruébalo
Detalles del evento
El evento scrollend se activa en los siguientes casos:
- El navegador ya no está animando ni traduciendo el desplazamiento.
- Se soltó el toque del usuario.
- El puntero del usuario soltó el pulgar de desplazamiento.
- Se soltó la presión de la tecla del usuario.
- Se completó el desplazamiento al fragmento.
- Se completó el ajuste de desplazamiento.
- Se completó scrollTo().
- El usuario desplazó el viewport visual.
El evento scrollend no se activa en los siguientes casos:
- El gesto de un usuario no generó ningún cambio en la posición de desplazamiento (no se produjo ninguna traslación).
- scrollTo() no generó ninguna traducción.
Una de las razones por las que este evento tardó tanto en llegar a la plataforma web fue la gran cantidad de detalles pequeños que necesitaban especificaciones. Una de las áreas más complejas fue la de articular los detalles de scrollend para la ventana gráfica visual en comparación con el documento. Considera una página web en la que acercas la imagen. Puedes desplazarte cuando se encuentra en este estado de zoom, y no necesariamente se desplaza el documento. Ten la certeza de que incluso esta interacción de desplazamiento controlada por el usuario del viewport visual emitirá el evento scrollend una vez que se complete.
Cómo usar el evento
Al igual que con otros eventos de desplazamiento, puedes registrar objetos de escucha de varias maneras.
addEventListener("scrollend", (event) => {
// scroll ended
});
aScrollingElement.addEventListener("scrollend", (event) => {
// scroll ended
});
o bien usa la propiedad del evento:
document.onscrollend = (event) => {
// scroll ended
};
aScrollingElement.onscrollend = (event) => {
// scroll ended
};
Polyfills y mejora progresiva
Si quieres usar este nuevo evento ahora, te damos nuestro mejor consejo. Puedes seguir usando tu estrategia actual de final de desplazamiento (si tienes una) y, al principio, verificar la compatibilidad con lo siguiente:
'onscrollend' in window
// true, if available
Se informará verdadero o falso según si el navegador ofrece el evento. Con esta verificación, puedes crear una rama del código:
if ('onscrollend' in window) {
document.onscrollend = callback
}
else {
document.onscroll = event => {
clearTimeout(window.scrollEndTimer)
window.scrollEndTimer = setTimeout(callback, 100)
}
}
Este es un buen comienzo para mejorar progresivamente tu evento scrollend cuando esté disponible. También puedes probar con un polyfill (NPM) que creé y que hace lo mejor que puede el navegador:
import {scrollend} from "scrollyfills"
// then use scrollend as if it's existed this whole time
document.onscrollend = callback
El polyfill mejorará progresivamente para usar el evento scrollend integrado en el navegador si está disponible. Si no está disponible, el script observa los eventos del puntero y se desplaza para hacer la mejor estimación del final del evento que pueda.
Casos de uso
Es una buena práctica evitar el trabajo pesado desde el punto de vista computacional mientras se desplaza. Esta práctica garantiza que el desplazamiento pueda usar toda la memoria y el procesamiento que necesite para que la experiencia sea fluida. Usar un evento scrollend proporciona el momento perfecto para llamar y hacer el trabajo duro, ya que el desplazamiento ya no se produce.
El evento scrollend se puede usar para activar varias acciones. Un caso de uso común es sincronizar los elementos de la IU asociados con la posición en la que se detuvo el desplazamiento. Por ejemplo, sincronizar la posición de desplazamiento de un carrusel con un indicador de puntos
- Sincronizar un elemento de la galería con sus metadatos
- Recuperación de datos después de que un usuario se desplaza a una pestaña nueva
Imagina una situación en la que un usuario desliza el dedo para descartar un correo electrónico. Después de que termine de deslizar, puedes realizar la acción según dónde se desplazó.
También puedes usar este evento para la sincronización después del desplazamiento programático o del usuario, o bien para acciones como el registro de Analytics.
Aquí tienes un buen ejemplo en el que se deben actualizar varios elementos, como flechas, puntos y enfoque, según la posición de desplazamiento. Mira cómo creé este carrusel en YouTube. También puedes probar la demostración en vivo.
Gracias a Mehdi Kazemi por su trabajo de ingeniería en este proyecto y a Robert Flack por su orientación sobre la API y la implementación.