diff --git a/src/components/ScrollToTop/ScrollToTop.tsx b/src/components/ScrollToTop/ScrollToTop.tsx index 8192001..7fd4b6f 100644 --- a/src/components/ScrollToTop/ScrollToTop.tsx +++ b/src/components/ScrollToTop/ScrollToTop.tsx @@ -5,15 +5,42 @@ export function ScrollToTop() { const { pathname, hash } = useLocation(); useEffect(() => { - const frame = window.requestAnimationFrame(() => { - if (hash) { - const target = document.getElementById(decodeURIComponent(hash.slice(1))); - if (target) { - target.scrollIntoView(); - return; - } + if (hash) { + let targetId: string; + + try { + targetId = decodeURIComponent(hash.slice(1)); + } catch { + targetId = hash.slice(1); } + const scrollToTarget = () => { + const target = document.getElementById(targetId); + + if (!target) { + return false; + } + + target.scrollIntoView({ block: 'start' }); + return true; + }; + + if (scrollToTarget()) { + return; + } + + const observer = new MutationObserver(() => { + if (scrollToTarget()) { + observer.disconnect(); + } + }); + + observer.observe(document.body, { childList: true, subtree: true }); + + return () => observer.disconnect(); + } + + const frame = window.requestAnimationFrame(() => { window.scrollTo({ top: 0, left: 0, behavior: 'instant' }); });