React怎么绑定scroll事件?

Undefined
  • 7

我需要在页面组件渲染完成之后监听滚屏事件,但是试了几种写法,只有下面第一种会触发,其余的都不会触发,求解。

 componentDidMount() {
    // 触发
    window.addEventListener('scroll', this.orderScroll.bind(this));
    // document.body.addEventListener('scroll', this.orderScroll.bind(this)); 不触发
    // document.getElementById('userOrder').addEventListener('scroll', this.orderScroll.bind(this)); 不触发
    // this.refs.userOrder.addEventListener('scroll', this.orderScroll.bind(this)); 不触发
 }
 
 orderScroll() {
     console.log('scroll');
 }
 
 render() {
     return(
         <div id="userOrder" ref="userOrder">
             <div></div>
         </div>
     )
 }
 
 // 这样写同样不会触发
 // render() {
 //     return(
 //         <div onScroll={this.orderScroll.bind(this)}>
 //             <div></div>
 //         </div>
 //     )
 // }
 

问题2,照着 window.addEventListener('scroll', this.orderScroll.bind(this));这样绑事件绑定成功之后,在componentWillUnMount() 函数里却清除不掉

componentWillUnMount() {
    window.removeEventListener('scroll', this.orderScroll.bind(this));
}
回复
阅读 20.3k
5 个回答

只有有滚动条的元素才能触发scroll事件。所以你这里面除了window之外当然都不触发。

清除的话,你的componentWillUnMount写错了,是componentWillUnmount。

this.orderScroll.bind(this),bind(this) 这样会产生一个新的函数 和之前绑定的函数不是同一个,所以当然移除不掉了

遇到同样问题,确实是bind引起的,因为bind是产生新函数,所以清除不掉。因为在滚动函数中需要setState,确实需要bind(this),正确的写法是在构造函数中绑定,写法如下

constructor(props) {
    super(props);
    this.state = {};
    this.scrollTop = 0;
    this.handleScroll = this.handleScroll.bind(this)
  }
  componentWillMount() {
    window.addEventListener('scroll', this.handleScroll);
  }
  componentWillUnmount() {
    window.removeEventListener('scroll', this.handleScroll);
  }

题主你好,我用你的第一种方法都没有触发哎,求指教

文档地址:https://zh-hans.reactjs.org/d...

constructor(props) {
    super(props);
    this.scroll = React.createRef();     // 创建一个 ref 来存储 scroll 的 DOM 元素

}
componentDidMount() {
    // 通过 "current" 来访问 DOM 节点
    this.scroll.current.addEventListener('scroll',() => {
      console.log('scroll')
    })
 }
 
 render() {
     return(
         <div ref={this.scroll}>
             <div></div>
         </div>
     )
 }
宣传栏