如何为React Router SPA实施滚动还原

时间:2019-11-08 19:49:08

标签: javascript reactjs google-chrome react-router

我正在构建一个React单页应用程序,并且我注意到滚动恢复似乎无法在Chrome(可能还有其他浏览器)中按预期工作。

在react-router-dom github存储库上,他们有一个页面说浏览器是starting to natively handle scrolling的单页面应用程序,并且其行为类似于传统的非SPA网页,如果history.scrollRestoration设置为auto

该页面上显示了我需要的行为:

  
      
  1. 向上滚动导航,这样就不会启动滚动到的新屏幕   底部。
  2.   
  3. 还原窗口的滚动位置和溢出   “后退”和“前进”点击上的元素(而不是“链接”点击!)
  4.   

但是我还需要禁用包含制表符或轮播的路由的行为。

这里是Chrome's spec on the issue的链接。

我在适用于OS X的Chrome版本78.0.3904.97(官方内部版本)(64位)中观察到的是我对history.scrollRestoration manual设置的期望。也就是说,当我向下滚动到页面的一半并单击链接时,下一个页面将在页面的中间滚动,直到与上一页相同的位置。

我已经在各个地方检查了history.scrollRestoration,发现它开始并保持auto(默认值)

@TrevorRobinson的回答是“这里的一个重要意义”是“浏览器自动尝试滚动还原... ...大多数情况下不适用于单页面应用程序...”好吧...我发现了一致的支持history.scrollRestoration,但显然浏览器在实际进行滚动还原方面表现得很差劲。然后应该注意here,今天可以节省我的时间。

然后,我寻找手动执行此操作的方法,但我不清楚前进的方向。 react-router-scroll说它与React Router v4不兼容,但是没有提到v5,这是该问题的最新版本。那么我应该假设v5也不兼容吗?

因此,我进一步寻找前进的方向,并找到了关于how to handle scroll restoration with React Router v4的SO答案...我是否应该假设与React Router v5一起使用? 更新:在v5中似乎不适用于我。我尝试了几种配置。我也无法使其完全与React Router v4一起使用。我知道它至少还活着,因为它可以滚动到新页面的顶部,但是历史记录不会恢复。

我也确实可以使用react-router-scroll-memory,但是它没有禁用在指定路线上滚动的选项,例如制表符或轮播所需的选项……我可能会对其进行破解。

我考虑过使用oaf-react-router,但是在文档中没有对禁用某些路线的滚动恢复或从上到下滚动进行任何说明。 编辑:如我的回答所述,它确实可以处理此问题。

有什么我忽略的东西吗?处理此问题的标准是什么,因为我不能是唯一需要此功能的人。似乎我在做一些前卫和实验性的工作,但我只需要让自己的网站像普通网站一样滚动即可。

1 个答案:

答案 0 :(得分:4)

执行此操作的一种方法是使用oaf-react-router。使用设置中的shouldHandleAction选项。该函数将通过previousLocationnextLocation传递,您可以使用它们来确定是否应重置/还原滚动,并返回false

const history = createBrowserHistory();

const settings = {
   shouldHandleAction: (previousLocation, nextLocation) => {
       // Inspect/compare nextLocation and/or previousLocation.
       return false // false if you don't want scroll restoration.
   }
};

wrapHistory(history, settings);

oaf-react-router可与React Router v4和v5一起使用,并且可处理可访问性,而许多SPA路由器则不能,因此这可能是目前最完整的解决方案。

奇怪的是,文档中没有详细介绍此功能。

如果其他人有可行的解决方案,并且将其视为更标准的解决方案,请在此处提供答案,我将考虑更改所选答案。