2017-04-24 83 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); 
}