diff --git a/layouts/partials/toc.html b/layouts/partials/toc.html index a9859a7a..25e85d9f 100644 --- a/layouts/partials/toc.html +++ b/layouts/partials/toc.html @@ -36,6 +36,21 @@ let isJumpingToAnchor = false function getActiveAnchorId(anchors, offsetRatio) { + // On a page short enough that it never scrolls, scroll position can + // never change, so the loop below can never pick a different entry. + // Clicking a TOC entry still changes the hash, so fall back to that + // when scrolling can't answer the question at all - honoured only if + // it names an entry the TOC actually lists, so an unrelated hash + // doesn't fake a match. Pages that do scroll are unaffected. + const canScroll = + document.documentElement.scrollHeight > window.innerHeight + 1 + if (!canScroll) { + const fromHash = decodeURIComponent(window.location.hash.substring(1)) + const known = [...document.querySelectorAll('#TableOfContents a[href^="#"]')] + .map(link => decodeURIComponent(link.getAttribute('href').substring(1))) + if (fromHash && known.includes(fromHash)) return fromHash + } + const threshold = window.scrollY + window.innerHeight * offsetRatio const tocLinks = [...document.querySelectorAll('#TableOfContents a[href^="#"]')] const tocIds = new Set(tocLinks.map(link => link.getAttribute('href').substring(1)))