zenno: make article toc only render upon first view
This commit is contained in:
@@ -10,6 +10,26 @@
|
|||||||
|
|
||||||
let { head, children }: Props = $props();
|
let { head, children }: Props = $props();
|
||||||
|
|
||||||
|
let tocViewed = $state(false);
|
||||||
|
let tocElem: HTMLElement | undefined = $state();
|
||||||
|
const observeTOC: IntersectionObserverCallback = (entries, obs) => {
|
||||||
|
for (const e of entries) {
|
||||||
|
if (!e.isIntersecting) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tocViewed = true;
|
||||||
|
obs.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (tocElem == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const obs = new IntersectionObserver(observeTOC, {rootMargin: "20% 0px"});
|
||||||
|
obs.observe(tocElem);
|
||||||
|
});
|
||||||
|
|
||||||
function tocClass(s: Section) {
|
function tocClass(s: Section) {
|
||||||
switch (s.h) {
|
switch (s.h) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -32,10 +52,12 @@
|
|||||||
{@render head()}
|
{@render head()}
|
||||||
{#if sections.length > 0}
|
{#if sections.length > 0}
|
||||||
<Sec h={2} id="toc" toc={false}>Table of Contents</Sec>
|
<Sec h={2} id="toc" toc={false}>Table of Contents</Sec>
|
||||||
<ul class="mb-4 list-disc pl-4">
|
<ul class="mb-4 list-disc pl-4" bind:this={tocElem}>
|
||||||
{#each sections as s (s.id)}
|
{#if tocViewed}
|
||||||
<li class={tocClass(s)}><a href={`#${s.id}`}>{@render s.children()}</a></li>
|
{#each sections as s (s.id)}
|
||||||
{/each}
|
<li class={tocClass(s)}><a href={`#${s.id}`}>{@render s.children()}</a></li>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
{/if}
|
{/if}
|
||||||
{@render children()}
|
{@render children()}
|
||||||
|
|||||||
Reference in New Issue
Block a user