检测用户何时使用React js滚动到div的底部

时间:2017-08-09 08:33:43

标签: javascript reactjs

我有一个不同部分的网站。我正在使用segment.io来跟踪页面上的不同操作。如何检测用户是否已滚动到div的底部?我试过以下但是一旦我滚动页面而不是什么时候它似乎就会被触发  我到达了div的底部。

componentDidMount() {
  document.addEventListener('scroll', this.trackScrolling);
}

trackScrolling = () => {
  const wrappedElement = document.getElementById('header');
  if (wrappedElement.scrollHeight - wrappedElement.scrollTop === wrappedElement.clientHeight) {
    console.log('header bottom reached');
    document.removeEventListener('scroll', this.trackScrolling);
  }
};

10 个答案:

答案 0 :(得分:33)

更简单的方法是使用scrollHeightscrollTopclientHeight

从总可滚动高度中减去滚动高度。如果这等于可见区域,则您已到达底部!

element.scrollHeight - element.scrollTop === element.clientHeight

在react中,只需将onScroll侦听器添加到可滚动元素,并在回调中使用event.target

class Scrollable extends Component {

  handleScroll = (e) => {
    const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
    if (bottom) { ... }
  }

  render() {
    return (
      <ScrollableElement onScroll={this.handleScroll}>
        <OverflowingContent />
      </ScrollableElement>
    );
  }
}

我发现这更直观,因为它处理可滚动元素本身,而不是window,它遵循正常的React方式(不使用id,忽略DOM节点)。

您还可以操纵公式以触发更高的页面(例如,延迟加载内容/无限滚动)。

答案 1 :(得分:30)

您可以使用public Person(String name, int yearsOld, boolean student, char gender) { this.setName(name); age = yearsOld; //here you could avoid using this since local variable name is different and age will refer to class level's age . this.student = student; } 检查底部是否已被查看

el.getBoundingClientRect().bottom

答案 2 :(得分:4)

这是使用React Hooks和ES6的解决方案:

import React, { useRef, useEffect } from 'react';

const MyListComponent = () => {
  const listInnerRef = useRef();

  const onScroll = () => {
    if (listInnerRef.current) {
      const { scrollTop, scrollHeight, clientHeight } = listInnerRef.current;
      if (scrollTop + clientHeight === scrollHeight) {
        // TO SOMETHING HERE
        console.log('Reached bottom')
      }
    }
  };

  return (
    <div className="list">
      <div className="list-inner" onScroll={() => onScroll()} ref={listInnerRef}>
        {/* List items */}
      </div>
    </div>
  );
};

export default List;

答案 3 :(得分:3)

我们还可以使用ref。

来检测div的滚动结尾
import React, { Component } from 'react';
import {withRouter} from 'react-router-dom';
import styles from 'style.scss';

class Gallery extends Component{ 

  paneDidMount = (node) => {    
    if(node) {      
      node.addEventListener("scroll", this.handleScroll.bind(this));      
    }
  }

  handleScroll = (event) => {    
    var node = event.target;
    const bottom = node.scrollHeight - node.scrollTop === node.clientHeight;
    if (bottom) {      
      console.log("BOTTOM REACHED:",bottom); 
    }    
  }

  render() {
    var that = this;        
    return(<div className={styles.gallery}>
      <div ref={that.paneDidMount} className={styles.galleryContainer}>
        ...
      </div>

    </div>);   
  }
}

export default withRouter(Gallery);

答案 4 :(得分:2)

此答案属于Brendan,但属于功能组件

export default () => {
   const handleScroll = (e) => {
       const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
       if (bottom) { 
           console.log("bottom")
       }
    }

return (
     <div onScroll={handleScroll}  style={{overflowY: 'scroll', maxHeight: '400px'}}  >
        //overflowing elements here
   </div>
 );
 }

如果第一个div不可滚动,它将无法正常工作,并且onScroll在第一个div之后的子元素(如div)中对我不起作用,因此onScroll应该位于出现溢出的第一个HTML标签上

答案 5 :(得分:1)

我在代码中使用了跟随

.modify-table-wrap {
    padding-top: 50px;
    height: 100%;
    overflow-y: scroll;
}

并在目标js中添加代码

    handleScroll = (event) => {
        const { limit, offset } = this.state
        const target = event.target
        if (target.scrollHeight - target.scrollTop === target.clientHeight) {
            this.setState({ offset: offset + limit }, this.fetchAPI)
        }
    }
    return (
            <div className="modify-table-wrap" onScroll={this.handleScroll}>
               ...
            <div>
            )

答案 6 :(得分:0)

我知道已经回答了这个问题,但是,我认为另一个好的解决方案是使用开源社区中已有的资源代替DIY。 React Waypoints是一个用于解决此问题的库。 (尽管不要问我,为什么这个确定人是否滚动到HTML元素上方的问题空间称为“路标”,哈哈)

我认为它的道具合同设计得非常好,肯定会鼓励您检查一下。

答案 7 :(得分:0)

扩展chandresh的答案以使用react钩子和ref我会这样做;

import React, {useState, useEffect} from 'react';

export default function Scrollable() {
    const [referenceNode, setReferenceNode] = useState();
    const [listItems] = useState(Array.from(Array(30).keys(), (n) => n + 1));

    useEffect(() => {
        return () => referenceNode.removeEventListener('scroll', handleScroll);
    }, []);

    function handleScroll(event) {
        var node = event.target;
        const bottom = node.scrollHeight - node.scrollTop === node.clientHeight;
        if (bottom) {
            console.log('BOTTOM REACHED:', bottom);
        }
    }

    const paneDidMount = (node) => {
        if (node) {
            node.addEventListener('scroll', handleScroll);
            setReferenceNode(node);
        }
    };

    return (
        <div
            ref={paneDidMount}
            style={{overflowY: 'scroll', maxHeight: '400px'}}
        >
            <ul>
                {listItems.map((listItem) => <li>List Item {listItem}</li>)}
            </ul>
        </div>
    );
}

答案 8 :(得分:0)

在React.Component中添加以下函数,您就可以完成:]

  componentDidMount() {
    window.addEventListener("scroll", this.onScroll, false);
  }

  componentWillUnmount() {
    window.removeEventListener("scroll", this.onScroll, false);
  }

  onScroll = () => {
    if (this.hasReachedBottom()) {
      this.props.onScrollToBottom();
    }
  };

  hasReachedBottom() {
    return (
      document.body.offsetHeight + document.body.scrollTop ===
      document.body.scrollHeight
    );
  }

答案 9 :(得分:0)

为了评估我的浏览器是否已滚动到 div 的底部,我采用了以下解决方案:

const el = document.querySelector('.your-element');
const atBottom = Math.ceil(el.scrollTop + el.offsetHeight) === el.scrollHeight;