Боковые меню

Боковые меню часто используются для навигации по одностраничным сайтам или большим интерфейсам. Плавная прокрутка обеспечивает более удобный пользовательский опыт при переходе между разделами. Для реализации этого в JavaScript применяется библиотека Smooth Scroll, которая позволяет управлять анимацией скролла к элементам страницы с высокой точностью.


Инициализация Smooth Scroll

Для начала необходимо подключить библиотеку к проекту:

<script src="https://cdn.jsdelivr.net/npm/smooth-scroll@16/dist/smooth-scroll.polyfills.min.js"></script>

После подключения создаётся экземпляр Smooth Scroll, указывая селекторы ссылок, которые будут вызывать плавный скролл:

const scroll = new SmoothScroll('a[href^="#"]', {
  speed: 600,           // скорость анимации в миллисекундах
  offset: 50,           // смещение от верхней границы экрана
  easing: 'easeInOutCubic', // тип кривой анимации
});

Пояснения параметров:

  • speed – определяет длительность анимации скролла.
  • offset – позволяет корректировать точку назначения, например, если фиксированное меню перекрывает заголовок.
  • easing – задаёт тип ускорения анимации, делая скролл более естественным.

Структура бокового меню

Боковое меню обычно оформляется списком ссылок:

<nav class="sidebar">
  <ul>
    <li><a href="#section1">Раздел 1</a></li>
    <li><a href="#section2">Раздел 2</a></li>
    <li><a href="#section3">Раздел 3</a></li>
  </ul>
</nav>

<section id="section1">...</section>
<section id="section2">...</section>
<section id="section3">...</section>

Каждая ссылка содержит href с идентификатором целевого блока. Smooth Scroll автоматически перехватывает клик и выполняет анимацию.


Динамическая подсветка активного раздела

Для улучшения навигации полезно подсвечивать активный пункт меню при прокрутке. Это реализуется через обработчик события scroll:

const sections = document.querySelectorAll('section');
const menuLinks = document.querySelectorAll('.sidebar a');

window.addEventListener('scroll', () => {
  let current = '';

  sections.forEach(section => {
    const sectionTop = section.offsetTop - 60;
    if (pageYOffset >= sectionTop) {
      current = section.getAttribute('id');
    }
  });

  menuLinks.forEach(link => {
    link.classList.remove('active');
    if (link.getAttribute('href') === `#${current}`) {
      link.classList.add('active');
    }
  });
});

Объяснение алгоритма:

  1. Определяется верхняя граница каждого раздела с учётом смещения (offset).
  2. Проверяется, какой раздел сейчас находится в зоне видимости.
  3. Подсвечивается соответствующая ссылка в меню.

Расширенные возможности Smooth Scroll

Библиотека поддерживает дополнительные функции, полезные для боковых меню:

  • Callback функции – позволяют выполнять действия после окончания прокрутки:
const scroll = new SmoothScroll('a[href^="#"]', {
  speed: 600,
  offset: 50,
  after: () => {
    console.log('Прокрутка завершена');
  }
});
  • Контроль скролла через API – можно программно запускать прокрутку к любому элементу:
scroll.animateScroll(document.querySelector('#section2'));
  • Поддержка динамически созданных ссылок – при добавлении новых пунктов меню после загрузки страницы достаточно вызвать scroll.destroy() и инициализировать Smooth Scroll заново, чтобы подключить новые элементы.

Интеграция с адаптивными боковыми меню

Для мобильных устройств боковое меню часто скрывается за «гамбургером». Smooth Scroll сохраняет плавность скролла даже при динамическом открытии/закрытии меню:

const menuButton = document.querySelector('.menu-toggle');
const sidebar = document.querySelector('.sidebar');

menuButton.addEventListener('click', () => {
  sidebar.classList.toggle('open');
});

При клике по ссылке внутри меню рекомендуется автоматически закрывать его:

menuLinks.forEach(link => {
  link.addEventListener('click', () => {
    sidebar.classList.remove('open');
  });
});

Настройка смещения для фиксированных заголовков

Если сайт использует фиксированный шапочный блок, необходимо корректировать точку прокрутки:

const scroll = new SmoothScroll('a[href^="#"]', {
  speed: 600,
  offset: () => document.querySelector('.header').offsetHeight
});

Здесь offset задаётся функцией, которая вычисляет текущую высоту шапки динамически. Это удобно при изменении размеров шапки на разных разрешениях.


Поддержка инерционной прокрутки и пользовательских кривых

Smooth Scroll позволяет настроить кривые ускорения (easing) для более естественного движения:

  • linear – равномерная скорость.
  • easeInQuad – плавное ускорение.
  • easeOutCubic – замедление перед остановкой.
  • easeInOutCubic – ускорение и замедление, наиболее естественный эффект.
const scroll = new SmoothScroll('a[href^="#"]', {
  speed: 800,
  easing: 'easeInOutCubic'
});

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


Обработка внутренних и внешних ссылок

Smooth Scroll можно настроить так, чтобы игнорировать внешние ссылки:

const scroll = new SmoothScroll('a[href^="#"]:not([data-no-scroll])', {
  speed: 600
});

Добавление атрибута data-no-scroll позволяет гибко управлять поведением меню.


Применение Smooth Scroll с динамическими компонентами

Если контент страницы загружается через AJAX или фреймворки вроде Vue или React, необходимо пересоздавать экземпляр Smooth Scroll после вставки новых разделов:

// после загрузки нового контента
scroll.destroy();
scroll = new SmoothScroll('a[href^="#"]', {
  speed: 600,
  offset: 50
});

Это гарантирует, что ссылки на новые секции будут корректно обрабатывать прокрутку.


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