Всем привет!
Продолжая экспериментировать с JavaScript, я хотела обновить горизонтальную навигацию, которую ранее создала для GitHubMobile (до текущей адаптивной версии и нативных приложений), и для этого примера панели инструментов Bootstrap.
Цель? Создать отзывчивую горизонтальную навигацию с помощью скролла, которая автоматически прокручивает активную навигационную ссылку в окне просмотра. Адаптивность заключается в том, что навигационные ссылки прокручиваются горизонтально — достаточно легко и масштабируются во всех окнах просмотра. Скроллинг и настройка активной ссылки выполняются на JS и, благодаря работе над предстоящим редизайном Bootstrap, относительно просты.
Вот финальное демо на сайте CodePen.
Посмотрите, что под капотом. Для HTML я использую базовые элементы: <nav>
, <ul>
и навигационные ссылки. <nav>
– это элемент, который прокручивается, а <ul>
всегда содержит ссылки на одну строку.
<header>
<h1>Demo</h1>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">World</a></li>
<li><a href="#">Politics</a></li>
<li><a href="#">Business</a></li>
<li><a href="#">Opinion</a></li>
<li><a href="#" class="active">Tech</a></li>
<li><a href="#">Science</a></li>
<li><a href="#">Health</a></li>
<li><a href="#">Sports</a></li>
<li><a href="#">Arts</a></li>
<li><a href="#">Books</a></li>
<li><a href="#">Style</a></li>
<li><a href="#">Food</a></li>
<li><a href="#">Travel</a></li>
</ul>
</nav>
</header>
Однако CSS для элементов <nav>
и <ul>
становится немного умнее. Я установила фиксированное значение height (равное вычисленной высоте ссылки) и overflow-y на <nav>
, чтобы «обрезать» ссылки внутри. Но это не избавляет от раздражающих полос прокрутки, появляющихся при скролле и, таким образом, закрывающих ссылки. Таким образом, среди ряда дополнительных базовых стилей у элемента <ul>
есть большое значение padding-bottom, позволяющее скрыть любую видимую полосу прокрутки. У такого решения есть свои проблемы юзабилити — полосы прокрутки показывают, что часть интерфейса можно скроллить, есть дополнительный контент и т. д. — но нет элегантного способа решить эту проблему во всех браузерах и на всех устройствах.
nav {
position: relative;
z-index: 2;
height: 2.5rem;
overflow-y: hidden;
scroll-behavior: smooth;
}
ul {
display: flex;
flex-wrap: nowrap;
padding-bottom: 1.5rem;
padding-left: 0;
margin-block: 0;
overflow-x: auto;
list-style: none;
text-align: center;
white-space: nowrap;
}
На стороне JavaScript мы начинаем с запроса селектора, проверяем, существует ли он на странице, и устанавливаем ряд переменных для навигационных ссылок и активной ссылки.
let nav = document.querySelectorAll('nav')
if (nav) {
let navLinks = document.querySelectorAll('nav a')
let activeLink = document.querySelector('.active')
//
}
Наша первая строка JSотвечает за немедленную (при загрузке страницы) прокрутку активной ссылки для просмотра содержащего ее элемента. В CodePen я установила ссылку, которая должна быть за пределами экрана, в качестве элемента .active, чтобы вы могли видеть прокрутку при загрузке страницы. Во время работы над документацией Bootstrap я нашел для этого полезный JS-метод — scrollIntoView.
let nav = document.querySelectorAll('nav')
if (nav) {
let navLinks = document.querySelectorAll('nav a')
let activeLink = document.querySelector('.active')
activeLink.scrollIntoView({ behavior: "smooth", inline: "center" })
//
}
behavior сообщает браузеру, как анимировать скроллинг, в то время как inline указывает браузеру выровнять скролл по горизонтали. (Для вертикального выравнивания, если необходимо, есть параметр block) Отсюда нам нужно добавить eventlistener к каждой навигационной ссылке, чтобы установить класс .active и прокрутить ссылку, по которой щелкнули в окне просмотра. Этот последний фрагмент кода можно было бы очистить с помощью функции scrollIntoView для дедупликации этой строки, но на данный момент это не кажется целесообразным и добавляет немного больше JS.
let nav = document.querySelectorAll('nav')
if (nav) {
let navLinks = document.querySelectorAll('nav a')
let activeLink = document.querySelector('.active')
activeLink.scrollIntoView({ behavior: "smooth", inline: "center" })
navLinks.forEach( function(link) {
link.addEventListener("click", (event) => {
navLinks.forEach( function(link) {
link.classList.remove('active')
})
link.classList.add('active')
link.scrollIntoView({ behavior: "smooth", inline: "center" })
})
})
}
Соберите все это вместе, и вы получите функциональный боковой скролл и адаптивную навигацию. Возможно, вам даже не понадобится переключение класса .active, но здесь он завершает демо, поэтому я добавила его для полноты картины.
Топ коментарі (0)