2016-07-06 193 views
4

我正在使用React,下面是我用来实现无限滚动功能的代码。带命名函数的window.removeEventListener不起作用

componentDidMount() { 
    // Flag to check if the content has loaded. 
    let flag = true; 

    function infiniteScroll() { 
     let enterpriseWrap = $('.enterprise-blocks'); 
     let contentHeight = enterpriseWrap.offsetHeight; 
     let yOffset = window.pageYOffset; 
     let y = yOffset + window.innerHeight; 

     console.log('hey'); 

     if(this.props.hasMore) { 

     if(y >= contentHeight && flag) { 
      flag = false; 

      this.props.loadMoreVendors(function() { 
      flag = true; 
      }); 

     } 

     } else { 
     window.removeEventListener('scroll', infiniteScroll.bind(this)); 
     } 
    } 

    window.addEventListener('scroll', infiniteScroll.bind(this)); 
    } 

我实际上想要解除滚动事件一旦所有的项目都加载,但removeEventListener不工作。难道我做错了什么?

回答

8

每次绑定一个函数时,都会返回一个新函数。您正在从最初添加的监听器中删除不同的监听器。存储function.bind结果和使用,在这两个地方

this.boundInfiniteScroll = this.infiniteScroll.bind(this); 
... 

    } else { 
    window.removeEventListener('scroll', this.boundInfiniteScroll); 
    } 
} 

window.addEventListener('scroll', this.boundInfiniteScroll); 
+0

真棒。非常感谢。 –

2

removeEventListener你必须通过相同的参考,你传递给addEventListener的功能,.bind返回新的参考,因为它是新的功能

bind()方法创建一个新函数,该函数在调用时将其关键字 设置为提供的值,并且在调用新函数时提供任何前面提供的给定序列的 参数。

所以在您的例子中,你有两个不同的基准,这就是为什么removeEventListener不起作用

let flag = true; 
const infiniteScrollFn = infiniteScroll.bind(this); 

function infiniteScroll() { 
    let enterpriseWrap = $('.enterprise-blocks'); 
    let contentHeight = enterpriseWrap.offsetHeight; 
    let yOffset = window.pageYOffset; 
    let y = yOffset + window.innerHeight; 

    if (this.props.hasMore) { 
    if (y >= contentHeight && flag) { 
     flag = false; 

     this.props.loadMoreVendors(function() { 
     flag = true; 
     }); 
    } 
    } else { 
    window.removeEventListener('scroll', infiniteScrollFn); 
    } 
} 

window.addEventListener('scroll', infiniteScrollFn); 

Example

+1

我喜欢这个解释。上投票。 –