Удалите функции таймаута и избавьтесь от их ошибок. Вот событие, которое вам действительно нужно: прокрутка.
До события 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
});
или используйте свойство event:
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 и руководство по реализации.