Асинхронные операции в handler

Waypoints — это легковесная библиотека для отслеживания прокрутки элементов на странице и вызова функций при достижении определённых точек. Одной из ключевых особенностей является возможность выполнения асинхронных операций внутри обработчиков событий (handler), что позволяет интегрировать динамическое поведение, задержки и сетевые запросы при прокрутке страницы.


Подключение Waypoints

Для начала необходимо подключить библиотеку. Waypoints доступна как через CDN, так и через пакетный менеджер npm:

<script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/noframework.waypoints.min.js"></script>

или через npm:

npm install waypoints

После подключения создаётся новый waypoint для элемента:

const waypoint = new Waypoint({
  element: document.querySelector('#target'),
  handler: function(direction) {
    // Здесь будет асинхронная логика
  },
  offset: '50%' // точка срабатывания на 50% высоты окна
});

Асинхронные функции в handler

Handler Waypoints может быть как обычной функцией, так и async function, что позволяет использовать await внутри обработчика:

const waypoint = new Waypoint({
  element: document.querySelector('#target'),
  handler: async function(direction) {
    console.log('Waypoint сработал', direction);
    const data = await fetchDataFromAPI();
    renderData(data);
  },
  offset: '75%'
});

Здесь:

  • fetchDataFromAPI() — функция, возвращающая промис, например запрос к серверу через fetch.
  • await приостанавливает выполнение обработчика до получения результата, не блокируя основной поток браузера.
  • Можно использовать try/catch для обработки ошибок асинхронных операций.

Примеры асинхронных операций

Загрузка данных при прокрутке

async function fetchDataFromAPI() {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
  if (!response.ok) throw new Error('Ошибка загрузки данных');
  return response.json();
}

const waypoint = new Waypoint({
  element: document.querySelector('#data-section'),
  handler: async function(direction) {
    try {
      const post = await fetchDataFromAPI();
      const container = document.querySelector('#post-container');
      container.innerHTML = `<h2>${post.title}</h2><p>${post.body}</p>`;
    } catch (err) {
      console.error(err);
    }
  },
  offset: '80%'
});

Задержка перед выполнением действия

Асинхронные обработчики позволяют легко реализовать задержку:

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

const waypoint = new Waypoint({
  element: document.querySelector('#delayed-action'),
  handler: async function(direction) {
    console.log('Начало задержки');
    await delay(1000); // задержка 1 секунда
    console.log('Действие выполнено после задержки');
  },
  offset: '60%'
});

Важные нюансы использования

  1. Состояние элемента: Waypoints срабатывает каждый раз при пересечении точки срабатывания. Асинхронная операция может быть вызвана несколько раз, если элемент прокручивается туда и обратно. Чтобы избежать повторного вызова, используют флаг:
let hasLoaded = false;

const waypoint = new Waypoint({
  element: document.querySelector('#once-section'),
  handler: async function(direction) {
    if (hasLoaded) return;
    hasLoaded = true;
    await loadContent();
  },
  offset: '70%'
});
  1. Обработка ошибок: Любая ошибка в async handler не ломает выполнение страницы, но её нужно обрабатывать через try/catch. Иначе она будет выброшена в консоль браузера.

  2. Производительность: Долгие асинхронные операции внутри handler могут влиять на плавность прокрутки, особенно на слабых устройствах. Рекомендуется минимизировать тяжёлую работу и использовать requestAnimationFrame или setTimeout для тяжелых визуальных изменений.


Использование нескольких waypoint с асинхронными операциями

Можно комбинировать несколько waypoint, каждый с асинхронным handler, чтобы создавать последовательные эффекты при прокрутке:

const waypoints = document.querySelectorAll('.section');

waypoints.forEach((section, index) => {
  new Waypoint({
    element: section,
    handler: async function(direction) {
      console.log(`Секция ${index} достигнута`);
      await loadSectionContent(index);
    },
    offset: '50%'
  });
});

Асинхронные эффекты и анимация

Асинхронные функции отлично подходят для интеграции с библиотеками анимаций, такими как GSAP:

const waypoint = new Waypoint({
  element: document.querySelector('#animate'),
  handler: async function(direction) {
    await gsap.to('#animate', { opacity: 1, duration: 1 });
  },
  offset: '75%'
});

Здесь await гарантирует завершение анимации перед выполнением последующих действий.


Асинхронные операции в handler Waypoints позволяют строить динамичные, отзывчивые интерфейсы, интегрировать сетевые запросы, анимации и задержки. Ключевые моменты: использовать async/await, контролировать повторные вызовы и обрабатывать ошибки, чтобы прокрутка оставалась плавной, а функционал надёжным.