
Scrollspy for Bootstrap5.2 without the IntersectionObserver
Scrollspy
In bootstrap 5.2 the changed the scrollspy to using the intersection Observer. It doesn't always works as you want. Here is a code snippet
that works without the intersection observer.
Give your navbar an ID. In this example the navbar has an of Id="mainNav".
Each nav-link in the navbar should be linked to a section with an Id
Javascript
(function () {
'use strict';
// constants
const sections = [...document.querySelectorAll('section[id]')];
const menuLinks = document.querySelectorAll('.nav-item a');
const navoffset = document.getElementById('mainNav').clientHeight;
const navToggle = document.querySelector('.navbar-toggler');
// The scrollspy handler
const scrollHandle = () => {
const scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
sections.forEach((section) => {
const offset = section.offsetTop - navoffset;
if (offset <= scrollPosition) {
menuLinks.forEach((link) => link.classList.remove('active'));
const target = document.querySelector(`a[href="#${section.id}"]`);
if (!target.hash) return;
target.classList.add('active');
if (target.parentElement.classList.contains('dropdown-menu')) {
target.parentElement.parentElement.firstChild.classList.add('active');
}
if (document.querySelector('.navbar-collapse').classList.contains('show')) navToggle.click();
}
});
};
// event listeners
document.addEventListener('scroll', scrollHandle, false);
document.addEventListener('resize', scrollHandle, false);
document.addEventListener('readystatechange', scrollHandle, false);
})();