File size: 2,603 Bytes
96dd062 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | ---
import type { MarkdownHeading } from "astro";
import "@/styles/toc.css";
import WidgetLayout from "@/components/common/WidgetLayout.astro";
import I18nKey from "@/i18n/i18nKey";
import { i18n } from "@/i18n/translation";
interface Props {
headings: MarkdownHeading[];
class?: string;
style?: string;
}
const { headings: _headings = [], class: className, style } = Astro.props;
---
<WidgetLayout
name={i18n(I18nKey.tableOfContents)}
id="sidebar-toc"
class={className}
style={style}
>
<div class="toc-scroll-container custom-scrollbar">
<div
class="toc-content"
id="sidebar-toc-content"
>
<!-- TOC内容将由JavaScript动态生成 -->
</div>
</div>
</WidgetLayout>
<style lang="stylus">
/* SidebarTOC 特定样式 */
.toc-scroll-container
max-height: calc(100vh - 20rem)
</style>
<script>
import { TOCManager } from "@/utils/tocUtils";
if (typeof window.SidebarTOC === "undefined") {
window.SidebarTOC = {
manager: null
};
}
async function initSidebarTOC() {
const tocContent = document.getElementById("sidebar-toc-content");
if (!tocContent) return;
try {
// 清理旧实例
if (window.SidebarTOC.manager) {
window.SidebarTOC.manager.cleanup();
}
// 创建新实例
window.SidebarTOC.manager = new TOCManager({
contentId: "sidebar-toc-content",
indicatorId: "sidebar-active-indicator",
maxLevel: 3,
scrollOffset: 80,
});
// 初始化
window.SidebarTOC.manager.init();
} catch (error) {
console.error("Failed to load TOCManager for SidebarTOC:", error);
}
}
// 初始化
// 确保 DOM 准备好后再执行
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initSidebarTOC);
} else {
initSidebarTOC();
}
// 页面切换时重新初始化
document.addEventListener("swup:contentReplaced", () => {
setTimeout(initSidebarTOC, 100);
});
// Astro 页面切换事件
document.addEventListener("astro:page-load", () => {
setTimeout(initSidebarTOC, 100);
});
// 浏览器导航事件
window.addEventListener("popstate", () => {
setTimeout(initSidebarTOC, 200);
});
// 监听 hashchange(但排除 TOC 内部导航)
window.addEventListener("hashchange", () => {
if (!window.tocInternalNavigation) {
setTimeout(initSidebarTOC, 100);
}
window.tocInternalNavigation = false;
});
</script>
|