@@ -75,30 +75,22 @@ class TableOfContents extends HTMLElement {
7575 this.observer = new IntersectionObserver(
7676 this.markVisibleSection, { threshold: 0 }
7777 );
78- }
78+ };
7979
8080 markVisibleSection = (entries: IntersectionObserverEntry[]) => {
81- requestAnimationFrame(( ) => {
82- entries.forEach((entry) => {
83- const id = entry.target.children[0]?.getAttribute("id") ;
84-
85- const idx = id ? this.headingIdxMap.get(id) : undefined ;
81+ entries.forEach((entry ) => {
82+ const id = entry.target.children[0]?.getAttribute("id");
83+ const idx = id ? this.headingIdxMap.get(id) : undefined ;
84+ if (idx != undefined)
85+ this.active[ idx] = entry.isIntersecting ;
8686
87- if (entry.isIntersecting && this.anchorNavTarget == entry.target)
88- this.anchorNavTarget = null;
89-
90- if (idx != undefined)
91- this.active[idx] = entry.isIntersecting;
92- });
93-
94- requestAnimationFrame(() => {
95- if (!document.querySelector(`#toc .${this.visibleClass}`)) {
96- this.fallback();
97- }
98- this.toggleActiveHeading();
99- this.scrollToActiveHeading();
100- });
87+ if (entry.isIntersecting && this.anchorNavTarget == entry.target.firstChild)
88+ this.anchorNavTarget = null;
10189 });
90+
91+ if (!this.active.includes(true))
92+ this.fallback();
93+ this.update();
10294 };
10395
10496 toggleActiveHeading = () => {
@@ -132,7 +124,7 @@ class TableOfContents extends HTMLElement {
132124
133125 if (this.anchorNavTarget || !this.tocEl) return;
134126 const activeHeading =
135- document.querySelectorAll<HTMLDivElement>(" #toc .visible" );
127+ document.querySelectorAll<HTMLDivElement>(` #toc .${this.visibleClass}` );
136128 if (!activeHeading.length) return;
137129
138130 const topmost = activeHeading[0];
@@ -153,6 +145,15 @@ class TableOfContents extends HTMLElement {
153145 });
154146 };
155147
148+ update = () => {
149+ requestAnimationFrame(() => {
150+ this.toggleActiveHeading();
151+ // requestAnimationFrame(() => {
152+ this.scrollToActiveHeading();
153+ // });
154+ });
155+ };
156+
156157 fallback = () => {
157158 if (!this.sections.length) return;
158159
@@ -162,20 +163,16 @@ class TableOfContents extends HTMLElement {
162163
163164 if (this.isInRange(offsetTop, 0, window.innerHeight)
164165 || this.isInRange(offsetBottom, 0, window.innerHeight)
165- || (offsetTop < 0 && offsetBottom > window.innerHeight)) {
166+ || (offsetTop < 0 && offsetBottom > window.innerHeight)) {
166167 this.markActiveHeading(i);
167168 }
168- else break;
169+ else if (offsetTop > window.innerHeight) break;
169170 }
170-
171- requestAnimationFrame(() => {
172- this.toggleActiveHeading();
173- })
174171 };
175172
176173 markActiveHeading = (idx: number)=> {
177174 this.active[idx] = true;
178- }
175+ };
179176
180177 handleAnchorClick = (event: Event) => {
181178 const anchor = event
@@ -195,14 +192,19 @@ class TableOfContents extends HTMLElement {
195192
196193 isInRange(value: number, min: number, max: number) {
197194 return min < value && value < max;
198- }
195+ };
199196
200197 connectedCallback() {
201198 // wait for the onload animation to finish, which makes the `getBoundingClientRect` return correct values
202- setTimeout(() => {
203- this.init();
204- }, 250);
205- }
199+ const element = document.querySelector('.prose');
200+ if (element) {
201+ element.addEventListener('animationend', () => {
202+ this.init();
203+ }, { once: true });
204+ } else {
205+ console.warn('Animation element not found');
206+ }
207+ };
206208
207209 init() {
208210 this.tocEl = document.getElementById(
@@ -221,6 +223,8 @@ class TableOfContents extends HTMLElement {
221223 document.querySelectorAll<HTMLAnchorElement>("#toc a[href^='#']")
222224 );
223225
226+ if (this.tocEntries.length === 0) return;
227+
224228 this.sections = new Array(this.tocEntries.length);
225229 this.headings = new Array(this.tocEntries.length);
226230 for (let i = 0; i < this.tocEntries.length; i++) {
@@ -240,16 +244,16 @@ class TableOfContents extends HTMLElement {
240244 );
241245
242246 this.fallback();
243- this.scrollToActiveHeading ();
244- }
247+ this.update ();
248+ };
245249
246250 disconnectedCallback() {
247251 this.sections.forEach((section) =>
248252 this.observer.unobserve(section)
249253 );
250254 this.observer.disconnect();
251255 this.tocEl?.removeEventListener("click", this.handleAnchorClick);
252- }
256+ };
253257}
254258
255259customElements.define("table-of-contents", TableOfContents);
0 commit comments