🐛 fix: toc child not collapsed

This commit is contained in:
ZhenShuo Leo
2025-06-04 12:18:33 +08:00
parent 850f987a68
commit 4ca31fadca

View File

@@ -19,47 +19,81 @@
</div>
</details>
<script>
{{ if .Site.Params.smartTOC }}
<script>
(function () {
var $toc = $('#TableOfContents');
if ($toc.length > 0) {
var $window = $(window);
'use strict'
function onScroll() {
var currentScroll = $window.scrollTop();
var h = $('.anchor');
var id = "";
h.each(function (i, e) {
e = $(e);
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;
const SCROLL_OFFSET_RATIO = 0.33
const TOC_SELECTOR = '#TableOfContents'
const ANCHOR_SELECTOR = '.anchor'
const TOC_LINK_SELECTOR = 'a[href^="#"]'
const NESTED_LIST_SELECTOR = 'li ul'
const ACTIVE_CLASS = 'active'
active.each(function (i, e) {
{{ if .Site.Params.smartTOCHideUnfocusedChildren }}
$(e).removeClass('active').siblings('ul').hide();
{{ else }}
$(e).removeClass('active');
{{ end }}
});
$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 getActiveAnchorId(anchors, offsetRatio) {
const threshold = window.scrollY + window.innerHeight * offsetRatio
for (let i = anchors.length - 1; i >= 0; i--) {
const top = anchors[i].getBoundingClientRect().top + window.scrollY
if (top <= threshold) return anchors[i].id
}
return anchors[0]?.id || ''
}
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);
$(document).ready(function () {
{{ if .Site.Params.smartTOCHideUnfocusedChildren }}
$toc.find('a').parent('li').find('ul').hide();
{{ end }}
onScroll();
});
const config = {
toc,
anchors,
links,
scrollOffset: SCROLL_OFFSET_RATIO,
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>
{{ end }}