The Situation
I have a fixed nav bar at the top of the page. As you scroll down through different sections of the page the nav bar dynamically updates (underlines and highlights). You can also click a section on the nav bar and it will scroll down to that section.
This is done using the intersection observer API to detect which section it's on and scrollIntoView to scroll to each section.
The Problem
Lets say you are on section 1 and you click the last section, 5, and it scrolls the page down past all the other sections in-between. The scroll is fast and as it scrolls all the sections are detected by the intersection observer and therefore the nav is updated. You end up getting an effect of the nav quickly changing for each nav item as it goes past each corresponding section.
The Goal
How do you delay the intersection observer from triggering the menu change if the section is only in frame for a millisecond? When quickly scrolling the nav bar should only update once the scrolling has stopped on a section.
Code Setup
const sectionItemOptions = {
threshold: 0.7,
};
const sectionItemObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// select navigation link corresponding to section
} else {
// deselect navigation link corresponding to section
}
});
}, sectionItemOptions);
// start observing all sections on page
sections.forEach((section) => {
sectionItemObserver.observe(section);
});
Ideas
My first thought was to put a setTimeout so that the nav wouldn't change until the Timeout was finished, then cancel the Timeout if the section left the screen before the timeout finished. But as the timeout is in a forEach loop this didn't work.
const sectionItemObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
let selectNavTimeout
if (entry.isIntersecting) {
// Set timeout when section is scrolled past
selectNavTimeout = setTimeout(() => {
// select navigation link corresponding to section
}, 1000)
} else {
// deselect navigation link corresponding to section
// cancel timeout when section has left screen
clearTimeout(selectNavTimeout)
}
});
}, sectionItemOptions);
Any other ideas would be greatly appreciated! Thanks :)