Прокрутка на веб-страницах должна быть плавной и быстрой. Выполнение тяжелых задач, таких как перерасчет макета, отслеживание маяков аналитических данных или динамические обновления DOM, во время прокрутки может насытить основной поток, что приведет к потере кадров и сбою макета.
Раньше разработчики использовали устранение дребезга контактов события scroll с помощью setTimeout(), чтобы определить, когда прокрутка завершена. Однако эти функции дебаунсинга известны своей ненадежностью. Они могут сработать, пока пользователь ещё прокручивает страницу.
Событие scrollend – это надежное решение, ориентированное на эффективность. Браузер запускает событие scrollend, когда прокрутка останавливается, все переходы завершаются и пользователь отпускает экран.
Как реализовать
Чтобы реализовать шаблон отложенной работы:
- Настройте прокручиваемый контейнер. Создайте контейнер с помощью
overflow: autoилиoverflow: scroll. - Прослушивание событий
scroll. Используйте этот прослушиватель только для базовых динамических показателей или информативного оформления макета. Не выполняйте здесь тяжелую работу. - Прослушивание событий
scrollend. Зарегистрируйте обратный вызовscrollendв контейнере прокрутки или в самом документе. - Выполняйте ресурсоемкие задачи в обратном вызове. Это безопасный способ получать динамический контент или запускать сложные макеты DOM.
Пример кода
.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);
});
Стратегическое внедрение и рекомендации
- РЕКОМЕНДУЕТСЯ использовать
scrollendвместо событийscrollс дебаунсингом при отправке веб-маяков с данными о макете или динамическом получении нового макета контента. - РЕКОМЕНДУЕТСЯ использовать этот атрибут вместе с взаимодействиями
scrollSnapChangeилиscrollSnapChanging, если вы создаете карусели или слайды с отзывами. - НЕ объединяйте динамические обновления, зависящие от макета, в обратных вызовах динамической визуальной прокрутки.
- РЕКОМЕНДУЕТСЯ учитывать, что масштабирование и прокрутка области просмотра корректно активируют событие
scrollend.
Резервная стратегия
Для неподдерживаемых браузеров используйте событие scroll с setTimeout, чтобы отправлять специальное событие scrollend.
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);
});
}