40 lines
1.2 KiB
JavaScript
40 lines
1.2 KiB
JavaScript
(() => {
|
|
const tocLinks = Array.from(document.querySelectorAll('.toc a'));
|
|
if (tocLinks.length === 0) return;
|
|
|
|
const idToLink = new Map();
|
|
tocLinks.forEach((link) => {
|
|
const id = link.getAttribute('href').slice(1);
|
|
idToLink.set(id, link);
|
|
});
|
|
|
|
const sections = Array.from(document.querySelectorAll('.doc-section'));
|
|
|
|
const setActive = (id) => {
|
|
tocLinks.forEach((l) => l.classList.remove('active'));
|
|
const link = idToLink.get(id);
|
|
if (link) link.classList.add('active');
|
|
};
|
|
|
|
const observer = new IntersectionObserver(
|
|
(entries) => {
|
|
const visible = entries
|
|
.filter((entry) => entry.isIntersecting)
|
|
.sort((a, b) => a.target.getBoundingClientRect().top - b.target.getBoundingClientRect().top);
|
|
if (visible[0]) setActive(visible[0].target.id);
|
|
},
|
|
{
|
|
rootMargin: '-30% 0px -60% 0px',
|
|
threshold: 0,
|
|
}
|
|
);
|
|
|
|
sections.forEach((section) => observer.observe(section));
|
|
|
|
tocLinks.forEach((link) => {
|
|
link.addEventListener('click', () => {
|
|
setActive(link.getAttribute('href').slice(1));
|
|
});
|
|
});
|
|
})();
|