zenno: make article toc only render upon first view
This commit is contained in:
@@ -10,6 +10,26 @@
|
||||
|
||||
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) {
|
||||
switch (s.h) {
|
||||
case 1:
|
||||
@@ -32,10 +52,12 @@
|
||||
{@render head()}
|
||||
{#if sections.length > 0}
|
||||
<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}>
|
||||
{#if tocViewed}
|
||||
{#each sections as s (s.id)}
|
||||
<li class={tocClass(s)}><a href={`#${s.id}`}>{@render s.children()}</a></li>
|
||||
{/each}
|
||||
{/if}
|
||||
</ul>
|
||||
{/if}
|
||||
{@render children()}
|
||||
|
||||
Reference in New Issue
Block a user