mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-11 07:23:32 -07:00
64 lines
1.5 KiB
JavaScript
64 lines
1.5 KiB
JavaScript
/** @param {HTMLElement} main */
|
|
export function initScrollSpy(main) {
|
|
const headings = [...main.querySelectorAll("article h1, article h2")];
|
|
const visibleHeadings = new Set();
|
|
const links = new Map(
|
|
[...main.querySelectorAll('nav a[href^="#"]')].map((link) => [
|
|
link.getAttribute("href"),
|
|
link,
|
|
]),
|
|
);
|
|
|
|
/** @type {string | null} */
|
|
let current = null;
|
|
|
|
/** @param {Element} heading */
|
|
function getHash(heading) {
|
|
const section = /** @type {HTMLElement} */ (
|
|
heading.closest("section[id]")
|
|
);
|
|
return `#${section.id}`;
|
|
}
|
|
|
|
/** @param {string} hash */
|
|
function getLink(hash) {
|
|
return /** @type {HTMLAnchorElement} */ (links.get(hash));
|
|
}
|
|
|
|
/** @param {string} hash */
|
|
function setCurrent(hash) {
|
|
if (hash === current) return;
|
|
|
|
if (current) getLink(current).removeAttribute("aria-current");
|
|
getLink(hash).setAttribute("aria-current", "location");
|
|
history.replaceState(null, "", hash);
|
|
current = hash;
|
|
}
|
|
|
|
function update() {
|
|
if (main.hidden) return;
|
|
|
|
const heading = headings.findLast((heading) =>
|
|
visibleHeadings.has(heading),
|
|
);
|
|
if (heading) setCurrent(getHash(heading));
|
|
}
|
|
|
|
const observer = new IntersectionObserver(
|
|
(entries) => {
|
|
for (const entry of entries) {
|
|
if (entry.isIntersecting) {
|
|
visibleHeadings.add(entry.target);
|
|
} else {
|
|
visibleHeadings.delete(entry.target);
|
|
}
|
|
}
|
|
|
|
update();
|
|
},
|
|
{ rootMargin: "0px 0px -80% 0px" },
|
|
);
|
|
|
|
for (const heading of headings) observer.observe(heading);
|
|
}
|