@@ -95,13 +95,23 @@ const throttle = (func, delay) => {
9595 }
9696}
9797
98+ // Check if user has scrolled to the bottom of the page
99+ const isAtBottom = () => {
100+ const scrollHeight = document .documentElement .scrollHeight
101+ const scrollTop = document .documentElement .scrollTop || document .body .scrollTop
102+ const clientHeight = document .documentElement .clientHeight
103+ // Consider "at bottom" if within 100px of the bottom
104+ return scrollHeight - scrollTop - clientHeight < 100
105+ }
106+
98107// Update sidebar active state based on the topmost visible heading
99108const updateSidebarActiveState = () => {
100109 const sidebar = document .querySelector (' .sidebar' )
101110 if (! sidebar) return
102111
103112 const sidebarAnchors = sidebar .querySelectorAll (' a' )
104113 const sidebarAnchorsContainer = sidebar .querySelectorAll (' .collapsible.sidebar-sub-header' )
114+ const pageAnchors = document .querySelectorAll (' .header-anchor' )
105115
106116 // Get all visible headings sorted by their position (topmost first)
107117 const sortedVisibleHeadings = Array .from (visibleHeadings .value ).sort ((a , b ) => {
@@ -110,12 +120,33 @@ const updateSidebarActiveState = () => {
110120 return aRect .top - bRect .top
111121 })
112122
113- // Select the topmost visible heading
114- const topmostHeading = sortedVisibleHeadings[0 ]
123+ let targetHeading = null
124+
125+ // If at bottom of page, select the last heading that's above the viewport center
126+ if (isAtBottom () && pageAnchors .length > 0 ) {
127+ const viewportCenter = window .innerHeight / 2
128+ const allAnchorsArray = Array .from (pageAnchors)
129+
130+ // Find all headings that are above the viewport center
131+ const headingsAboveCenter = allAnchorsArray .filter (anchor => {
132+ const rect = anchor .getBoundingClientRect ()
133+ return rect .top < viewportCenter
134+ })
135+
136+ // Select the last one (closest to bottom)
137+ if (headingsAboveCenter .length > 0 ) {
138+ targetHeading = headingsAboveCenter[headingsAboveCenter .length - 1 ]
139+ }
140+ }
141+
142+ // If not at bottom or no heading found, use the topmost visible heading
143+ if (! targetHeading && sortedVisibleHeadings .length > 0 ) {
144+ targetHeading = sortedVisibleHeadings[0 ]
145+ }
115146
116- if (! topmostHeading ) return
147+ if (! targetHeading ) return
117148
118- const currentAnchor = topmostHeading .getAttribute (' data-anchor' )
149+ const currentAnchor = targetHeading .getAttribute (' data-anchor' )
119150
120151 // Update active class on sidebar links
121152 sidebarAnchors .forEach (a => a .classList .remove (' active' ))
0 commit comments