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


11

我正在构建一个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,但是在文档中没有对禁用某些路由的滚动恢复或从上到下滚动进行任何说明。编辑:它确实处理了此问题,如我的回答所述。

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


2
您应该看一下Nextjs,他们通过缓存历史记录实现了这一点。
朱里安

凉!当我可以从这个项目中下来时,我将仔细研究。
BBaysinger

Answers:


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路由器则无法访问,因此这可能是目前最完整的解决方案。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.