This commit is contained in:
1 parent
8dfe2624ab
commit
3fe68cd57e
2 files changed
+48
-5
No files matched your search
+16
-4
@@ -1405,6 +1405,7 @@ footer section p:first-child {
|
|||||||
margin-left: -1rem;
|
margin-left: -1rem;
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
z-index: 1; /* 保证在指示器上方 */
|
||||||
color: #b0b0b0; /* VOID style dark text */
|
color: #b0b0b0; /* VOID style dark text */
|
||||||
transition:
|
transition:
|
||||||
color 0.2s,
|
color 0.2s,
|
||||||
@@ -1421,16 +1422,27 @@ footer section p:first-child {
|
|||||||
|
|
||||||
.TOC li a.is-active-link {
|
.TOC li a.is-active-link {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 动态滑动指示器 */
|
||||||
|
.toc-active-indicator {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
background-color: rgba(0, 0, 0, 0.3); /* VOID style dark highlight */
|
background-color: rgba(0, 0, 0, 0.3); /* VOID style dark highlight */
|
||||||
border-left: 2px solid #419b38;
|
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) {
|
@media screen and (min-width: 1199.5px) {
|
||||||
.TOC li a:hover {
|
.TOC li a:hover {
|
||||||
background-color: rgba(0, 0, 0, 0.3);
|
/* hover 时不修改背景和左边框了,保持透明给指示器让路 */
|
||||||
border-left: 2px solid #419b38;
|
|
||||||
padding-left: calc(1rem - 2px);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
|
|
||||||
let sidebarShow = $state(true);
|
let sidebarShow = $state(true);
|
||||||
let hasToc = $state(false);
|
let hasToc = $state(false);
|
||||||
|
let indicatorTop = $state(0);
|
||||||
|
let indicatorHeight = $state(0);
|
||||||
|
let indicatorOpacity = $state(0);
|
||||||
|
let tocContainer = $state<HTMLElement>();
|
||||||
|
|
||||||
let { data }: { data: PageData } = $props();
|
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(() => {
|
$effect(() => {
|
||||||
if (hasToc && sidebarShow) {
|
if (hasToc && sidebarShow) {
|
||||||
document.body.classList.add('sidebar-show');
|
document.body.classList.add('sidebar-show');
|
||||||
@@ -176,7 +203,11 @@
|
|||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div class="toc-mask" onclick={() => (sidebarShow = false)}></div>
|
<div class="toc-mask" onclick={() => (sidebarShow = false)}></div>
|
||||||
<div class="TOC" aria-label="{$page.data.aliases?.post || '文章'}目录">
|
<div class="TOC" bind:this={tocContainer} aria-label="{$page.data.aliases?.post || '文章'}目录">
|
||||||
|
<div
|
||||||
|
class="toc-active-indicator"
|
||||||
|
style="transform: translateY({indicatorTop}px); height: {indicatorHeight}px; opacity: {indicatorOpacity}"
|
||||||
|
></div>
|
||||||
<div class="js-toc"></div>
|
<div class="js-toc"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user