在早期版本的React Router中,我们为滚动恢复提供了开箱即用的支持,从那时起人们就一直在寻求它。希望本文档可以帮助您从滚动条和路由中获取所需内容!
浏览器开始使用history.pushState自己处理滚动恢复,就像它们使用普通浏览器导航一样处理它。它已经很好的在chrome中运行了。 这是文档。
因为浏览器开始处理“默认情况”并且应用程序具有不同的滚动需求(如此网站!),我们不提供默认滚动管理。但本指南应该可以帮助您实现任何滚动需求。
滚动到顶部
大多数情况下,您需要“滚动到顶部”,因为您有一个很长的内容页面组件,当导航时,会保持向下滚动了的状态。
使用<ScrollToTop>组件可以直接处理这个组件,该组件将在每个导航上滚动窗口。确保将其包装在withRouter中以使其能够访问路由器的props:
class ScrollToTop extends Component {
componentDidUpdate(prevProps) {
if (this.props.location.pathname !== prevProps.location.pathname) {
window.scrollTo(0, 0);
}
}
render() {
return this.props.children;
}
}
export default withRouter(ScrollToTop);
function App() {
return (
<Router>
<ScrollToTop>
<App />
</ScrollToTop>
</Router>
);
}
// or just render it bare anywhere you want, but just one :)
<ScrollToTop />;
该组件将会在你的应用的顶部渲染,但是渲染在Route之下。
如果您有一个连接到路由器的标签界面,那么您可能不希望在切换标签时滚动到顶部。那么你可以使用<ScrollToTopOnMount>组件
class ScrollToTopOnMount extends Component {
componentDidMount() {
window.scrollTo(0, 0);
}
render() {
return null;
}
}
class LongContent extends Component {
render() {
<div>
<ScrollToTopOnMount />
<h1>Here is my long content page</h1>
</div>;
}
}
// somewhere else
<Route path="/long-content" component={LongContent} />;
通用方法
对于通用解决方案(以及哪些浏览器开始本地实现),我们谈论两件事:
- 1、滚动导航,这样就不会启动滚动到底部的新屏幕
- 2、在点击“后退”和“前进”时恢复窗口和溢出元素的滚动位置(但不是链接点击!)
我们在某种程度上想要发布通用API。以下是我们的目标:
首先,ScrollRestoration会在导航的时候滚动窗口。
其次,它会使用位置信息。其关键点是保存窗口的滚动位置以及RestoredScroll 组件的滚动位置到sessionStorage。然后,当ScrollRestoration或者RestoredScroll组件挂载(mount)的时候,可以从sessionsStorage中查找到它们的位置。
<Router>
<ScrollRestoration>
<div>
<h1>App</h1>
<RestoredScroll id="bunny">
<div style={{ height: "200px", overflow: "auto" }}>I will overflow</div>
</RestoredScroll>
</div>
</ScrollRestoration>
</Router>
棘手的是,当我不希望管理窗口滚动时,如何定义一个“选择退出”按钮的API。
比如,当你的页面中包含浮动的tab导航,但你并不想滚动到顶部(这些tabs可能滚出了视图!)
当我了解到chrome现在为我们管理滚动位置,并意识到不同的应用程序将有不同的滚动需求,我有点失去了我们需要提供某些东西的信念 - 特别是当人们只想滚动到顶部时(你看到它是直接向你自己的应用添加)。基于此,对于这项工作我们不是很必要去完成(就像你我们有限的时间!)。但是,我们很乐意帮助任何愿意实施通用解决方案的人。一个可靠的解决方案甚至可以存在于项目中。如果你开始它就打我们了:)
网友评论