Активные состояния навигации позволяют визуально выделять текущий раздел страницы в меню при прокрутке. В сочетании с библиотекой Smooth Scroll это достигается динамическим отслеживанием положения скролла и синхронизацией с ссылками навигации.
Основной подход заключается в том, чтобы каждая ссылка на секцию
страницы имела уникальный идентификатор, а скрипт отслеживал, какая
секция видна в данный момент. При совпадении активная ссылка получает
CSS-класс, например active, который стилизуется
визуально.
<nav>
<ul>
<li><a href="#section1" class="nav-link">Раздел 1</a></li>
<li><a href="#section2" class="nav-link">Раздел 2</a></li>
<li><a href="#section3" class="nav-link">Раздел 3</a></li>
</ul>
</nav>
<section id="section1">...</section>
<section id="section2">...</section>
<section id="section3">...</section>
Библиотека Smooth Scroll обеспечивает плавный переход при клике на якорные ссылки. Инициализация выполняется следующим образом:
const scroll = new SmoothScroll('a[href*="#"]', {
speed: 600,
offset: 0,
clip: true,
});
Для динамического обновления активного состояния необходимо определить момент, когда верхняя граница секции пересекает определённую точку окна. Обычно используют верх окна или центр видимой области.
const sections = document.querySelectorAll('section');
const navLinks = document.querySelectorAll('.nav-link');
function activateNav() {
let scrollPos = window.scrollY + window.innerHeight / 2;
sections.forEach((section, index) => {
if (scrollPos >= section.offsetTop && scrollPos < section.offsetTop + section.offsetHeight) {
navLinks.forEach(link => link.classList.remove('active'));
navLinks[index].classList.add('active');
}
});
}
window.addEventListener('scroll', activateNav);
Smooth Scroll позволяет отслеживать завершение анимации перехода, чтобы корректно активировать ссылку:
scroll.on('scrollEnd', function (anchor, toggle) {
navLinks.forEach(link => link.classList.remove('active'));
if (toggle) toggle.classList.add('active');
});
При изменении размеров окна положение секций относительно видимой области меняется. Для корректной работы активных состояний важно пересчитывать координаты:
window.addEventListener('resize', () => {
sections.forEach(section => {
section.dataset.top = section.offsetTop;
});
});
data-top для оптимизации
вычислений при скролле.requestAnimationFrame для обработки
события scroll, чтобы избежать лагов при высокой частоте
событий:let ticking = false;
window.addEventListener('scroll', () => {
if (!ticking) {
window.requestAnimationFrame(() => {
activateNav();
ticking = false;
});
ticking = true;
}
});
Ключевой момент — визуальное выделение текущей ссылки:
.nav-link.active {
color: #ff6600;
font-weight: bold;
border-bottom: 2px solid #ff6600;
}
Для многоуровневых навигаций логика не меняется, но важно корректно
отслеживать вложенные секции. Для этого создаются отдельные массивы
ссылок и секций, либо используется рекурсивный поиск
querySelectorAll.
requestAnimationFrame для
плавности.Эта схема обеспечивает точное, визуально корректное отображение активного состояния навигации на странице с плавной прокруткой.