Прогресс-бар прокрутки

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

<!-- jQuery (если используется jQuery-версия) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

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

После подключения скрипта можно создавать новые точки отслеживания прокрутки (waypoints) для элементов страницы.


Создание прогресс-бара при прокрутке

Прогресс-бар прокрутки показывает пользователю, сколько страницы уже просмотрено. Для его реализации потребуется:

  1. HTML-элемент прогресс-бара.
  2. CSS для стилизации.
  3. JavaScript для динамического обновления ширины элемента.

HTML пример:

<div id="scroll-progress-container">
  <div id="scroll-progress-bar"></div>
</div>

CSS стили:

#scroll-progress-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 5px;
  background-color: rgba(0,0,0,0.1);
  z-index: 9999;
}

#scroll-progress-bar {
  width: 0%;
  height: 100%;
  background-color: #4caf50;
  transition: width 0.1s linear;
}

Расчет прогресса прокрутки

Для корректного отображения прогресса необходимо вычислять отношение текущей прокрутки к общей высоте документа:

function updateProgressBar() {
  const scrollTop = window.scrollY;
  const docHeight = document.documentElement.scrollHeight - window.innerHeight;
  const scrollPercent = (scrollTop / docHeight) * 100;
  document.getElementById('scroll-progress-bar').style.width = scrollPercent + '%';
}

window.addEventListener('scroll', updateProgressBar);

В этом примере ширина прогресс-бара обновляется при каждом событии прокрутки, обеспечивая плавное заполнение.


Интеграция Waypoints с прогресс-баром

Waypoints позволяет выполнять действия при достижении определенных элементов. Можно использовать Waypoints для более детальной анимации прогресс-бара на конкретных секциях страницы.

Пример: подсветка прогресс-бара по секциям

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

sections.forEach((section, index) => {
  new Waypoint({
    element: section,
    handler: function(direction) {
      const progressPercent = ((index + 1) / sections.length) * 100;
      document.getElementById('scroll-progress-bar').style.width = progressPercent + '%';
    },
    offset: '50%' // Триггер срабатывает когда секция достигает середины экрана
  });
});
  • element — элемент, к которому привязан waypoint.
  • handler — функция, вызываемая при пересечении точки.
  • offset — расстояние от верхней границы окна, при котором срабатывает waypoint.

Использование offset позволяет запускать прогресс-анимацию заранее или при достижении центра элемента.


Обратное действие при прокрутке вверх

Waypoints поддерживает определение направления прокрутки (down или up), что позволяет корректно обновлять прогресс при движении вверх:

new Waypoint({
  element: section,
  handler: function(direction) {
    if (direction === 'down') {
      document.getElementById('scroll-progress-bar').style.width = ((index + 1) / sections.length) * 100 + '%';
    } else {
      document.getElementById('scroll-progress-bar').style.width = (index / sections.length) * 100 + '%';
    }
  },
  offset: '50%'
});

Это обеспечивает точное отражение прогресса, независимо от направления прокрутки.


Использование Sticky-прогресс-бара

Для закрепления прогресс-бара в верхней части окна можно комбинировать CSS position: fixed и Waypoints для динамического изменения цвета или стиля при достижении определенных секций:

sections.forEach(section => {
  new Waypoint({
    element: section,
    handler: function(direction) {
      if (direction === 'down') {
        document.getElementById('scroll-progress-bar').style.backgroundColor = section.dataset.color;
      } else {
        document.getElementById('scroll-progress-bar').style.backgroundColor = '#4caf50';
      }
    },
    offset: '0%'
  });
});

Использование data-color на секциях позволяет менять цвет прогресс-бара в зависимости от контента.


Оптимизация производительности

  • Использовать requestAnimationFrame при обновлении прогресс-бара для снижения нагрузки на рендеринг.
  • Объединять несколько waypoint’ов в одну функцию, чтобы уменьшить количество обработчиков.
  • Настраивать offset с учетом размера элементов и визуальной логики страницы.

Пример с requestAnimationFrame:

let ticking = false;

function onScroll() {
  if (!ticking) {
    window.requestAnimationFrame(function() {
      updateProgressBar();
      ticking = false;
    });
    ticking = true;
  }
}

window.addEventListener('scroll', onScroll);

Такой подход минимизирует количество вызовов updateProgressBar и делает анимацию плавной даже на больших страницах.


Адаптивность и кроссбраузерность

  • Прогресс-бар, созданный с помощью Waypoints, корректно работает на мобильных устройствах при использовании window.innerHeight и scrollY.
  • Для старых браузеров рекомендуется использовать полифиллы для requestAnimationFrame и Element.scrollHeight.
  • Плавные CSS-трансформации (transition) лучше поддерживаются в современных браузерах, но fallback на мгновенное изменение ширины обеспечит базовую функциональность.

Дополнительные возможности

Waypoints позволяет расширять функционал прогресс-бара:

  1. Анимация заливки прогресс-бара разными цветами для каждой секции.
  2. Использование горизонтального прогресса для лендингов с прокруткой вбок.
  3. Взаимодействие с другими библиотеками анимации, например, GSAP, для сложных визуальных эффектов.

Комбинирование Waypoints с прогресс-баром открывает возможности создания динамичных интерфейсов, полностью синхронизированных с прокруткой страницы.