diff --git a/docs/theme/page-toc.js b/docs/theme/page-toc.js index 1ca6f621de9c34723e8ccd3be3d293a57f802d08..627416fddf06ae1330e53d88da7ae950b2bd46ca 100644 --- a/docs/theme/page-toc.js +++ b/docs/theme/page-toc.js @@ -3,21 +3,18 @@ let scrollTimeout; const listenActive = () => { const elems = document.querySelector(".pagetoc").children; [...elems].forEach((el) => { - el.addEventListener("click", (event) => { + el.addEventListener("click", (_) => { clearTimeout(scrollTimeout); [...elems].forEach((el) => el.classList.remove("active")); el.classList.add("active"); - // Prevent scroll updates for a short period + scrollTimeout = setTimeout(() => { scrollTimeout = null; - }, 100); // Adjust timing as needed + }, 100); }); }); }; -const getPagetoc = () => - document.querySelector(".pagetoc") || autoCreatePagetoc(); - const autoCreatePagetoc = () => { const main = document.querySelector("#content > main"); const content = Object.assign(document.createElement("div"), { @@ -27,30 +24,41 @@ const autoCreatePagetoc = () => { main.prepend(content); main.insertAdjacentHTML( "afterbegin", - '
', + '
', ); return document.querySelector(".pagetoc"); }; + +const getPagetoc = () => + document.querySelector(".pagetoc") || autoCreatePagetoc(); + const updateFunction = () => { - if (scrollTimeout) return; // Skip updates if within the cooldown period from a click + if (scrollTimeout) return; + const headers = [...document.getElementsByClassName("header")]; - const scrolledY = window.scrollY; - let lastHeader = null; - - // Find the last header that is above the current scroll position - for (let i = headers.length - 1; i >= 0; i--) { - if (scrolledY >= headers[i].offsetTop) { - lastHeader = headers[i]; - break; + if (headers.length === 0) return; + + const threshold = 100; + let activeHeader = null; + + for (const header of headers) { + const rect = header.getBoundingClientRect(); + + if (rect.top <= threshold) { + activeHeader = header; } } + if (!activeHeader && headers.length > 0) { + activeHeader = headers[0]; + } + const pagetocLinks = [...document.querySelector(".pagetoc").children]; pagetocLinks.forEach((link) => link.classList.remove("active")); - if (lastHeader) { + if (activeHeader) { const activeLink = pagetocLinks.find( - (link) => lastHeader.href === link.href, + (link) => activeHeader.href === link.href, ); if (activeLink) activeLink.classList.add("active"); } @@ -63,13 +71,9 @@ document.addEventListener("DOMContentLoaded", () => { const nonH1Headers = headers.filter( (header) => !header.parentElement.tagName.toLowerCase().startsWith("h1"), ); - const sidetoc = document.querySelector(".sidetoc"); const tocContainer = document.querySelector(".toc-container"); if (nonH1Headers.length === 0) { - if (sidetoc) { - sidetoc.style.display = "none"; - } if (tocContainer) { tocContainer.classList.add("no-toc"); } @@ -84,6 +88,7 @@ document.addEventListener("DOMContentLoaded", () => { className: "toc-title", textContent: "On This Page", }); + pagetoc.appendChild(tocTitle); headers.forEach((header) => { @@ -94,7 +99,14 @@ document.addEventListener("DOMContentLoaded", () => { }); pagetoc.appendChild(link); }); + updateFunction(); listenActive(); - window.addEventListener("scroll", updateFunction); + + const pageElement = document.querySelector(".page"); + if (pageElement) { + pageElement.addEventListener("scroll", updateFunction); + } else { + window.addEventListener("scroll", updateFunction); + } });