Next.js link 页面滚动到顶部时不呈现

Next.js link doesn't render with page scrolled at the top

我有这样一个组件:

const Milestone = props => {
  const { path, disabled, index, ...rest } = props;

  if (disabled) return <MilestoneCheck disabled />;

  return (
    <Link href={path} passHref>
      <a>
        <MilestoneCheck {...rest} />
      </a>
    </Link>
  );
};

当我单击 'Link' 转到下一页,然后单击后退按钮返回到我原来的位置时,页面不会在顶部加载,而是从上次滚动的页面加载位置。 加个'scrollTop' 路由变化的方法感觉效率不是很高,有没有更优雅的方案让页面始终在顶部加载?

使用以下内容包装您的 App 组件:

<ScrollToTop>
  ... all components there
</ScrollTop>

ScrollTop 组件:

import React, { useEffect } from 'react';
import { withRouter } from 'react-router-dom';

const ScrollToTop = ({ children, location: { pathname, search } }) => {
  useEffect(() => {
    try {
      window.scroll({
        top: 0,
        left: 0,
        behavior: 'smooth'
      });
    } catch (error) {
      // just a fallback for older browsers
      window.scrollTo(0, 0);
    }
  }, [pathname, search]);

  return children;
};

export default withRouter(ScrollToTop);

最终在 app.js 主文件中执行此操作:

  componentDidMount() {
    Router.events.on('routeChangeComplete', () => {
      window.scroll({
        top: 0,
        left: 0,
        behavior: 'smooth'
      });
    });
  }

我为这个问题苦恼了几天,找到了解决方案。

由于某些未知原因,问题是 NextJS 在导入全局 html 样式时存在一些错误。我的全局 styles.scss 导入中有 html class 已加载到我的主包装器中。一旦我从导入中删除 html ,滚动问题就会停止,页面加载就像在静态网站上一样。

在这里找到解决方案https://github.com/zeit/next.js/issues/7594

当我的页面无法在顶部呈现时,我遇到了同样的问题。就我而言,在我的 global.css 中,我有这个:

html {
  font-size: 62.5%;
  scroll-behavior: smooth;
}

删除 scroll-behavior: smooth; 后,一切开始按预期工作。

在您的 Page/Layout 组件中导入下一个路由器

import Router from 'next/router';

// you can then hook into there events

Router.onRouteChangeStart = () => {

};

Router.onRouteChangeComplete = () => {
  window.scroll({
    top: 0,
    left: 0,
  });
};

Router.onRouteChangeError = () => {

};

const Page = props => { 
  return <div>{props.children}</div>
}

在我的例子中,top: 0behavior: 'smooth 一起使用,但 不适用于 behavior: 'auto'。默认 behavior: 'auto'top: 0 工作,但任何其他值工作,例如:

window.scroll({
  top: 1,
});

我有过这种经历,我尝试了很多方法让它发挥作用,但没有成功。 这种路由更改行为应该默认发生,除非您正在做一些不同的事情。

我注意到从我的 html/body 标签中删除 overflow-x: hidden 后,一切都开始正常工作。

尽量不要在 html/body 元素中使用这种形式的样式:

html, body {
- overflow-x: hidden;
}

您可以将包装器元素(即 div)的最大宽度设置为 100vwoverflow-x:hidden 以归档相同的内容。

在我的例子中,我使用的是 Bootstrap,我不得不在 bootstrap.min.css 文件中删除:

:root {
 scroll-behavior: 'smooth'
}

这最终对我有用(更新到最新的 NextJS 路由配置)

Router.events.on('routeChangeComplete', (url) => {
      window.scroll({
        top: 0,
        left: 0,
      });
    });

一个可能的原因可能是根元素之一的 overflow-x: hidden;bodyhtml#__next

您可以尝试添加min-height: 100%或替换为overflow-x: clip;

导航时页面未滚动到顶部的另一个原因是存在以下样式规则时:

html { height: 100%; }

这个 here 有一个 Github 问题。