Merge pull request #2202 from ZhenShuo2021/fix/toc-child

🐛 Fix: smartTOCHideUnfocusedChildren not collapsed
This commit is contained in:
Nuno Coração
2025-06-17 22:31:12 +01:00
committed by GitHub
+70 -36
View File
@@ -19,47 +19,81 @@
</div> </div>
</details> </details>
<script>
{{ if .Site.Params.smartTOC }} {{ if .Site.Params.smartTOC }}
<script>
(function () { (function () {
var $toc = $('#TableOfContents'); 'use strict'
if ($toc.length > 0) {
var $window = $(window);
function onScroll() { const SCROLL_OFFSET_RATIO = 0.33
var currentScroll = $window.scrollTop(); const TOC_SELECTOR = '#TableOfContents'
var h = $('.anchor'); const ANCHOR_SELECTOR = '.anchor'
var id = ""; const TOC_LINK_SELECTOR = 'a[href^="#"]'
h.each(function (i, e) { const NESTED_LIST_SELECTOR = 'li ul'
e = $(e); const ACTIVE_CLASS = 'active'
if (e.offset().top - $(window).height()/3 <= currentScroll) {
id = decodeURIComponent(e.attr('id'));
}
});
var active = $toc.find('a.active');
if (active.length == 1 && active.eq(0).attr('href') == '#' + id) return true;
active.each(function (i, e) { function getActiveAnchorId(anchors, offsetRatio) {
{{ if .Site.Params.smartTOCHideUnfocusedChildren }} const threshold = window.scrollY + window.innerHeight * offsetRatio
$(e).removeClass('active').siblings('ul').hide(); for (let i = anchors.length - 1; i >= 0; i--) {
{{ else }} const top = anchors[i].getBoundingClientRect().top + window.scrollY
$(e).removeClass('active'); if (top <= threshold) return anchors[i].id
{{ end }} }
}); return anchors[0]?.id || ''
$toc.find('a[href="#' + id + '"]').addClass('active'); }
$toc.find('a[href="#' + id + '"]').parentsUntil('#TableOfContents').each(function (i, e) {
$(e).children('a').parents('ul').show(); function updateTOC({ toc, anchors, links, scrollOffset, collapseInactive }) {
}); const activeId = getActiveAnchorId(anchors, scrollOffset)
if (!activeId) return
links.forEach(link => {
const isActive = link.getAttribute('href') === `#${activeId}`
link.classList.toggle(ACTIVE_CLASS, isActive)
if (collapseInactive) {
const ul = link.closest('li')?.querySelector('ul')
if (ul) ul.style.display = isActive ? '' : 'none'
}
})
if (collapseInactive) {
const activeLink = toc.querySelector(`a[href="#${CSS.escape(activeId)}"]`)
let el = activeLink
while (el && el !== toc) {
if (el.tagName === 'UL') el.style.display = ''
if (el.tagName === 'LI') el.querySelector('ul')?.style.setProperty('display', '')
el = el.parentElement
}
}
}
function initTOC() {
const toc = document.querySelector(TOC_SELECTOR)
if (!toc) return
const collapseInactive = {{ if site.Params.smartTOCHideUnfocusedChildren }}true{{ else }}false{{ end }}
const anchors = [...document.querySelectorAll(ANCHOR_SELECTOR)]
const links = [...toc.querySelectorAll(TOC_LINK_SELECTOR)]
if (collapseInactive) {
toc.querySelectorAll(NESTED_LIST_SELECTOR).forEach(ul => ul.style.display = 'none')
} }
$window.on('scroll', onScroll); const config = {
$(document).ready(function () { toc,
{{ if .Site.Params.smartTOCHideUnfocusedChildren }} anchors,
$toc.find('a').parent('li').find('ul').hide(); links,
{{ end }} scrollOffset: SCROLL_OFFSET_RATIO,
onScroll(); collapseInactive
}); }
window.addEventListener('scroll', () => updateTOC(config), { passive: true })
window.addEventListener('hashchange', () => updateTOC(config), { passive: true })
updateTOC(config)
} }
})();
{{ end }} document.readyState === 'loading'
? document.addEventListener('DOMContentLoaded', initTOC)
: initTOC()
})()
</script> </script>
{{ end }}