1- import gsap from "https://cdn.skypack.dev/gsap" ;
2- import { ScrollTrigger } from "https://cdn.skypack.dev/gsap/ScrollTrigger" ;
3-
41document . addEventListener ( "DOMContentLoaded" , function ( ) {
52 // Handle window resize event
63 window . addEventListener ( "resize" , function ( ) {
7- // Check if the viewport width is greater than 991px (desktop breakpoint)
84 initializeTableOfContents ( ) ;
95 } ) ;
106
@@ -16,7 +12,6 @@ function initializeTableOfContents() {
1612 return ;
1713 }
1814
19- gsap . registerPlugin ( ScrollTrigger ) ;
2015 const headers = document . querySelectorAll ( ".text-rich-text h2" ) ;
2116 const tocContainer = document . querySelector ( ".dynamic-page-toc-container" ) ;
2217 const tocComponent = document . querySelector ( ".sidebar_toc_component" ) ;
@@ -45,7 +40,7 @@ function initializeTableOfContents() {
4540 . replace ( / ^ - | - $ / g, "" ) ;
4641
4742 // Ensure the ID starts with a letter or underscore
48- let id = `section-${ baseId } ` ; // Example prefix to ensure valid ID
43+ let id = `section-${ baseId } ` ;
4944 let count = 1 ;
5045
5146 // Ensure the ID is unique
@@ -68,49 +63,56 @@ function initializeTableOfContents() {
6863
6964 // Handle click event on TOC link
7065 link . addEventListener ( "click" , function ( event ) {
71- event . preventDefault ( ) ; // Prevent default anchor behavior
72- scrollToHeader ( id ) ; // Scroll to the corresponding header
66+ event . preventDefault ( ) ;
67+ scrollToHeader ( id ) ;
7368 } ) ;
7469 } ) ;
7570
7671 // Set initial active link based on current scroll position
7772 updateActiveHeader ( ) ;
7873
74+ // Add scroll listener to update active header
75+ let scrollTimeout ;
76+ window . addEventListener ( "scroll" , function ( ) {
77+ // Throttle scroll events for performance
78+ if ( scrollTimeout ) {
79+ window . cancelAnimationFrame ( scrollTimeout ) ;
80+ }
81+ scrollTimeout = window . requestAnimationFrame ( function ( ) {
82+ updateActiveHeader ( ) ;
83+ } ) ;
84+ } , { passive : true } ) ;
85+
7986 // Function to scroll to a specific header by ID
8087 function scrollToHeader ( id ) {
8188 const header = document . getElementById ( id ) ;
8289 if ( header ) {
8390 header . scrollIntoView ( { behavior : "smooth" , block : "start" } ) ;
84-
85- // Update active link in TOC
8691 updateActiveLink ( id ) ;
8792 }
8893 }
8994
90- // Function to update active link in TOC based on current scroll position
95+ // Function to update active link based on current scroll position
9196 function updateActiveHeader ( ) {
9297 let currentActiveHeader = null ;
98+ let closestDistance = Infinity ;
99+
93100 headers . forEach ( function ( header ) {
94101 const bounding = header . getBoundingClientRect ( ) ;
95- if (
96- bounding . top <= 100 && // Adjust this value as needed
97- bounding . bottom >= 100 && // Adjust this value as needed
98- ( currentActiveHeader === null ||
99- bounding . top < currentActiveHeader . getBoundingClientRect ( ) . top )
100- ) {
102+ const distance = Math . abs ( bounding . top - 100 ) ;
103+
104+ // Find the header closest to our target position (100px from top)
105+ if ( bounding . top <= 150 && distance < closestDistance ) {
106+ closestDistance = distance ;
101107 currentActiveHeader = header ;
102108 }
103109 } ) ;
104110
105111 if ( currentActiveHeader ) {
106- const id = currentActiveHeader . id ;
107- updateActiveLink ( id ) ;
108- } else {
109- // If no headers are active, set the first link as active
110- if ( headers . length > 0 && window . scrollY < 100 ) {
111- const firstHeaderId = headers [ 0 ] . id ;
112- updateActiveLink ( firstHeaderId ) ;
113- }
112+ updateActiveLink ( currentActiveHeader . id ) ;
113+ } else if ( headers . length > 0 && window . scrollY < 100 ) {
114+ // If near top of page, activate first header
115+ updateActiveLink ( headers [ 0 ] . id ) ;
114116 }
115117 }
116118
@@ -126,20 +128,6 @@ function initializeTableOfContents() {
126128 }
127129 }
128130
129- // Add ScrollTrigger to monitor visibility and update active link
130- headers . forEach ( function ( header ) {
131- ScrollTrigger . create ( {
132- trigger : header ,
133- start : "top 20%" , // Adjust start position as needed
134- end : "bottom top" , // Adjust end position as needed
135- onToggle : ( self ) => {
136- if ( self . isActive ) {
137- updateActiveLink ( header . id ) ;
138- }
139- } ,
140- } ) ;
141- } ) ;
142-
143131 if ( headers . length > 0 ) {
144132 tocComponent . style . display = "block" ;
145133 }
0 commit comments