在 React 中处理滚动动画

IT技术 javascript reactjs redux
2021-05-02 02:56:54

在 React 中处理滚动位置正确方法是什么?由于更好的用户体验,我真的很喜欢平滑滚动。由于在 React 中操作 DOM 是一种反模式,我遇到了一个问题:如何平滑滚动到某个位置/元素?我通常会更改元素的 scrollTop 值,但这是对 DOM 的操作,这是不允许的。

JSBIN

代码:

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 的方式实现这一点

4个回答

您可以只使用 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'})
  }
}

编辑:因为此方法尚未被所有浏览器支持浏览器支持概述),您可能需要使用polyfill

window.scroll({top: 0, left: 0, behavior: 'smooth' }) 为我工作。

您还需要检查浏览器的兼容性

或者使用polyfill


编辑:为了完整起见,这里是如何使用 webpack 动态填充。

if (!('scrollBehavior' in document.documentElement.style)) {
//safari does not support smooth scroll
  (async () => {
    const {default: smoothScroll} = await import(
      /* webpackChunkName: 'polyfill-modern' */
      'smoothscroll-polyfill'
      )
    smoothScroll.polyfill()
  })()
}

通过这个动态 polyfill,除非浏览器支持平滑滚动,否则包通过 ajax 加载。

polyfill-modern 是一个任意的块名称,它提示 webpack 编译器将包组合在一起,以减少对服务器的请求数量。

最简单的方法: -

window.scrollTo({top: 0, left: 0, behavior: 'smooth' });

这个简单的 JavaScript 代码适用于所有浏览器。

已经有几个很好的软件包可以为您处理这个问题:

https://github.com/fisshy/react-scroll -演示

https://www.npmjs.com/package/react-scroll-to-component 简单滚动到组件

希望这可以帮助!