요소로 스크롤하는 방법?


181

스크롤 할 때마다 여러 메시지를 표시하는 채팅 위젯이 있습니다. 내가 지금 직면하고있는 문제는 메시지가로드 될 때 슬라이더가 맨 위에 고정되어 있다는 것입니다. 이전 배열의 마지막 색인 요소에 초점을 맞추고 싶습니다. 인덱스를 전달하여 동적 참조를 만들 수 있다는 것을 알았지 만이를 달성하기 위해 사용할 스크롤 기능의 종류도 알아야합니다.

 handleScrollToElement(event) {
    const tesNode = ReactDOM.findDOMNode(this.refs.test)
    if (some_logic){
      //scroll to testNode      
    }
  }

  render() {

    return (
      <div>
        <div ref="test"></div>
      </div>)
  }

답변:


301

반응식 16.8 +, 기능 컴포넌트

import React, { useRef } from 'react'

const scrollToRef = (ref) => window.scrollTo(0, ref.current.offsetTop)   
// General scroll to element function

const ScrollDemo = () => {

   const myRef = useRef(null)
   const executeScroll = () => scrollToRef(myRef)

   return (
      <> 
         <div ref={myRef}>I wanna be seen</div> 
         <button onClick={executeScroll}> Click to scroll </button> 
      </>
   )
}

StackBlits에 대한 전체 데모를 보려면 여기를 클릭하십시오.

반응 16.3 +, 클래스 구성 요소

class ReadyToScroll extends Component {

    constructor(props) {
        super(props)
        this.myRef = React.createRef()  
    }

    render() {
        return <div ref={this.myRef}></div> 
    }  

    scrollToMyRef = () => window.scrollTo(0, this.myRef.current.offsetTop)   
    // run this method to execute scrolling. 

}

클래스 컴포넌트-Ref 콜백

class ReadyToScroll extends Component {
    myRef=null
    // Optional

    render() {
        return <div ref={ (ref) => this.myRef=ref }></div>
    } 

    scrollToMyRef = () => window.scrollTo(0, this.myRef.offsetTop)
    // run this method to execute scrolling. 
}

문자열 참조를 사용하지 마십시오.

문자열 참조는 성능에 해를 끼치며 구성 할 수 없으며 나갈 것입니다 (2018 년 8 월).

문자열 참조에는 몇 가지 문제가 있으며 레거시로 간주되며 향후 릴리스 중 하나에서 제거 될 수 있습니다. [공식 리 액트 문서]

resource1 resource2

선택 사항 : 스크롤 애니메이션 다듬기

/* css */
html {
    scroll-behavior: smooth;
}

아이에게 심판을 전달

우리는 ref가 반응 요소가 아닌 dom 요소에 부착되기를 원합니다. 따라서 하위 컴포넌트로 전달할 때 prop ref의 이름을 지정할 수 없습니다.

const MyComponent = () => {
    const myRef = useRef(null)
    return <ChildComp refProp={myRef}></ChildComp>
} 

그런 다음 심판 소품을 돔 요소에 부착하십시오.

const ChildComp = (props) => {
    return <div ref={props.refProp} />
}

5
window.scrollTo(0, offsetTop)현재 브라우저에서 더 나은 지원을 제공하는 더 나은 옵션입니다
MoMo

1
예에서 일관성을 유지할 수 있습니다. myRef에서 시작하여 domRef로 시작하여 tesNode?로 끝납니다. 그것은 매우 혼란
루이스 레 코크

4
사실 이후 분명히 이것은 React 구성 요소가 아니라 기본 DOM 요소에만 작동한다는 점을 언급하는 것이 중요합니다.
jpunk11

1
@ jpunk11 방금 답변을 업데이트했습니다. 업데이트 된 답변은 자식 클래스 구성 요소에있는 dom 요소로 스크롤하는 방법을 설명합니다.
벤 잉어

2
@SimonFranzen 업데이트 된 답변-TLDR-클래스 구성 요소 사례를 살펴보십시오. scrollToMyRef가 호출되면 참조를 첨부 한 자식으로 스크롤됩니다. 메서드를 다른 자식 구성 요소에 전달하고 여기에서 트리거 할 수 있습니다.
벤 잉어

55

이것은 나를 위해 일했다

this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })

