iter: d08 演示页侧边目录 + 滚动高亮
This commit is contained in:
+26
-1
@@ -27,6 +27,27 @@ import {
|
||||
tooltip,
|
||||
} from '@ui-arch/ui';
|
||||
|
||||
/*** 侧边目录:挂载后从 .sec 反推锚点,IntersectionObserver 高亮视口内区块(清单改动自动跟随) ***/
|
||||
function buildToc(toc: HTMLElement, content: HTMLElement): void {
|
||||
const secs = Array.from(content.querySelectorAll<HTMLElement>('section.sec'));
|
||||
if (!secs.length) return; // 卫语句:无区块不建目录
|
||||
const links = secs.map((sec) =>
|
||||
h('a', { class: 'toc-link', href: `#${sec.id}`, 'data-for': sec.id }, sec.querySelector('h2')?.textContent ?? sec.id),
|
||||
);
|
||||
toc.append(...links);
|
||||
const io = new IntersectionObserver(
|
||||
(entries) => {
|
||||
for (const en of entries) {
|
||||
if (!en.isIntersecting) continue; // 只处理刚进入视口的区块
|
||||
const id = (en.target as HTMLElement).id;
|
||||
for (const link of links) link.classList.toggle('is-active', link.getAttribute('data-for') === id);
|
||||
}
|
||||
},
|
||||
{ rootMargin: '-10% 0px -80% 0px' }, // 顶部窄条判定,滚动时高亮更跟手
|
||||
);
|
||||
for (const sec of secs) io.observe(sec);
|
||||
}
|
||||
|
||||
/*** 生成演示区块;id 供文档站 iframe 锚点定位 ***/
|
||||
function section(id: string, title: string, desc: string, ...body: unknown[]): HTMLElement {
|
||||
return h(
|
||||
@@ -84,7 +105,7 @@ const menuPick = signal('');
|
||||
// —— 禁用态演示:开关信号同时绑定 switch 的 checked 与 checkbox 的 disabled ——
|
||||
const locked = signal(true);
|
||||
|
||||
const app = h(
|
||||
const content = h(
|
||||
'div',
|
||||
{ class: 'page' },
|
||||
h(
|
||||
@@ -322,4 +343,8 @@ const app = h(
|
||||
),
|
||||
);
|
||||
|
||||
const toc = h('aside', { class: 'toc' }, h('div', { class: 'toc-title' }, '目录')); // 目录项由 buildToc 填充
|
||||
const app = h('div', { class: 'shell' }, toc, content);
|
||||
|
||||
mount('#app', () => app);
|
||||
buildToc(toc, content);
|
||||
|
||||
Reference in New Issue
Block a user