[英]Server side rendered element should be scrolled to bottom on initial render
我正在構建一個 React 服務器端呈現的應用程序 (Next.js) 並有一個可滾動的<div>
,我希望在 React 為組件補充水分之前在頁面初始加載時將其滾動到底部。
這意味着像下面這樣的useLayoutEffect()
鈎子是不夠的,因為在 React 安裝和運行這個鈎子之前,會有一個簡短的 flash 元素滾動到頂部。
useLayoutEffect(() => {
const element = ref.current;
element.scrollTop = element.scrollHeight - element.clientHeight;
});
我認為可以防止這種情況發生的方法是在服務器端呈現的頁面中添加一個<script>
標記。 例如:
function MyComponent() {
return (
<>
<div style={{overflowY: "scroll"}}>
...
</div>
<script>
var element = document.currentScript.previousElementSibling;
element.scrollTop = element.scrollHeight - element.clientHeight;
</script>
</>
);
}
但是,我發現當<script>
執行時<div>
元素的clientHeight
為 0。
據推測,我需要等待瀏覽器完成加載 DOM,所以我添加了一個DOMContentLoaded
偵聽器:
function MyComponent() {
return (
<>
<div style={{overflowY: "scroll"}}>
...
</div>
<script>
var element = document.currentScript.previousElementSibling;
document.addEventListener("DOMContentLoaded", function() {
element.scrollTop = element.scrollHeight - element.clientHeight;
});
</script>
</>
);
}
但是,使用這種方法,瀏覽器似乎仍然在scrollTop
設置為 0 的情況下進行繪制,然后處理DOMContentLoaded
事件處理程序。
如何在此處編寫<script>
以在element.clientHeight
等 DOM 屬性加載后但在第一次瀏覽器繪制之前執行“滾動到底部”行為,以便用戶看不到錯誤滾動 position 的 flash。
還有比這更好的方法嗎?
這個版本實際上在生產中工作。 It doesn't work in development because Next.js use's Webpack's style-loader
in development which means styles don't load until the JavaScript code has loaded and the JavaScript code is loaded at the end of the document <body>
.
所以在生產中element.clientHeight
將是正確的(因為 CSS 已加載到<head>
中)但在開發中element.clientHeight
將為0(因為 CSS 將在<body>
的末尾加載)。
function MyComponent() {
return (
<>
<div style={{overflowY: "scroll"}}>
...
</div>
<script>
var element = document.currentScript.previousElementSibling;
element.scrollTop = element.scrollHeight - element.clientHeight;
</script>
</>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.