편집 : 나는 의견에 따라 이것을 확장하고 싶었습니다.

const scrollTo = (ref) => {
  if (ref /* + other conditions */) {
    ref.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}

<div ref={scrollTo}>Item</div>

1
어디에 넣을

수명주기 메서드 또는 생성자
su_sundariya

1
매력처럼 작동합니다. 위의 어느 것도 나를 위해 작동하지 않습니다, 이것은 받아 들여야합니다!
Shin

1
나를 위해 일한 것은 'start'가 'block'매개 변수의 기본값입니다.
Liron Lavi

@ Ben Carp의 대답이 그렇지 않을 때 이것은 나를 위해 일했습니다.
Jason Masters

37

https://www.w3schools.com/Jsref/prop_element_offsettop.asp에서 이미 결정한 요소의 상단 위치를 찾은 다음 https://www.w3schools.com/Jsref/met_win_scrollto.aspscrollTo 메소드 를 통해이 위치로 스크롤 하십시오.

이와 같은 것이 작동해야합니다.

handleScrollToElement(event) {
  const tesNode = ReactDOM.findDOMNode(this.refs.test)
  if (some_logic){
    window.scrollTo(0, tesNode.offsetTop);
  }
}

render() {

  return (
    <div>
      <div ref="test"></div>
    </div>)
}

최신 정보:

이후 v16.3 반작용React.createRef() 바람직

constructor(props) {
  super(props);
  this.myRef = React.createRef();
}

handleScrollToElement(event) {
  if (<some_logic>){
    window.scrollTo(0, this.myRef.current.offsetTop);
  }
}

render() {

  return (
    <div>
      <div ref={this.myRef}></div>
    </div>)
}

2
이것이 더 나은 대답입니다. 사용하는 ReactDOM.findDomNode()것이 더 나은 방법입니다-React는 컴포넌트를 다시 렌더링하기 때문에 함수를 호출 할 때 ID로 얻는 div가 존재하지 않을 수 있습니다.
Good Idea

4
공식 문서에 따르면 사용을 피해야 findDOMNode합니다. 대부분의 경우 참조를 DOM 노드에 첨부하고 findDOMNode전혀 사용하지 않을 수 있습니다 .
Facyo Kouch

1
문자열 매핑으로 this.refs를 사용하는 것은 더 이상 사용되지 않습니다. stackoverflow.com/questions/43873511/…
Himmet Avsar

1
참고 : this.myRef.current.scrollIntoView()대신 사용해야 했습니다 window.scrollTo(0, this.myRef).
Babbz77

14

findDOMNode를 사용하는 것은 결국 더 이상 사용되지 않을 것입니다.

선호되는 방법은 콜백 참조를 사용하는 것입니다.

깃 허우 에슬 린트


3
답변이 지워지지 않도록 링크 된 자료의 관련 부분을 포함 시키십시오.
totymedli

12

이제 useRef반응 후크 API에서 사용할 수 있습니다

https://reactjs.org/docs/hooks-reference.html#useref

선언

let myRef = useRef()

구성 요소

<div ref={myRef}>My Component</div>

사용하다

window.scrollTo({ behavior: 'smooth', top: myRef.current.offsetTop })

귀하의 코드를 사용하려고합니다. 나는 console.log그것이 당신의 window.scrollTo진술을 실행 하고 있음 을 알 수 있지만 (내 경우에 맞게 조정되었지만) 스크롤하지는 않습니다. 이것이 React Bootstrap Modal을 사용하고 있다는 사실과 관련이 있습니까?
robertwerner_sf

9

scrollIntoView메소드를 사용 하여 주어진 요소로 스크롤 할 수도 있습니다 .

handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
 if (some_logic){
  tesNode.scrollIntoView();
  }
 }

 render() {
  return (
   <div>
     <div ref="test"></div>
   </div>)
}

9

파티에 늦었을 수도 있지만 적절한 방법으로 내 프로젝트에 동적 참조를 구현하려고했지만 알 때까지 찾은 모든 대답은 내 취향에 만족하지 못하므로 내가 생각하는 해결책을 생각해 냈습니다. 단순하고 기본적이고 권장되는 반응 방식을 사용하여 심판을 만듭니다.

