|
| 1 | +let scrollTimeout; |
| 2 | + |
| 3 | +const listenActive = () => { |
| 4 | + const elems = document.querySelector(".pagetoc").children; |
| 5 | + [...elems].forEach(el => { |
| 6 | + el.addEventListener("click", (event) => { |
| 7 | + clearTimeout(scrollTimeout); |
| 8 | + [...elems].forEach(el => el.classList.remove("active")); |
| 9 | + el.classList.add("active"); |
| 10 | + // Prevent scroll updates for a short period |
| 11 | + scrollTimeout = setTimeout(() => { |
| 12 | + scrollTimeout = null; |
| 13 | + }, 100); // Adjust timing as needed |
| 14 | + }); |
| 15 | + }); |
| 16 | +}; |
| 17 | + |
| 18 | +const getPagetoc = () => document.querySelector(".pagetoc") || autoCreatePagetoc(); |
| 19 | + |
| 20 | +const autoCreatePagetoc = () => { |
| 21 | + const main = document.querySelector("#content > main"); |
| 22 | + const content = Object.assign(document.createElement("div"), { |
| 23 | + className: "content-wrap" |
| 24 | + }); |
| 25 | + content.append(...main.childNodes); |
| 26 | + main.prepend(content); |
| 27 | + main.insertAdjacentHTML("afterbegin", '<div class="sidetoc"><nav class="pagetoc"></nav></div>'); |
| 28 | + return document.querySelector(".pagetoc"); |
| 29 | +}; |
| 30 | +const updateFunction = () => { |
| 31 | + if (scrollTimeout) return; // Skip updates if within the cooldown period from a click |
| 32 | + const headers = [...document.getElementsByClassName("header")]; |
| 33 | + const scrolledY = window.scrollY; |
| 34 | + let lastHeader = null; |
| 35 | + |
| 36 | + // Find the last header that is above the current scroll position |
| 37 | + for (let i = headers.length - 1; i >= 0; i--) { |
| 38 | + if (scrolledY >= headers[i].offsetTop) { |
| 39 | + lastHeader = headers[i]; |
| 40 | + break; |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + const pagetocLinks = [...document.querySelector(".pagetoc").children]; |
| 45 | + pagetocLinks.forEach(link => link.classList.remove("active")); |
| 46 | + |
| 47 | + if (lastHeader) { |
| 48 | + const activeLink = pagetocLinks.find(link => lastHeader.href === link.href); |
| 49 | + if (activeLink) activeLink.classList.add("active"); |
| 50 | + } |
| 51 | +}; |
| 52 | + |
| 53 | +window.addEventListener('load', () => { |
| 54 | + const pagetoc = getPagetoc(); |
| 55 | + const headers = [...document.getElementsByClassName("header")]; |
| 56 | + headers.forEach(header => { |
| 57 | + const link = Object.assign(document.createElement("a"), { |
| 58 | + textContent: header.text, |
| 59 | + href: header.href, |
| 60 | + className: `pagetoc-${header.parentElement.tagName}` |
| 61 | + }); |
| 62 | + pagetoc.appendChild(link); |
| 63 | + }); |
| 64 | + updateFunction(); |
| 65 | + listenActive(); |
| 66 | + window.addEventListener("scroll", updateFunction); |
| 67 | +}); |
| 68 | + |
0 commit comments