Навигация по разделам

Waypoints — это лёгкая библиотека для отслеживания позиции элементов на странице относительно области видимости окна браузера. Для её использования необходимо подключить скрипт и убедиться, что DOM полностью загружен. На практике подключение выглядит следующим образом:

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

После подключения создаётся объект Waypoint, который принимает два ключевых параметра: element и handler.

var waypoint = new Waypoint({
  element: document.getElementById('section1'),
  handler: function(direction) {
    console.log('Вы достигли секции 1, направление:', direction);
  },
  offset: '50%' // триггер срабатывает, когда элемент достигает середины окна
});

Ключевые моменты:

  • element — HTML-элемент, за которым необходимо следить.
  • handler — функция, вызываемая при пересечении триггерной линии.
  • offset — смещение триггера относительно верхней границы окна. Может быть в пикселях (100px) или процентах (50%).

Отслеживание направления прокрутки

Waypoints предоставляет возможность различать направление скролла через параметр direction в обработчике:

handler: function(direction) {
  if (direction === 'down') {
    console.log('Пользователь прокрутил вниз');
  } else if (direction === 'up') {
    console.log('Пользователь прокрутил вверх');
  }
}

Это удобно для изменения активного состояния меню навигации, анимации появления элементов и других интерактивных эффектов.


Настройка оффсета для гибкой навигации

Оффсет позволяет управлять моментом срабатывания waypoint.

var waypoint = new Waypoint({
  element: document.getElementById('section2'),
  handler: function(direction) {
    console.log('Триггер сработал!');
  },
  offset: 200 // срабатывание за 200px до верхней границы окна
});

Можно использовать динамические функции для оффсета:

var waypoint = new Waypoint({
  element: document.getElementById('section3'),
  handler: function() {
    console.log('Динамический оффсет!');
  },
  offset: function() {
    return this.element.clientHeight / 2;
  }
});

Функция возвращает значение смещения в пикселях, что позволяет создавать сложные сценарии с секциями разной высоты.


Группы Waypoints и массовая активация

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

var waypoint = new Waypoint({
  element: document.getElementById('section4'),
  handler: function(direction) {
    console.log('Групповое событие сработало');
  },
  group: 'navigation'
});

Группы позволяют контролировать последовательность срабатывания и применять методы массового включения/отключения waypoint’ов:

Waypoint.Group.findOrCreate({ name: 'navigation' }).disable();
Waypoint.Group.findOrCreate({ name: 'navigation' }).enable();

Sticky навигация с помощью Waypoints

Одной из распространённых задач является фиксация меню при прокрутке. Для этого создаётся waypoint на верхней границе меню:

var sticky = new Waypoint.Sticky({
  element: document.getElementById('menu')
});

Элемент автоматически получает класс .stuck при пересечении верхней границы окна, что позволяет подключить CSS для фиксации позиции:

.stuck {
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 1000;
}

Активация меню по текущей секции

Для навигации по разделам часто используют подсветку активного пункта меню. Алгоритм:

  1. Создаём waypoint для каждой секции.
  2. В обработчике добавляем класс активного состояния к соответствующему пункту меню.
  3. Снимаем класс с предыдущих пунктов.
var sections = document.querySelectorAll('section');
sections.forEach(function(section) {
  new Waypoint({
    element: section,
    handler: function(direction) {
      document.querySelectorAll('.menu a').forEach(function(link) {
        link.classList.remove('active');
      });
      document.querySelector(`.menu a[href="#${section.id}"]`).classList.add('active');
    },
    offset: '25%'
  });
});

Особенности:

  • Смещение 25% позволяет активировать секцию заранее, когда пользователь ещё прокручивает верхнюю часть следующей секции.
  • Использование href="#id" связывает пункты меню с идентификаторами секций для точной навигации.

Очистка и уничтожение Waypoints

Waypoints создаёт объекты, которые могут оставаться в памяти, поэтому для динамических страниц важно освобождать ресурсы:

var wp = new Waypoint({
  element: document.getElementById('section5'),
  handler: function() {
    console.log('Событие сработало');
  }
});

// позже, если секция удаляется
wp.destroy();

Метод destroy() удаляет waypoint и освобождает внутренние слушатели событий.


Интеграция с анимацией

Waypoints часто используют совместно с CSS-анимациями или библиотеками вроде Animate.css. Событие срабатывания waypoint может запускать анимацию:

new Waypoint({
  element: document.getElementById('feature'),
  handler: function() {
    this.element.classList.add('animate__fadeInUp');
  },
  offset: '80%'
});

Такой подход позволяет оживлять контент при прокрутке, не нагружая браузер постоянными событиями скролла.


События на уровне окна и кастомизация

Waypoints позволяет контролировать события через глобальные триггеры scroll и resize. Можно обновлять waypoint после изменения размеров окна:

window.addEventListener('resize', function() {
  Waypoint.refreshAll();
});

Это гарантирует, что все смещения и триггеры корректно пересчитаются для адаптивной верстки.


Использование бесфреймворковых и jQuery версий

Waypoints доступен в двух вариантах: чистый JavaScript и с поддержкой jQuery. jQuery-версия упрощает синтаксис:

$('#section6').waypoint(function(direction) {
  console.log('jQuery waypoint сработал', direction);
}, { offset: '50%' });

Для проектов без jQuery рекомендуется использовать noframework вариант, чтобы минимизировать зависимость и размер скрипта.


Waypoints предоставляет гибкие возможности для создания навигации по разделам, интерактивных эффектов при прокрутке, sticky-меню и анимации контента. С помощью настроек offset, group и методов управления waypoint’ами можно реализовать как простую подсветку меню, так и сложные динамические интерфейсы с адаптивной реакцией на скролл.