2017-04-24 90 views
1

我在组件内部有一些代码检测该组件是否在滚动中可见。该代码如下所示:更改页面后卸载事件

constructor(props) { 
     super(props); 
     this.handleScrollAnimation = this.handleScrollAnimation.bind(this); 
    } 

    componentDidMount() { 
    this.handleLoadAnimation(); 
    window.addEventListener('scroll', _.throttle(this.handleScrollAnimation.bind(this), 300)); 
    } 

    componentWillUnmount() { 
    window.removeEventListener('scroll', this.handleScrollAnimation.bind(this)); 
    } 

    handleLoadAnimation() { 
    const component = this.CalloutBoxes; 
    if (this.isElementInViewport(component)) { 
     component.classList.add('already-visible'); 
    } 
    } 

    handleScrollAnimation() { 
    const component = this.CalloutBoxes; 
    if (this.isElementInViewport(component)) { 
     component.classList.add('animated'); 
    } 
    } 

    isElementInViewport(el) { 
    const rect = el.getBoundingClientRect(); 

    return rect.bottom > 0 && 
     rect.right > 0 && 
     rect.left < (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */ && 
     rect.top < (window.innerHeight || document.documentElement.clientHeight); /* or $(window).height() */ 
    } 

当我导航到另一页时,出现错误Cannot read property 'getBoundingClientRect' of null。我不知道我需要做什么来阻止这一点,并且找不到任何能够让我知道我需要做什么的概念。

这是我的组件的渲染功能:

render() { 
    const styles = { 
     image: { 
     backgroundImage: `url(${this.props.data.image})` 
     } 
    }; 

    return (
     <div 
     ref={c => { 
      this.CalloutBoxes = c; 
     }} 
     className="mini-nav-box" 
     > 
     <Link to={this.props.data.link}> 
      <div style={styles.image} className="mini-nav-box-bg"/> 
      <div className="mini-nav-box-content"> 
      <h3>{this.props.data.title}</h3> 
      <p>{this.props.data.copy}</p> 
      </div> 
     </Link> 
     </div> 
    ); 
    } 

这就是我所说的组件页面上:

{ calloutBoxes.map((box, index) => { 
    return <CalloutBoxes key={index} data={box}/>; 
})} 

编辑:

我看,我不得不删除.bind(this)来自remove和add event listner,因为他们每次都创建一个新函数。所以现在我remove事件监听者现在看起来是这样的:

window.removeEventListener('scroll', this.scrollFn); 

但是我仍然有isElementInViewport功能射击的问题,它没有它这些组件之一另一页上。

回答

0

所以我意识到我是非常非常愚蠢的。

您需要做的是将debounce添加到构造函数中,并将其从add事件侦听器中删除。

构造函数的代码现在看起来是这样的:

constructor(props) { 
    super(props); 
    this.handleScroll = _.debounce(this.handleScrollAnimation.bind(this), 300); 
} 

然后componentDidMount看起来像现在这样:

componentDidMount() { 
    this.handleLoadAnimation(); 
    window.addEventListener('scroll', this.handleScroll); 
}