-
Notifications
You must be signed in to change notification settings - Fork 9
Persist sidebar scroll position across navigation #379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| (function () { | ||
| if (typeof window === "undefined") return; | ||
|
|
||
| var KEY = "kernel-docs-sidebar-scroll"; | ||
|
|
||
| function findSidebar() { | ||
| var candidates = document.querySelectorAll( | ||
| "aside, nav[aria-label='Sidebar'], aside[aria-label='Sidebar'], #sidebar" | ||
| ); | ||
| for (var i = 0; i < candidates.length; i++) { | ||
| var el = candidates[i]; | ||
| if (el.scrollHeight > el.clientHeight + 1) return el; | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| function save() { | ||
| var sb = findSidebar(); | ||
| if (sb) { | ||
| try { sessionStorage.setItem(KEY, String(sb.scrollTop)); } catch (e) {} | ||
| } | ||
| } | ||
|
|
||
| function restore() { | ||
| var sb = findSidebar(); | ||
| if (!sb) return false; | ||
| var raw; | ||
| try { raw = sessionStorage.getItem(KEY); } catch (e) { return false; } | ||
| if (raw === null) return false; | ||
| var top = parseInt(raw, 10); | ||
| if (isNaN(top)) return false; | ||
| if (Math.abs(sb.scrollTop - top) > 1) sb.scrollTop = top; | ||
| return true; | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Restore reports success prematurelyMedium Severity After navigation, Reviewed by Cursor Bugbot for commit 34326a0. Configure here. |
||
|
|
||
| var saveTimer; | ||
| document.addEventListener( | ||
| "scroll", | ||
| function (e) { | ||
| var sb = findSidebar(); | ||
| if (!sb) return; | ||
| var t = e.target; | ||
| if (t === sb || (t.contains && t.contains(sb)) || sb.contains(t)) { | ||
| clearTimeout(saveTimer); | ||
| saveTimer = setTimeout(save, 80); | ||
| } | ||
| }, | ||
| true | ||
| ); | ||
|
|
||
| document.addEventListener( | ||
| "click", | ||
| function (e) { | ||
| if (e.target && e.target.closest && e.target.closest("a")) save(); | ||
| }, | ||
| true | ||
| ); | ||
|
|
||
| function pollRestore() { | ||
| var attempts = 0; | ||
| var iv = setInterval(function () { | ||
| attempts++; | ||
| if (restore() || attempts > 30) clearInterval(iv); | ||
| }, 50); | ||
| } | ||
|
|
||
| var origPush = history.pushState; | ||
| history.pushState = function () { | ||
| var r = origPush.apply(this, arguments); | ||
| pollRestore(); | ||
| return r; | ||
| }; | ||
| var origReplace = history.replaceState; | ||
| history.replaceState = function () { | ||
| var r = origReplace.apply(this, arguments); | ||
| pollRestore(); | ||
| return r; | ||
| }; | ||
| window.addEventListener("popstate", pollRestore); | ||
|
|
||
| if (document.readyState === "complete") { | ||
| pollRestore(); | ||
| } else { | ||
| window.addEventListener("load", pollRestore); | ||
| } | ||
| })(); | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mintlify documents
#sidebar-contentas the scrollable content area inside the sidebar, but this selector only considers the outer containers. On pages where the user actually scrolls#sidebar-content,save()records the outer#sidebar/asidescrollTop(typically0) or finds nothing, so deep API/sidebar navigation still resets instead of restoring the position. Include and prefer#sidebar-contentbefore the container selectors so the saved value comes from the element that receives the scroll.Useful? React with 👍 / 👎.