diff --git a/src/app.css b/src/app.css index 2cbfd31..82dbfbf 100644 --- a/src/app.css +++ b/src/app.css @@ -1405,6 +1405,7 @@ footer section p:first-child { margin-left: -1rem; padding-left: 1rem; position: relative; + z-index: 1; /* 保证在指示器上方 */ color: #b0b0b0; /* VOID style dark text */ transition: color 0.2s, @@ -1421,16 +1422,27 @@ footer section p:first-child { .TOC li a.is-active-link { font-weight: 700; +} + +/* 动态滑动指示器 */ +.toc-active-indicator { + position: absolute; + left: 0; + width: 100%; background-color: rgba(0, 0, 0, 0.3); /* VOID style dark highlight */ border-left: 2px solid #419b38; - padding-left: calc(1rem - 2px); /* adjust padding for the border */ + pointer-events: none; + z-index: 0; + transition: + transform 0.24s cubic-bezier(0.16, 1, 0.3, 1), + height 0.24s cubic-bezier(0.16, 1, 0.3, 1), + opacity 0.2s; + opacity: 0; } @media screen and (min-width: 1199.5px) { .TOC li a:hover { - background-color: rgba(0, 0, 0, 0.3); - border-left: 2px solid #419b38; - padding-left: calc(1rem - 2px); + /* hover 时不修改背景和左边框了,保持透明给指示器让路 */ } } diff --git a/src/routes/posts/[slug]/+page.svelte b/src/routes/posts/[slug]/+page.svelte index 720b34e..7d4e0fd 100644 --- a/src/routes/posts/[slug]/+page.svelte +++ b/src/routes/posts/[slug]/+page.svelte @@ -8,6 +8,10 @@ let sidebarShow = $state(true); let hasToc = $state(false); + let indicatorTop = $state(0); + let indicatorHeight = $state(0); + let indicatorOpacity = $state(0); + let tocContainer = $state(); let { data }: { data: PageData } = $props(); @@ -84,6 +88,29 @@ }; }); + $effect(() => { + if (!hasToc || !tocContainer) return; + + const updateIndicator = () => { + const activeLink = tocContainer!.querySelector('a.is-active-link') as HTMLElement; + if (activeLink) { + indicatorTop = activeLink.offsetTop; + indicatorHeight = activeLink.offsetHeight; + indicatorOpacity = 1; + } else { + indicatorOpacity = 0; + } + }; + + const observer = new MutationObserver(updateIndicator); + observer.observe(tocContainer, { attributes: true, subtree: true, attributeFilter: ['class'] }); + + setTimeout(updateIndicator, 100); + + return () => { + observer.disconnect(); + }; + }); $effect(() => { if (hasToc && sidebarShow) { document.body.classList.add('sidebar-show'); @@ -176,7 +203,11 @@
(sidebarShow = false)}>
-
+
+