I'm working on a react project and I want to highlight the sidebar nav list when the corresponding section is visible while scrolling, and I used useEffect and IntersectionObserver for that and add an active class to the sidebar nav item with the code below.
The problem is that some of the sections are not 100% height of the viewport, causing multiple sidebar nav list items to highlight simultaneously and I do not want that. I want only a single nav item to have the active class.
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
const id = entry.target.getAttribute('id');
if (entry.isIntersecting) {
document
.querySelector(`.sidebarList li a[href="#${id}"]`)
.classList.add('active');
} else {
document
.querySelector(`.sidebarList li a[href="#${id}"]`)
.classList.remove('active');
}
});
});
document.querySelectorAll('section[id]').forEach((section) => {
observer.observe(section);
});
return () => observer.disconnect();
});