El desplazamiento en la Web debe ser fluido y responsivo. Ejecutar tareas pesadas, como volver a calcular el diseño, hacer un seguimiento de las balizas de datos de estadísticas o actualizar el DOM de forma dinámica, durante el desplazamiento puede saturar el subproceso principal, lo que genera fotogramas perdidos y un diseño inestable.
Históricamente, los desarrolladores han dependido de la eliminación de rebotes del evento scroll con setTimeout() para adivinar cuándo finaliza un desplazamiento. Sin embargo, estas funciones de debounce son notoriamente poco confiables. Es posible que se activen mientras el usuario aún se desplaza.
El evento scrollend ofrece una solución muy confiable y orientada al rendimiento. El navegador activa un evento scrollend exactamente cuando se detiene un desplazamiento, finalizan todas las transiciones y se suelta un gesto táctil.
Cómo implementarla
Para implementar un patrón de aplazamiento de trabajo, haz lo siguiente:
- Configura un contenedor desplazable: Crea un contenedor con
overflow: autoooverflow: scroll. - Escucha eventos
scroll: Usa este objeto de escucha solo para métricas dinámicas básicas o estilos de diseño informativos. No ejecutes tareas pesadas aquí. - Detecta eventos
scrollend: Registra una devolución de llamadascrollenden el contenedor de desplazamiento o en el documento. - Ejecuta trabajo costoso en la devolución de llamada: Aquí es seguro recuperar contenido dinámico o activar diseños de DOM integrales.
Código de ejemplo
.scroll-container {
height: 300px;
overflow-y: auto;
}
const scroller = document.querySelector('.scroll-container');
// 1. Informative feedback during scroll
scroller.addEventListener('scroll', () => {
// Avoid dynamic heavier data updates here
console.log('Scrolling dynamically... updates deferred');
});
// 2. Safe callback when scrolling rests
scroller.addEventListener('scrollend', () => {
// Run layout recalculations or analytical beacons updates here
const currentVisibleSection = findMostVisibleSection(scroller);
fetchAdditionalData(currentVisibleSection);
});
Implementación estratégica y prácticas recomendadas
- SÍ uses
scrollenden lugar de eventosscrollcon rebote cuando actives balizas de datos de diseño o recuperes dinámicamente un nuevo diseño de contenido. - SÍ considera vincular esto con interacciones de ajuste
scrollSnapChangeoscrollSnapChangingsi estás creando carruseles o diapositivas de galerías de testimonios. - NO agrupes las actualizaciones dinámicas que dependen del diseño dentro de las devoluciones de llamada de desplazamiento visual dinámico.
- SÍ considera que el zoom y el desplazamiento del viewport visual activan el evento
scrollendcorrectamente.
Estrategia de resguardo
En el caso de los navegadores no compatibles, recurre a un evento scroll con rebote con setTimeout para enviar un evento scrollend personalizado.
function initializeDemo() {
const scroller = document.querySelector('#scroller');
scroller.addEventListener('scrollend', () => {
// Safe execution
});
}
if ('onscrollend' in window) {
initializeDemo();
} else {
initializeDemo();
const scroller = document.querySelector('#scroller');
scroller.addEventListener('scroll', () => {
clearTimeout(window.scrollendtimer);
window.scrollendtimer = setTimeout(() => {
scroller.dispatchEvent(new CustomEvent('scrollend'));
}, 100);
});
}