JQuery: отложенный вызов функции после окончания ресайза
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Для того чтобы событие resize
начинало выполняться лишь после окончания изменения размеров окна, применяйте демпфер (debouncer), основанный на функции setTimeout
:
let resizeTimer;
$(window).resize(function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
// Ваш код будет выполнен только после того, как изменение размеров окончено
console.log('Изменение размеров окна завершено!');
}, 250); // Задержка составляет 250 миллисекунд
});
В данном коде используется задержка, создаваемая при помощи функции setTimeout
. Она каждый раз сбрасывается при новом событии resize
. Выполнение команды clearTimeout
гарантирует выполнение функции только один раз, и это произойдет после последнего события изменения размера. Задержку (в данном случае она равна 250 мс) можно настроить в соответствии с требованиями вашего проекта.
Освоение принципа работы демпфирования
Демпфирование (Debouncing) позволяет эффективно регулировать частоту возникновения событий. Если события начинают происходить слишком быстро и часто, это снижает производительность. Демпфирование обеспечивает начало работы события лишь после того, как проходит определенный промежуток времени бездействия.
Настройка времени демпфирования
Вам, как и акробату на канате, потребуется найти баланс между быстрой реакцией на события и оптимальной производительностью, настроив время демпфирования. Если задержка в 250 мс кажется вам слишком длинной, сократите ее. Если события изменения размеров возникают слишком часто, увеличьте время задержки. Настройте его исходя из специфики вашего приложения.
Исключаем незначительные события
Следует использовать некоторые подходы для отсеивания незначительных изменений размера окна, например, тех, которые происходят при появлении полос прокрутки:
- Отключите полосы прокрутки, меняя свойство
overflow
элементаbody
во время изменения размера окна. - Запоминайте и сравнивайте размеры окна перед выполнением кода, чтобы удостовериться, что изменения действительно произошли.
let lastWidth = $(window).width(), lastHeight = $(window).height();
$(window).resize(function() {
let newWidth = $(window).width(), newHeight = $(window).height();
if(newWidth !== lastWidth || newHeight !== lastHeight){
lastWidth = newWidth;
lastHeight = newHeight;
// Здесь выполняйте необходимые действия
}
});
Визуализация
Можно представить демпфер как пост на шоссе:
На шоссе (🛣️) расположен пост (🚧), который пропускает транспорт через себя с определенной периодичностью:
| Действие | Транспортное движение | Изменение размеров окна |
| -------------------- | --------------------- | ---------------------- |
| Непрерывное движение | 🚗🚕🚗🚕🚗🚕🚗🚕🚗 | Изменение размеров |
| Работа поста | 🚧 ... ... 🚧 ОТКРЫТО! | Сработал демпфер |
| Один проезд | 🚗 (Проезд разрешен) | Событие запущено |
Подобно посту, демпфер позволяет событию начать работу только после того, как прекращаются изменения размеров.
Хранение идентификатора таймаута изменения размеров
Чтобы не нарушать глобальный контекст, для надежного хранения идентификаторов таймеров используйте jQuery.data()
:
$(window).resize(function() {
let timeoutId = $.data(this, 'resizeTimer');
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
// Выполните нужные действия здесь
}, 300);
$.data(this, 'resizeTimer', timeoutId);
});
Используйте плагины или вспомогательные функции
Если вы предпочитаете не углубляться в детали реализации демпфирования, воспользуйтесь готовыми решениями, предлагаемыми плагинами для jQuery, например, jQuery Throttle/Debounce от Бена Алмана, или функциями из библиотек Underscore.js и Lodash:
$(window).resize(_.debounce(function() {
// Вставьте сюда ваш код
}, 250));