在React中处理滚动位置的正确方法是什么?因为更好的用户体验,我真的很喜欢平滑滚动。因为在React中操作DOM是一种反模式我遇到了问题:如何平滑地滚动到某个位置/元素?我通常会更改元素的scrollTop值,但这是对DOM的操作,这是不允许的。
代码:
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
handleClick = e => {
for (let i = 1; i <= 100; i++) {
setTimeout(() => (this.node.scrollTop = i), i * 2);
}
};
render() {
const someArrayToMap = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
return (
<div ref={node => this.node = node} style={{overflow: 'auto', height: '100vh'}}>
<button onClick={this.handleClick}>CLICK TO SCROLL</button>
{
[...someArrayToMap,
...someArrayToMap,
...someArrayToMap,
...someArrayToMap,
...someArrayToMap,
...someArrayToMap,
...someArrayToMap].map((e, i) => <div key={i}>some text here</div>)
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
如何以 React 的方式实现这一目标?
答案 0 :(得分:13)
您可以只使用refs和scrollIntoView
方法(使用behavior: 'smooth'
进行平滑滚动)。只需几行代码,不需要打包。
说这就是您要滚动到的内容
<p ref={this.myRef} className="scrollToHere">[1] ...</p>
还有某种按钮
<button onClick={() => {this.scroll(this.myRef)}} className="footnote">[1]</button>
调用滚动方法
class App extends Component {
constructor() {
super()
this.myRef = React.createRef();
scroll(ref) {
ref.current.scrollIntoView({behavior: 'smooth'})
}
}
编辑:由于并非所有浏览器(overview of browser support)都支持此方法,因此您可能要使用polyfill。
答案 1 :(得分:7)
答案 2 :(得分:2)
已经有一些好的套装可以帮你处理:
https://github.com/fisshy/react-scroll - Demo
https://www.npmjs.com/package/react-scroll-to-component 简单滚动到组件
希望这有帮助!
答案 3 :(得分:2)
在React中有几个用于滚动到锚点的库。选择的选项取决于您正在寻找的功能以及您网页的现有设置。
React Scrollable Anchor是一个轻量级库,专门用于滚动到映射到URL哈希的锚点。它还会根据当前关注的部分更新URL哈希。 [完全披露:我是这个图书馆的作者]
React Scroll,在另一个答案中提到,是一个功能更全面的库,用于滚动到锚点,而不会在URL中反映任何位置。
如果你已经使用了React Router,你也可以连接React Router Hash Link Scroll这样的东西,然后它也会绑定到你的URL哈希。
答案 4 :(得分:1)
我非常喜欢API部分中的react-router website,他们似乎使用这个scrollToDoc component,这是一个非常甜蜜的典型VanillaJS平滑滚动函数转换为React,它取决于{{3} }!
答案 5 :(得分:1)
最简单的方法:-
window.scrollTo({top: 0, left: 0, behavior: 'smooth' });
此简单的JavaScript代码适用于所有浏览器。
答案 6 :(得分:1)
这是一个使用钩子的小型无依赖解决方案
const useSmoothScrollTo = id => {
const ref = useRef(null)
useEffect(() => {
const listener = e => {
if (ref.current && location.hash === id) {
ref.current.scrollIntoView({behavior: 'smooth'})
}
}
window.addEventListener('hashchange', listener, true)
return () => {
window.removeEventListener('hashchange', listener)
}
}, [])
return {
'data-anchor-id': id,
ref
}
}
你像这样使用它:
export const FeaturesSection = () => {
const bind = useSmoothScrollTo('#features')
return (
<section {...bind} className={classes.features}>
...
</section>
)
}
然后你只需要在你的应用程序中的任何其他地方做
<a href="#features">Go to Features</a>
显然,与上述相同的警告适用于 .scrollIntoView({behavior: 'smooth'})