때로는 문서 작성 방법이 알려진 양의 뷰가 있다고 가정하고 대부분의 경우이 수를 알 수 없으므로이 경우 문제를 해결하는 방법이 필요하며 필요한 수의 알 수없는 뷰에 대한 동적 참조를 작성하십시오 수업에 보여

그래서 내가 생각하고 완벽하게 작동 할 수있는 가장 간단한 해결책은 다음과 같습니다.

class YourClass extends component {

state={
 foo:"bar",
 dynamicViews:[],
 myData:[] //get some data from the web
}

inputRef = React.createRef()

componentDidMount(){
  this.createViews()
}


createViews = ()=>{
const trs=[]
for (let i = 1; i < this.state.myData.lenght; i++) {

let ref =`myrefRow ${i}`

this[ref]= React.createRef()

  const row = (
  <tr ref={this[ref]}>
<td>
  `myRow ${i}`
</td>
</tr>
)
trs.push(row)

}
this.setState({dynamicViews:trs})
}

clickHandler = ()=>{

//const scrollToView = this.inputRef.current.value
//That to select the value of the inputbox bt for demostrate the //example

value=`myrefRow ${30}`

  this[value].current.scrollIntoView({ behavior: "smooth", block: "start" });
}


render(){

return(
<div style={{display:"flex", flexDirection:"column"}}>
<Button onClick={this.clickHandler}> Search</Button>
<input ref={this.inputRef}/>
<table>
<tbody>
{this.state.dynamicViews}
<tbody>
<table>
</div>


)

}

}

export default YourClass

이렇게하면 스크롤이 원하는 행으로 이동합니다 ..

환호하고 그것이 다른 사람들을 돕는 희망


8

2019 년 7 월-전용 후크 / 기능

전용 후크 / 함수는 구현 세부 정보를 숨길 수 있으며 구성 요소에 간단한 API를 제공합니다.

반응 16.8 + 기능적 구성 요소

const useScroll = () => {
  const htmlElRef = useRef(null)
  const executeScroll = () => window.scrollTo(0, htmlElRef.current.offsetTop)

  return [executeScroll, htmlElRef]
}

모든 기능적 구성 요소에서 사용하십시오.

const ScrollDemo = () => {
    const [executeScroll, htmlElRef] = useScroll()
    useEffect(executeScroll, []) // Runs after component mounts

    return <div ref={htmlElRef}>Show me</div> 
}

전체 데모

반응 16.3 + 클래스 컴포넌트

const utilizeScroll = () => {
  const htmlElRef = React.createRef()
  const executeScroll = () => window.scrollTo(0, htmlElRef.current.offsetTop)

  return {executeScroll, htmlElRef}
}

모든 클래스 구성 요소에서 사용하십시오.

class ScrollDemo extends Component {
  constructor(){
    this.elScroll = utilizeScroll()
  }

  componentDidMount(){
    this.elScroll.executeScroll()
  }

  render(){
    return <div ref={this.elScroll.htmlElRef}>Show me</div> 
  }
} 

전체 데모


7

이 방법으로 시도 할 수 있습니다.

 handleScrollToElement = e => {
    const elementTop = this.gate.offsetTop;
    window.scrollTo(0, elementTop);
 };

 render(){
  return(
      <h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
 )}

좋은 해결책이지만 this.gate.offsetTop 대신 e.offsetTop을 원하고 this.gate를 함수에 전달하십시오.
KingOfHypocrites

5

당신은 같은 것을 사용할 수 있습니다 componentDidUpdate

componentDidUpdate() {
  var elem = testNode //your ref to the element say testNode in your case; 
  elem.scrollTop = elem.scrollHeight;
};

3
나는 요소 ID를 사용하는 것이 바람직하지 않다고 생각합니다. 그것은 가상 돔 개념을
깨뜨립니다

라이프 사이클 방법을 사용하는 것은 코드를 실행하기 위해 WHEN / WHERE까지 진행하는 방법입니다. 그러나 아마도 실제 코드에 대해이 답변에서 볼 수있는 다른 방법론을 사용하고 싶을 것입니다
Dameo

3

간단한 시나리오가 있습니다. 사용자가 내 Material UI Navbar에서 메뉴 항목을 클릭하면 페이지의 섹션으로 스크롤하고 싶습니다. refs를 사용하고 모든 구성 요소를 통해 스레드 할 수는 있지만 스레딩 소품은 여러 구성 요소를 소품으로 사용하여 코드가 취약하기 때문에 싫어합니다.

