programing

React js를 사용하여 사용자가 div의 맨 아래로 스크롤하는 경우 감지

bestprogram 2023. 2. 26. 16:23

React js를 사용하여 사용자가 div의 맨 아래로 스크롤하는 경우 감지

다른 섹션이 있는 웹사이트를 가지고 있습니다.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);
  }
};

보다 심플한 방법은 스크롤 높이, 스크롤 탑 및 클라이언트를 사용하는 것입니다.높이.

스크롤 가능한 총 높이에서 스크롤 높이를 뺍니다.이 값이 보이는 영역과 같으면 바닥에 도달한 것입니다!

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

가능하고 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통상적인 리액트 방식을 따릅니다(ID를 사용하지 않고 DOM 노드를 무시합니다).

또한 페이지를 더 높게 트리거하도록 방정식을 조작할 수 있습니다(예: 느린 콘텐츠 로드/무한 스크롤).

하면 .el.getBoundingClientRect().bottom

isBottom(el) {
  return el.getBoundingClientRect().bottom <= window.innerHeight;
}

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

componentWillUnmount() {
  document.removeEventListener('scroll', this.trackScrolling);
}

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

다음은 리액트 훅과 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;

이 답변은 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를 스크롤할 수 없는 경우에는 동작하지 않으며 첫 번째 div 뒤에 있는 div와 같은 하위 요소에서는 onScroll이 작동하지 않습니다.따라서 onScroll은 오버플로가 있는 첫 번째 HTML 태그에 있어야 합니다.

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);

리액트 훅과 레퍼런스를 사용하기 위해 샹드레쉬의 답변을 확장하면 다음과 같이 할 수 있습니다.

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>
    );
}

React에 다음 기능을 추가합니다.컴포넌트 완료:]

  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
    );
  }

이미 답변이 끝난 것은 알지만, 다른 좋은 해결책은 DIY가 아닌 오픈 소스 커뮤니티에서 이미 구할 수 있는 것을 사용하는 것이라고 생각합니다.리액트 웨이포인트는 바로 이 문제를 해결하기 위해 존재하는 라이브러리입니다.(HTML 엘리먼트를 스크롤 할 것인지 아닌지를 판단하는 이 문제 공간을 왜 웨이포인트라고 하는지 묻지 마세요).

소품 계약도 잘 되어 있고 꼭 확인해 보시기 바랍니다.

나는 내 코드를 팔로우하곤 했다.

.syslog-table-syslog {패딩탑: 50px;높이: 100%;
overflow-y: 스크롤;}

그리고 대상 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>
            )

스크롤 div 뒤에 높이가 0인 div를 넣은 다음 이 div가 표시되는지 여부를 감지하려면 이 사용자 지정 훅을 사용하십시오.

  const bottomRef = useRef();
  const reachedBottom = useCustomHooks(bottomRef);

  return(
  <div>
   {search resault}
  </div>
  <div ref={bottomRef}/> )

reachedBottom로 전환됩니다.true바닥에 닿으면

브라우저가 div의 아래까지 스크롤되었는지 여부를 평가하기 위해 다음 솔루션을 선택했습니다.

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

아래 솔루션은 대부분의 브라우저에서 정상적으로 동작하지만 일부 브라우저에서는 문제가 있습니다.

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

보다 좋고 정확한 방법은 모든 브라우저에서 작동하는 아래의 코드를 사용하는 것은 모든 브라우저에서 동작합니다.

Math.abs(e.target.scrollHeight - e.target.clientHeight - e.target.scrollTop) < 1

그래서 최종 코드는 다음과 같아야 합니다.

const App = () => {
   const handleScroll = (e) => {
     const bottom = Math.abs(e.target.scrollHeight - e.target.clientHeight - e.target.scrollTop) < 1;
     if (bottom) { ... }
   }
   return(
     <div onScroll={handleScroll}>
       ...
     </div>
   )
}

이 답변은 Brendan의 것이지만, 저는 이 방법으로 그 코드를 사용할 수 있습니다.

window.addEventListener("scroll", (e) => {
        const bottom =
            e.target.scrollingElement.scrollHeight -
                e.target.scrollingElement.scrollTop ===
            e.target.scrollingElement.clientHeight;
        console.log(e);
        console.log(bottom);
        if (bottom) {
            console.log("Reached bottom");
        }
    });

다른 사용자는 다음 방법으로 타깃 내부에서 직접 액세스할 수 있습니다.e.target.scrollHeight,
에 의해 같은 것을 달성할 수 있다.e.target.scrollingElement.scrollHeight

언급URL : https://stackoverflow.com/questions/45585542/detecting-when-user-scrolls-to-bottom-of-div-with-react-js