feat: 仅在文章页面启用目录功能并修复 TOC 初始化逻辑

This commit is contained in:
seahi committed 2026-07-29 18:18:25 +08:00
1 parent 922811afd8
commit f6da0fcd53
2 files changed
+12 -58

No files matched your search

-55
View File
@@ -1,52 +1,9 @@
<script lang="ts">
import { page } from '$app/stores';
import type { PageData } from './$types';
import { onMount } from 'svelte';
import tocbot from 'tocbot';
import MarkdownRenderer from '$lib/components/MarkdownRenderer.svelte';
let sidebarShow = $state(true);
let { data }: { data: PageData } = $props();
onMount(() => {
tocbot.init({
tocSelector: '.js-toc',
contentSelector: '.js-toc-content',
headingSelector: 'h1, h2, h3, h4, h5',
hasInnerContainers: false,
linkClass: 'toc-link',
activeLinkClass: 'is-active-link',
listClass: 'toc-list',
isCollapsedClass: 'is-collapsed',
collapsibleClass: 'is-collapsible',
listItemClass: 'toc-list-item',
collapseDepth: 0,
scrollSmooth: true,
headingsOffset: 20
});
if (window.innerWidth < 1200) {
sidebarShow = false;
}
$effect(() => {
if (sidebarShow) {
document.body.classList.add('sidebar-show');
} else {
document.body.classList.remove('sidebar-show');
}
return () => {
document.body.classList.remove('sidebar-show');
};
});
return () => {
tocbot.destroy();
};
});
</script>
<svelte:head>
@@ -64,17 +21,5 @@
</article>
</div>
<!-- TOC Overlay and Sidebar -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="toc-mask" onclick={() => sidebarShow = false}></div>
<div class="TOC" aria-label="{$page.data.aliases?.page || '页面'}目录">
<div class="js-toc"></div>
</div>
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div id="toggle-toc" class="ctrler-item" onclick={() => sidebarShow = !sidebarShow}>
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16"><path fill="currentColor" d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L27 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 120.8c9.8 9.3 10 24.8.4 34.3z"></path></svg>
</div>
</main>
+12 -3
View File
@@ -1,15 +1,20 @@
<script lang="ts">
import { page } from '$app/stores';
import type { PageData } from './$types';
import { onMount } from 'svelte';
import { onMount, tick } from 'svelte';
import tocbot from 'tocbot';
import MarkdownRenderer from '$lib/components/MarkdownRenderer.svelte';
let sidebarShow = $state(true);
let hasToc = $state(false);
let { data }: { data: PageData } = $props();
onMount(() => {
const headers = document.querySelectorAll('.js-toc-content h1, .js-toc-content h2, .js-toc-content h3, .js-toc-content h4, .js-toc-content h5, .js-toc-content h6');
if (headers.length > 0) {
hasToc = true;
tick().then(() => {
tocbot.init({
tocSelector: '.js-toc',
contentSelector: '.js-toc-content',
@@ -29,9 +34,11 @@
if (window.innerWidth < 1200) {
sidebarShow = false;
}
});
}
$effect(() => {
if (sidebarShow) {
if (hasToc && sidebarShow) {
document.body.classList.add('sidebar-show');
} else {
document.body.classList.remove('sidebar-show');
@@ -43,7 +50,7 @@
});
return () => {
tocbot.destroy();
if (hasToc) tocbot.destroy();
};
});
@@ -76,6 +83,7 @@
</article>
</div>
{#if hasToc}
<!-- TOC Overlay and Sidebar -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
@@ -89,4 +97,5 @@
<div id="toggle-toc" class="ctrler-item" onclick={() => sidebarShow = !sidebarShow}>
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16"><path fill="currentColor" d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L27 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 120.8c9.8 9.3 10 24.8.4 34.3z"></path></svg>
</div>
{/if}
</main>