Merge pull request #18649 from dvdksn/heading-ids

feat: improve heading markup and scroll behavior
This commit is contained in:
David Karlsson 2023-11-13 07:33:56 +01:00 committed by GitHub
commit d2dffd4e28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 42 deletions

View File

@ -1,43 +1,29 @@
const toc = document.querySelector("#TableOfContents") const toc = document.querySelector("#TableOfContents");
const headings = document.querySelectorAll("main article h2, main article h3");
if (toc) { if (toc) {
const prose = document.querySelector("article.prose") window.addEventListener("scroll", updateToc);
const headings = prose.querySelectorAll("h2, h3") updateToc();
// grab the yposition and targets for all anchor links }
const anchorLinks = Array.from(headings)
.map((h) => h.previousElementSibling)
.map((a) => [a.offsetTop - 64, `#${a.name}`])
.sort((a, b) => (a[0] > b[0] ? 1 : 0))
let closestHeading function updateToc() {
// find the heading currently in view
// find the closest anchor link based on window scrollpos const currentSection = Array.from(headings).reduce((previous, current) => {
function findClosestHeading() { const { top } = current.getBoundingClientRect();
yPos = window.scrollY // if current is in the top 100px of the viewport
closest = anchorLinks.reduce((prev, curr) => { // 100px is an arbitrary value
return Math.abs(curr[0] - yPos) < Math.abs(prev[0] - yPos) && // Should be header height + margin
curr[0] <= yPos if (top < 100) {
? curr return current;
: prev
})
return closest
} }
return previous
function updateToc() { });
const prev = toc.querySelector('a[aria-current="true"]') const prev = toc.querySelector('a[aria-current="true"]');
const next = toc.querySelector(`a[href="${closestHeading[1]}"]`) const next = toc.querySelector(`a[href="#${currentSection.id}"]`);
if (prev) { if (prev) {
prev.removeAttribute("aria-current") prev.removeAttribute("aria-current");
} }
if (next) { if (next) {
next.setAttribute("aria-current", "true") next.setAttribute("aria-current", "true");
} }
}
function handleScroll() {
closestHeading = findClosestHeading()
updateToc()
}
window.addEventListener("scroll", handleScroll)
} }

View File

@ -1,6 +1,5 @@
{{ $id := .id | default (anchorize (plainify .text)) }} {{ $id := .id | default (anchorize (plainify .text)) }}
<a class="relative -top-16" name="{{ $id }}"></a> <h{{ .level }} class="{{ .class }} scroll-mt-20" id="{{ $id }}">
<h{{ .level }} {{ with .class }} class="{{ . }}" {{ end }}>
<a class="text-black dark:text-white no-underline hover:underline" href="#{{ $id }}"> <a class="text-black dark:text-white no-underline hover:underline" href="#{{ $id }}">
{{ .text }} {{ .text }}
</a> </a>