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

BBa*_*ger 9 javascript google-chrome reactjs react-router

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

在react-router-dom github repo上,他们有一个页面说浏览器开始本地处理单页面应用程序的滚动,并且如果history.scrollRestoration设置为,则行为将类似于传统的非SPA网页。auto

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

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

但是我还需要禁用包含标签或轮播的路由的行为。

这是Chrome关于此问题的规范的链接。

我在OS X的Chrome版本78.0.3904.97(正式版本)(64位)中观察到的内容似乎是我期望的history.scrollRestoration manual设置。也就是说,当我向下滚动页面一半并单击链接时,下一页向下滚动到页面中间,与上一页相同。

history.scrollRestoration在各个地方检查了,发现它开始并保持auto为默认状态,

在此意义的一个问题是这样的,从@ TrevorRobinson的答案“浏览器的滚动时自动恢复尝试......主要是做不适合单页的应用程序的工作......”好吧......我找到了一致的支持history.scrollRestoration,但显然,浏览器在实际进行滚动还原时很cr脚。那应该在这里指出,这今天可以节省我的时间。

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

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

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

我考虑过使用oaf-react-router,但是在文档中对于禁用某些路由的滚动还原或滚动到顶部没有任何说明。编辑:它确实处理了此问题,如我的回答所述。

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

BBa*_*ger 5

一种方法是使用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);
Run Code Online (Sandbox Code Playgroud)

oaf-react-router 与 React Router v4 和 v5 一起工作,并处理可访问性,许多 SPA 路由器没有,所以它可能是目前最完整的解决方案。

奇怪的是,文档没有详细说明此功能。

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