The Scrollspy is used to automatically update links in a navigation list based on scroll position.
Examples
<div class="scrollspy flex flex-wrap">
<div class="flex justify-between items-center px-3 py-2 w-full navbar bg-gray-400 text-white">
<a class="navbar-brand p-2 text-xl text-gray-900" href="#">Navbar</a>
<ul class="flex flex-wrap mb-0 text-center bg-white rounded-full">
<li class="nav-item rounded-full text-blue-500">
<a class="block px-4 py-2 rounded-full" href="#scrollspyHeading1">First</a>
</li>
<li class="nav-item rounded-full text-blue-500">
<a class="block px-4 py-2 rounded-full" href="#scrollspyHeading2" onclick="">Second</a>
</li>
<li class="nav-item relative rounded-full text-blue-500" x-data="{ open: false }">
<a class="dropdown-toggle mr-4 cursor-pointer flex items-center justify-center w-full pl-4 py-2"@click="open = ! open" href="#dropdown">
Dropdown
<svg xmlns="http://www.w3.org/2000/svg" class="inline-block w-5 h-5"
x-bind:style="open ? 'transform: rotate(180deg);transition-duration: 500ms' : 'transform: -rotate(180deg);transition-duration: 500ms'"
viewBox="0 0 512 512" fill="currentColor"
style="transform: -rotate(180deg);transition-duration: 500ms">
<path d="M128 192l128 128 128-128z"></path>
</svg>
</a>
<ul class="absolute z-50 py-2 text-left text-gray-600 bg-white border rounded shadow-md "
@click.outside="open = false" x-show="open" x-transition.duration.500>
<li class="text-blue-500">
<a class="block w-full px-4 py-1 hover:text-blue-500 whitespace-nowrap " href="#scrollspyHeading3">Third</a>
</li>
<li class="text-blue-500">
<a class="block w-full px-4 py-1 hover:text-blue-500 whitespace-nowrap " href="#scrollspyHeading4">Fourth</a>
</li>
<hr class="mx-2 overflow-hidden border-gray-400">
<li class="text-blue-500">
<a class="block w-full px-4 pr-20 hover:text-blue-500 py-1 whitespace-nowrap " href="#scrollspyHeading5">Fifth</a>
</li>
</ul>
</li>
</ul>
</div>
<div class="anyipsum-output slides overflow-y-auto mt-2 h-48">
<section id="scrollspyHeading1">
<p class="font-semibold text-xl text-gray-900">First heading</hp>
<p class="text-gray-500 mb-4">This is some placeholder content for the
scrollspy page. Note that as you scroll down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.This is some placeholder content for
the
scrollspy page. Note that as you scroll down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.</p>
</section><br>
<section id="scrollspyHeading2">
<h5 class="font-semibold text-xl text-gray-900"> Second heading</h5>
<p class="text-gray-500 mb-4">This is some placeholder content for the
scrollspy page. Note that as you scroll down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.This is some placeholder content for
the
scrollspy page. Note that as you scroll down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.</p>
</section><br>
<section id="dropdown">
<section id="scrollspyHeading3">
<h5 class="font-semibold text-xl text-gray-900">Third heading</h5>
<p class="text-gray-500 mb-4">This is some placeholder content for the
scrollspy page. Note that as you scroll down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.scrollspy page. Note that as you
scroll
down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.</p>
</section><br>
<section id="scrollspyHeading4">
<h5 class="font-semibold text-xl text-gray-900"> Fourth heading</h5>
<p class="text-gray-500 mb-4">This is some placeholder content for the
scrollspy page. Note that as you scroll down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.scrollspy page. Note that as you
scroll
down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.</p>
</section><br>
<section id="scrollspyHeading5">
<h5 class="font-semibold text-xl text-gray-900"> Fifth heading</h5>
<p class="text-gray-500 mb-4">This is some placeholder content for the
scrollspy page. Note that as you scroll down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.scrollspy page. Note that as you
scroll
down the page, the appropriate navigation link is
highlighted. It's repeated throughout the component example. We keep adding some more
example
copy here to emphasize the scrolling and highlighting.</p>
</section>
</section>
</div>
</div>
Script
window.addEventListener('DOMContentLoaded', () => {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const id = entry.target.getAttribute('id');
if (entry.intersectionRatio > 0) {
if (id == 'scrollspyHeading1' || id == 'scrollspyHeading2' || id == 'scrollspyHeading3' || id == 'scrollspyHeading4' || id == 'scrollspyHeading5' || id == 'dropdown') {
document.querySelector(`div li a[href="#${id}"]`).parentElement.classList.add('active');
}
} else {
if (id == 'scrollspyHeading1' || id == 'scrollspyHeading2' || id == 'scrollspyHeading3' || id == 'scrollspyHeading4' || id == 'scrollspyHeading5' || id == 'dropdown') {
document.querySelector(`div li a[href="#${id}"]`).parentElement.classList.remove('active');
}
}
});
});
// Track all sections that have an `id` applied
document.querySelectorAll('section[id]').forEach((section) => {
observer.observe(section);
});
});