Обработка событий
Зачастую при обработке таких событий как: scroll, click, keyup и т.д. возникает необходимость обрабатывать не каждое событие, а только последнее.
В каких случаях необходимо?
-
Подряд возникает несколько событий с одинаковым типом
-
Нет необходимости в получении результата обработки промежуточных событий
-
Обработка занимает длительное время
Пример №1
Пользователь изменяет количество товара в корзине интернет-магазина
Как мы видим, пересчет корзины происходит не при каждом изменении количества товара, а только после прекращения кликов.
Пересчет происходит на сервере, поэтому нет смысла тратить серверные ресурсы на промежуточные пересчеты, которые устареют за время выполнения XHR-запросов.
Если бы пересчет был моментальный, то пользователь наблюдал бы мельтешащие цифры.
Где еще может пригодиться такое поведение?
- Отображение многоуровневых меню по наведению курсора мыши
- Выпадающие подсказки для строки поиска
- Применение фильтров в каталогах
- и много других случаев
Как реализовать?
По-прежнему необходимо получать каждое событие, но обрабатывать только то, после которого в течение некоторого времени не произошло новых событий.
Для реализации пригодятся таймеры.
При возникновении события можно устанавливать таймер, который будет вызывать итоговый обработчик.
Обычная обработка события
document.addEventListener('click', () => { console.log('clicked') })
Отложенная обработка через таймер
let timer = null document.addEventListener('click', () => { if(timer) window.clearTimeout(timer) timer = window.setTimeout(() => { console.log('clicked') }, 1000) })
Если потребуется сделать несколько подобных обработчиков, то для каждого придется создавать свои переменные таймеров и добавлять однотипный код.
Минусы приведенного примера
Универсальная функция
function debounce(func, time) {
let iTimeout = null
return (...args) => {
if(iTimeout) {
window.clearTimeout(iTimeout)
}
iTimeout = window.setTimeout(() => {
func(...args)
iTimeout = null
}, time)
}
}
const onClickDebounced = debounce(() => { console.log('clicked') }, 1000) document.addEventListener('click', onClickDebounced)
Хорошая реализация функции debounce включена в библиотеку Lodash
Работа с событиями
By evgenysm
Работа с событиями
- 48