@@ -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",
- '<div class="sidetoc"><nav class="pagetoc"></nav></div>',
+ '<div class="toc-container"><nav class="pagetoc"></nav></div>',
);
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);
+ }
});