Reputation: 35
Been struggling with a problem for a few days now. So, when I can't figure it out myself I went to the forum. Hope you guys can help me figure it out.
For the navbar, the items will light up when the user reached the section. That's all good. But when I scroll down and click away the item still lights up. I guess the observer doesn't remove the class. I can't figure out how I could do this.
I made a codepen to illustrate the code and the problem. Hope my question is clear enough.
Thanks in advance!
https://codepen.io/tijmenjacobs/pen/wvdeaow
const checkForSections = () => {
const optionsSections = {
root: null,
rootMargin: "-350px -150px",
threshold: .9
};
const addHighlightClass = (entries) => {
const [entry] = entries;
const id = entry.target.getAttribute("id");
if (entry.isIntersecting) {
document
.querySelector(`.navbar__link[href="#${id}"]`)
.parentElement.classList.add("highlight");
} else {
document
.querySelector(`.navbar__link[href="#${id}"]`)
.parentElement.classList.remove("highlight");
}
};
const observer = new IntersectionObserver(addHighlightClass, optionsSections);
// Track sections
Array.from(document.querySelectorAll("section[id]")).map((section) => {
observer.observe(section);
});
};
checkForSections();
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
.navbar {
position: fixed;
width: 100%;
padding: 2rem;
background-color: cornflowerblue;
display: flex;
justify-content: center;
align-items: center;
}
.navbar__list {
list-style: none;
display: flex;
}
.navbar__item {
margin-left: 1rem;
}
.navbar__link,
.navbar__link:visited {
color: inherit;
text-decoration: none;
}
.navbar__link:hover,
.navbar__link:active,
.navbar__link:visited:hover,
.navbar__link:visited:active {
color: red;
}
section {
height: 100vh;
text-align: center;
padding: 5rem;
display: flex;
justify-content: center;
align-items: center;
}
section h2 {
color: #bada55;
font-size: 5rem;
}
.highlight {
color: red;
}
<nav class="navbar">
<ul class="navbar__list">
<li class="navbar__item"><a href="#home" class="navbar__link">Home</a></li>
<li class="navbar__item"><a href="#about" class="navbar__link">About</a></li>
<li class="navbar__item"><a href="#contact" class="navbar__link">Contacts</a></li>
</ul>
</nav>
<body>
<section id="home">
<h2>Home</h2>
</section>
<section id="about">
<h2>About</h2>
</section>
<section id="contact">
<h2>Contact</h2>
</section>
</body>
Upvotes: 2
Views: 57
Reputation: 12919
Instead of only checking the first entry
with const [entry] = entries;
you can iterate through all entries and update accordingly.
const addHighlightClass = (entries) => {
entries.forEach(entry => {
const id = entry.target.getAttribute("id");
if (entry.isIntersecting) {
document
.querySelector(`.navbar__link[href="#${id}"]`)
.parentElement.classList.add("highlight");
} else {
document
.querySelector(`.navbar__link[href="#${id}"]`)
.parentElement.classList.remove("highlight");
}
})
};
Edited snippet:
const checkForSections = () => {
const optionsSections = {
root: null,
rootMargin: "-350px -150px",
threshold: .9
};
const addHighlightClass = (entries) => {
entries.forEach(entry => {
const id = entry.target.getAttribute("id");
if (entry.isIntersecting) {
document
.querySelector(`.navbar__link[href="#${id}"]`)
.parentElement.classList.add("highlight");
} else {
document
.querySelector(`.navbar__link[href="#${id}"]`)
.parentElement.classList.remove("highlight");
}
})
};
const observer = new IntersectionObserver(addHighlightClass, optionsSections);
// Track sections
Array.from(document.querySelectorAll("section[id]")).map((section) => {
observer.observe(section);
});
};
checkForSections();
* { box-sizing: border-box; padding: 0; margin: 0;}.navbar { position: fixed; width: 100%; padding: 2rem; background-color: cornflowerblue; display: flex; justify-content: center; align-items: center;}.navbar__list { list-style: none; display: flex;}.navbar__item { margin-left: 1rem;}.navbar__link,.navbar__link:visited { color: inherit; text-decoration: none;}.navbar__link:hover,.navbar__link:active,.navbar__link:visited:hover,.navbar__link:visited:active { color: red;}section { height: 100vh; text-align: center; padding: 5rem; display: flex; justify-content: center; align-items: center;}section h2 { color: #bada55; font-size: 5rem;}.highlight { color: red;}
<nav class="navbar"> <ul class="navbar__list"> <li class="navbar__item"><a href="#home" class="navbar__link">Home</a></li> <li class="navbar__item"><a href="#about" class="navbar__link">About</a></li> <li class="navbar__item"><a href="#contact" class="navbar__link">Contacts</a></li> </ul></nav><body> <section id="home"> <h2>Home</h2> </section> <section id="about"> <h2>About</h2> </section> <section id="contact"> <h2>Contact</h2> </section></body>
Upvotes: 1