More actions
No edit summary |
No edit summary |
||
Line 45: | Line 45: | ||
} | } | ||
// Helper: | // Helper: expand parent, wait two frames, scroll manually | ||
function smoothScrollToHeading(heading) { | function smoothScrollToHeading(heading) { | ||
if (!heading) return; | if (!heading) return; | ||
// If | // If heading has 0px height (ghost anchor), find next real heading | ||
if (heading.offsetHeight === 0) { | if (heading.offsetHeight === 0) { | ||
const nextHeading = heading.parentElement.querySelector('h1, h2, h3, h4, h5, h6'); | const nextHeading = heading.parentElement.querySelector('h1, h2, h3, h4, h5, h6'); | ||
Line 57: | Line 57: | ||
} | } | ||
// Wait two animation frames for DOM to reflow fully | |||
heading. | requestAnimationFrame(() => { | ||
requestAnimationFrame(() => { | |||
const rect = heading.getBoundingClientRect(); | |||
const scrollTop = window.scrollY + rect.top - 60; // 60px offset for sticky header | |||
window.scrollTo({ top: scrollTop, behavior: 'smooth' }); | |||
}); | |||
}); | |||
} | |||
} | |||
} | } | ||