繁体   English   中英

服务器端渲染元素应在初始渲染时滚动到底部

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM