09 前端畫面與架構
09 重新整理後停留在舊 scroll 位置
Reload 後頁面自動停在上次的 scroll 位置,而不是從這次初始化流程的起點開始。
30 秒摘要
- 現象:reload 後頁面自動停在上次的 scroll 位置,而不是從這次初始化流程的起點開始。 developer.mozilla
- 影響:首屏動畫、ScrollTrigger、pin、鎖滾動流程可能從錯誤起點初始化。
- 優先方向:先檢查是否在 hydration 前設定、是否為 Pages Router、是否放在
pages/_document。 nextjs
先做這三步
- 手動捲到中後段後重新整理,確認能否穩定重現。
- 檢查專案是否有
pages/_document.tsx/pages/_document.jsx;Next.js 規定 custom Document 需包含<Html>、<Main />、<NextScript />等必要結構。 nextjs - 確認
history.scrollRestoration = "manual"是否早於 React hydration 執行;beforeInteractive類型的腳本時機屬於 hydration 前。 nextjs
標準解法
在 pages/_document 的 <body> 最前面加入最小 inline script,將 history.scrollRestoration 設為 manual。MDN 說明 manual 代表頁面位置不會被自動恢復。 developer.mozilla
範例:
import { Html, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html data-font-smoothing="figma">
<body className="relative">
{/* Prevent browser scroll restoration before React hydration */}
<script
dangerouslySetInnerHTML={{
__html: `
if ("scrollRestoration" in history) {
history.scrollRestoration = "manual";
}
`,
}}
/>
<Main />
<NextScript />
</body>
</Html>
);
}預期結果:reload 後不再沿用舊 scroll 位置,首屏動畫與 ScrollTrigger 從一致起點初始化。 developer.mozilla
驗證方式
- 捲到中後段後重新整理,確認頁面不會停在舊位置。 developer.mozilla
- 確認首屏動畫、解鎖流程與 ScrollTrigger 狀態正常。
升級條件
- 已設定
manual仍無效。 - 問題其實來自自訂滾動容器、第三方 smooth scroll、或 GSAP 初始化順序。
備註
這類問題通常是瀏覽器自動恢復舊 scroll 位置,導致動畫頁初始化起點不一致;MDN 對
scrollRestoration的定義可作為判斷基礎。建議先檢查pages/_document與 hydration 前時機,再套用上面的做法。 nextjs