Fix docs sidebar navigation scroll targeting with lazy-loaded images
This commit is contained in:
parent
c3eecc88ad
commit
fead6db379
2 changed files with 45 additions and 16 deletions
|
|
@ -2247,15 +2247,31 @@ function initializeDocsPage() {
|
|||
suppressScrollSpy._timer = setTimeout(() => { _scrollSpySuppressed = false; }, 800);
|
||||
}
|
||||
|
||||
// Helper: get element offset relative to a scrollable ancestor
|
||||
function getOffsetRelativeTo(el, ancestor) {
|
||||
let offset = 0;
|
||||
let current = el;
|
||||
while (current && current !== ancestor) {
|
||||
offset += current.offsetTop;
|
||||
current = current.offsetParent;
|
||||
// Scroll a target element into view within the docs-content container.
|
||||
// Uses manual offsetTop calculation instead of scrollIntoView to avoid
|
||||
// misalignment caused by lazy-loaded images that haven't reserved height yet.
|
||||
// Does an initial scroll, then a correction after images near the target load.
|
||||
function scrollDocTarget(target) {
|
||||
if (!target || !docsContent) return;
|
||||
suppressScrollSpy();
|
||||
|
||||
function calcOffset(el) {
|
||||
let offset = 0;
|
||||
let current = el;
|
||||
while (current && current !== docsContent) {
|
||||
offset += current.offsetTop;
|
||||
current = current.offsetParent;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
return offset;
|
||||
|
||||
// Initial scroll
|
||||
docsContent.scrollTop = calcOffset(target);
|
||||
|
||||
// Correction pass after lazy images near the target have had time to load
|
||||
// and shift layout. Two passes cover most reflow scenarios.
|
||||
setTimeout(() => { docsContent.scrollTop = calcOffset(target); }, 150);
|
||||
setTimeout(() => { docsContent.scrollTop = calcOffset(target); }, 500);
|
||||
}
|
||||
|
||||
// Section title click → expand/collapse children + scroll
|
||||
|
|
@ -2275,10 +2291,9 @@ function initializeDocsPage() {
|
|||
if (children) children.classList.add('expanded');
|
||||
}
|
||||
|
||||
// Scroll to section (suppress scroll spy so it doesn't fight)
|
||||
suppressScrollSpy();
|
||||
// Scroll to section
|
||||
const target = document.getElementById('docs-' + sectionId);
|
||||
if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
scrollDocTarget(target);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -2290,9 +2305,8 @@ function initializeDocsPage() {
|
|||
child.classList.add('active');
|
||||
|
||||
// Keep parent section expanded
|
||||
suppressScrollSpy();
|
||||
const target = document.getElementById(child.dataset.target);
|
||||
if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
scrollDocTarget(target);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -2386,11 +2400,23 @@ function initializeDocsPage() {
|
|||
function navigateToDocsSection(sectionId) {
|
||||
// Switch to help page
|
||||
if (typeof navigateToPage === 'function') navigateToPage('help');
|
||||
// Wait for docs to initialize
|
||||
// Wait for docs to initialize, then use manual scroll with correction passes
|
||||
setTimeout(() => {
|
||||
const target = document.getElementById(sectionId);
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
const docsContent = document.getElementById('docs-content');
|
||||
if (target && docsContent) {
|
||||
function calcOffset(el) {
|
||||
let offset = 0;
|
||||
let current = el;
|
||||
while (current && current !== docsContent) {
|
||||
offset += current.offsetTop;
|
||||
current = current.offsetParent;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
docsContent.scrollTop = calcOffset(target);
|
||||
setTimeout(() => { docsContent.scrollTop = calcOffset(target); }, 150);
|
||||
setTimeout(() => { docsContent.scrollTop = calcOffset(target); }, 500);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35863,6 +35863,7 @@ tr.tag-diff-same {
|
|||
/* Main content */
|
||||
.docs-content {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
padding: 40px 48px;
|
||||
scroll-behavior: smooth;
|
||||
|
|
@ -36108,6 +36109,8 @@ tr.tag-diff-same {
|
|||
.docs-screenshot {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
aspect-ratio: 16 / 9;
|
||||
object-fit: contain;
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
|
|
|
|||
Loading…
Reference in a new issue