изменение цвета ссылки в зависимости от пролистывания к якорю в закреплённом меню
как сделать, чтобы цвет ссылки менялся при прокрутке страницы к нужному якорю, меню при этом закреплено?
Ответы (3 шт):
Автор решения: Meth0d
→ Ссылка
// создаем переменную со всеми ссылками
const links = document.querySelectorAll('.links')
// навешиваем на каждую обработчик события "клик"
links.forEach(link => link.addEventListener('click', () => {
// находим уже активную ссылку
const active = document.querySelector('.link.active')
// если она есть, снимаем с нее класс active
active && active.classList.remove('active')
// накидываем класс active на ту ссылку на которую мы нажали
link.classList.add('active')
}))
соответственно так же прописываем классу active нужные стили
Автор решения: soledar10
→ Ссылка
Пример 1
const sections = document.querySelectorAll("section");
const navbarLinks = document.querySelectorAll(".navbar__link");
const navbarHeight = document.querySelector(".navbar").offsetHeight;
window.addEventListener('scroll', () => {
let current = "";
sections.forEach(section => {
const sectionTop = section.offsetTop;
if (pageYOffset >= sectionTop - navbarHeight) {
current = section.getAttribute("id");
}
});
navbarLinks.forEach(link => {
link.classList.remove("is-active");
if (link.classList.contains(current)) {
link.classList.add("is-active");
}
});
})
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
}
.navbar {
position: fixed;
top: 0;
left: 0;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
background-color: #000;
width: 100%;
}
.navbar__link {
padding: .5rem 1rem;
color: #fff;
}
.navbar__link.is-active {
color: #f00;
}
section {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-size: 10vw;
background-color: #ccc;
}
section:nth-of-type(even) {
background-color: #ddd;
}
<nav class="navbar">
<a href="#s1" class="navbar__link s1 is-active">Link 1</a>
<a href="#s2" class="navbar__link s2">Link 2</a>
<a href="#s3" class="navbar__link s3">Link 3</a>
<a href="#s4" class="navbar__link s4">Link 4</a>
</nav>
<section id="s1">Section 1</section>
<section id="s2">Section 2</section>
<section id="s3">Section 3</section>
<section id="s4">Section 4</section>
<footer>Footer</footer>
Пример 2
window.addEventListener('DOMContentLoaded', () => {
const observerCallback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting && entry.intersectionRatio >= .5) {
document.querySelector('.is-active').classList.remove('is-active');
const id = entry.target.getAttribute("id");
const newLink = document.querySelector('[href="#' + id + '"]').classList.add('is-active');
}
});
};
const options = {
threshold: .5,
};
const observer = new IntersectionObserver(observerCallback, options);
const sections = document.querySelectorAll('section');
sections.forEach((section) => observer.observe(section));
});
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
}
.navbar {
position: fixed;
top: 0;
left: 0;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
background-color: #000;
width: 100%;
}
.navbar__link {
padding: .5rem 1rem;
color: #fff;
}
.navbar__link.is-active {
color: #f00;
}
section {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-size: 10vw;
background-color: #ccc;
}
section:nth-of-type(even) {
background-color: #ddd;
}
<nav class="navbar">
<a href="#s1" class="navbar__link is-active">Link 1</a>
<a href="#s2" class="navbar__link">Link 2</a>
<a href="#s3" class="navbar__link">Link 3</a>
<a href="#s4" class="navbar__link">Link 4</a>
</nav>
<section id="s1">Section 1</section>
<section id="s2">Section 2</section>
<section id="s3">Section 3</section>
<section id="s4">Section 4</section>
<footer>Footer</footer>
Автор решения: puffleeck
→ Ссылка
#ody{
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
}
.y{
border: 1px solid green;
grid-row: 1;
}
.y:nth-child(1){grid-column: 1;}
.y:nth-child(2){grid-column: 2;}
.y:nth-child(3){grid-column: 3;}
.y:nth-child(4){grid-column: 4;}
.y:after{
content: 'xyz';
position: fixed;
}
:target ~ .y{color: red}
.x{
grid-column: 1 / 5;
border: 1px solid violet;
height: 100vh;
}
<b id='ody'>
<div id='div1' class='x'>aaaa</div>
<a href='#div1' class='y'>a1</a>
<div id='div2' class='x'>aaaa</div>
<a href='#div2' class='y'>a2</a>
<div id='div3' class='x'>aaaa</div>
<a href='#div3' class='y'>a3</a>
<div id='div4' class='x'>aaaa</div>
<a href='#div4' class='y'>a4</a>
</b>
осталось только слушалку скрола повесить с подменой хэша(location.hash \ history.hash)
правда так порядок пунктов меню не самый адекватный получается, но всё таки...