방금 반응 구성 요소에 바닐라 JS를 사용했는데 제대로 작동합니다. 스크롤하려는 요소와 헤더 구성 요소에 ID를 배치하여 방금 수행했습니다.

const scroll = () => {
  const section = document.querySelector( '#contact-us' );
  section.scrollIntoView( { behavior: 'smooth', block: 'start' } );
};

2

다음과 같이하세요:

1) 설치 :

npm install react-scroll-to --save

2) 패키지를 가져옵니다.

import { ScrollTo } from "react-scroll-to";

3) 사용법 :

class doc extends Component {
  render() {
    return(
      <ScrollTo>
        {({ scroll }) => (
          <a onClick={() => scroll({ x: 20, y: 500, , smooth: true })}>Scroll to Bottom</a>
        )}
      </ScrollTo>
    )
  }
}

2

이 문제를 해결하기 위해 사용할 수 있는 클래스 구성 요소 코드 스 니펫 은 다음과 같습니다 .

이 접근법은 심판을 사용 했으며 대상 심판으로 부드럽게 스크롤 합니다.

import React, { Component } from 'react'

export default class Untitled extends Component {
  constructor(props) {
    super(props)
    this.howItWorks = React.createRef() 
  }

  scrollTohowItWorks = () =>  window.scroll({
    top: this.howItWorks.current.offsetTop,
    left: 0,
    behavior: 'smooth'
  });

  render() {
    return (
      <div>
       <button onClick={() => this.scrollTohowItWorks()}>How it works</button>
       <hr/>
       <div className="content" ref={this.howItWorks}>
         Lorem ipsum dolor, sit amet consectetur adipisicing elit. Nesciunt placeat magnam accusantium aliquid tenetur aspernatur nobis molestias quam. Magnam libero expedita aspernatur commodi quam provident obcaecati ratione asperiores, exercitationem voluptatum!
       </div>
      </div>
    )
  }
}

1

나를 위해 일한 것 :

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.myRef = React.createRef(); // Create a ref    
    }

    // Scroll to ref function
    scrollToMyRef = () => {
        window.scrollTo({
            top:this.myRef.offsetTop, 
            // behavior: "smooth" // optional
        });
    };

    // On component mount, scroll to ref
    componentDidMount() {
        this.scrollToMyRef();
    }

    // Render method. Note, that `div` element got `ref`.
    render() {
        return (
            <div ref={this.myRef}>My component</div>
        )
    }
}

1

머지 않아 머티리얼 UI 컴포넌트에서 이러한 솔루션을 작동시킬 수 없었습니다. current속성 이없는 것 같습니다 .

방금 div구성 요소 사이 에 빈칸을 추가 하고 ref 소품을 설정했습니다.


1

가장 좋은 방법은를 사용하는 것 element.scrollIntoView({ behavior: 'smooth' })입니다. 멋진 애니메이션으로 요소를 스크롤하여 볼 수 있습니다.

React와 결합 useRef()하면 다음과 같은 방법으로 수행 할 수 있습니다.

import React, { useRef } from 'react'

const Article = () => {
  const titleRef = useRef()

  function handleBackClick() {
      titleRef.current.scrollIntoView({ behavior: 'smooth' })
  }

  return (
      <article>
            <h1 ref={titleRef}>
                A React article for Latin readers
            </h1>

            // Rest of the article's content...

            <button onClick={handleBackClick}>
                Back to the top
            </button>
        </article>
    )
}

React 컴포넌트로 스크롤하려면 참조를 렌더링 된 요소로 전달해야합니다. 이 기사는 문제를 더 깊이 파고들 것입니다 .


0
 <div onScrollCapture={() => this._onScrollEvent()}></div>

 _onScrollEvent = (e)=>{
     const top = e.nativeEvent.target.scrollTop;
     console.log(top); 
}


0

onclick 함수 안에서 이것을 사용하여 id가 "step2Div"인 div로 부드럽게 스크롤했습니다.

let offset = 100;
window.scrollTo({
    behavior: "smooth",
    top:
    document.getElementById("step2Div").getBoundingClientRect().top -
    document.body.getBoundingClientRect().top -
    offset
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.