Удалите свои функции тайм-аута и избавьтесь от их ошибок, вот событие, которое вам действительно нужно: scrollend.
До появления события scrollend не существовало надежного способа определить завершение прокрутки. Это означало, что события срабатывали с задержкой или когда палец пользователя еще находился на экране. Эта ненадежность в определении фактического завершения прокрутки приводила к ошибкам и ухудшению пользовательского опыта.
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
В лучшем случае стратегия setTimeout() может определить, остановилась ли прокрутка на 100ms . Это больше похоже на событие паузы прокрутки, а не на событие завершения прокрутки.
После события scrollend браузер выполняет всю эту сложную обработку данных за вас.
document.onscrollend = event => {…}
Вот это действительно круто. Идеально рассчитано по времени и содержит множество важных условий перед запуском.
Попробуйте!
Подробности мероприятия
Событие scrollend срабатывает, когда: - Браузер больше не анимирует или не перемещает прокрутку. - Пользователь отпустил палец на экране. - Указатель мыши отпустил ползунок прокрутки. - Пользователь отпустил клавишу. - Прокрутка до фрагмента завершена. - Привязка к прокрутке завершена. - scrollTo() завершена. - Пользователь прокрутил визуальную область просмотра.
Событие scrollend не срабатывает в следующих случаях: - Жест пользователя не привел к изменению положения прокрутки (перемещение не произошло). - scrollTo() не привела к перемещению.
Одна из причин, по которой это событие так долго не появлялось на веб-платформе, заключалась в множестве мелких деталей, требующих детальной спецификации. Одной из самых сложных областей было описание обработки события scrollend для визуального окна просмотра по сравнению с документом. Рассмотрим веб-страницу, которую вы увеличиваете. Вы можете прокручивать страницу в этом увеличенном состоянии, и это не обязательно означает прокрутку документа. Будьте уверены, что даже такое взаимодействие пользователя с визуальной областью просмотра будет генерировать событие scrollend после завершения прокрутки.
Использование события
Как и в случае с другими событиями прокрутки, вы можете зарегистрировать обработчики событий несколькими способами.
addEventListener("scrollend", (event) => {
// scroll ended
});
aScrollingElement.addEventListener("scrollend", (event) => {
// scroll ended
});
или используйте свойство события:
document.onscrollend = (event) => {
// scroll ended
};
aScrollingElement.onscrollend = (event) => {
// scroll ended
};
Полифилы и прогрессивное улучшение
Если вы хотите использовать это новое событие прямо сейчас, вот наш лучший совет. Вы можете продолжать использовать свою текущую стратегию завершения прокрутки (если она у вас есть), а в начале проверить поддержку с помощью:
'onscrollend' in window
// true, if available
Это будет сообщать значение true или false в зависимости от того, поддерживает ли браузер это событие. С помощью этой проверки вы можете разветвить код:
if ('onscrollend' in window) {
document.onscrollend = callback
}
else {
document.onscroll = event => {
clearTimeout(window.scrollEndTimer)
window.scrollEndTimer = setTimeout(callback, 100)
}
}
Это хорошее начало для постепенного улучшения вашего события scrollend , когда оно станет доступно. Вы также можете попробовать созданный мной полифил ( NPM ), который делает все возможное, что может предложить браузер:
import {scrollend} from "scrollyfills"
// then use scrollend as if it's existed this whole time
document.onscrollend = callback
Полифил будет постепенно улучшаться, чтобы использовать встроенное в браузер событие scrollend , если оно доступно. Если оно недоступно, скрипт отслеживает события указателя и прокрутки, чтобы максимально точно определить момент окончания события.
Варианты использования
Рекомендуется избегать ресурсоемких вычислительных операций во время прокрутки. Это гарантирует, что прокрутка будет использовать как можно больше памяти и вычислительных ресурсов, обеспечивая плавную работу. Использование события scrollend идеально подходит для вызова и выполнения сложной работы, поскольку прокрутка уже не происходит.
Событие scrollend можно использовать для запуска различных действий. Распространенный пример использования — синхронизация связанных элементов пользовательского интерфейса с позицией, в которой остановилась прокрутка. Например: — Синхронизация позиции прокрутки карусели с точечным индикатором. — Синхронизация элемента галереи с его метаданными. — Получение данных после того, как пользователь прокрутит страницу до новой вкладки.
Представьте себе ситуацию, когда пользователь пролистывает электронное письмо. После того, как он закончит пролистывание, вы можете выполнить действие в зависимости от того, куда он прокрутил страницу.
Это событие также можно использовать для синхронизации после программной или пользовательской прокрутки, а также для таких действий, как запись аналитических данных.
Вот хороший пример, где несколько элементов, таких как стрелки, точки и фокус, необходимо обновлять в зависимости от положения прокрутки. Посмотрите, как я создал эту карусель, на YouTube . Также попробуйте демонстрацию в реальном времени .
Благодарим Мехди Каземи за инженерную работу над этим проектом и Роберта Флэка за помощь в разработке API и внедрении.