programing

반응에서 스크롤 애니메이션 처리

fastcode 2023. 4. 5. 22:19
반응형

반응에서 스크롤 애니메이션 처리

React에서 스크롤 위치를 올바르게 처리하는 방법은 무엇입니까?UX가 좋아져서 부드러운 스크롤이 정말 좋아요.리액트에서 DOM을 조작하는 것은 안티패턴이기 때문에 어떻게 하면 어떤 위치/요소로 부드럽게 스크롤할 수 있을까요?보통 요소의 scrollTop 값을 변경하지만 이는 DOM에서의 조작이므로 허용되지 않습니다.

JSBIN

코드:

import React from 'react';
import ReactDOM from 'react-dom';


class App extends React.Component {
  handleClick = e => {
    for (let i = 1; i <= 100; i++) {
      setTimeout(() => (this.node.scrollTop = i), i * 2);
    }
  };

  render() {
    const someArrayToMap = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    return (
      <div ref={node => this.node = node} style={{overflow: 'auto', height: '100vh'}}>
        <button onClick={this.handleClick}>CLICK TO SCROLL</button>
        {
            [...someArrayToMap,
            ...someArrayToMap,
            ...someArrayToMap,
            ...someArrayToMap,
            ...someArrayToMap,
            ...someArrayToMap,
            ...someArrayToMap].map((e, i) => <div key={i}>some text here</div>)
        }
      </div>
    );
  }
}


ReactDOM.render(<App />, document.getElementById('root'));

리액트 방식으로 이를 실현하는 방법

레퍼런스랑 레퍼런스랑scrollIntoView메서드(와 함께)behavior: 'smooth'매끄러운 스크롤을 실현합니다).몇 줄의 코드일 뿐 패키지는 필요 없습니다.

스크롤 대상이라고 합니다.

<p ref={this.myRef} className="scrollToHere">[1] ...</p>

그리고 어떤 종류의 버튼은

<button onClick={() => {this.scroll(this.myRef)}} className="footnote">[1]</button>

스크롤 방식이라고 부르다

class App extends Component {
  constructor() {
    super()
    this.myRef = React.createRef();

  scroll(ref) {
    ref.current.scrollIntoView({behavior: 'smooth'})
  }
}

편집: 이 메서드는 모든 브라우저에서 아직 지원되지 않으므로(브라우저 지원 개요) 폴리필을 사용하는 것이 좋습니다.

window.scroll({top: 0, left: 0, behavior: 'smooth' })잘 먹히네요.

또한 브라우저의 호환성을 확인해야 합니다.

또는 폴리필 사용


편집: 완성도를 높이기 위해 웹 팩으로 동적으로 폴리필하는 방법을 소개합니다.

if (!('scrollBehavior' in document.documentElement.style)) {
//safari does not support smooth scroll
  (async () => {
    const {default: smoothScroll} = await import(
      /* webpackChunkName: 'polyfill-modern' */
      'smoothscroll-polyfill'
      )
    smoothScroll.polyfill()
  })()
}

이 동적 폴리필에 의해 브라우저가 부드러운 스크롤을 지원하지 않는 한 패키지는 ajax를 통해 로드됩니다.

polyfill-modern는 임의의 청크명으로 서버에 대한 요구 수를 줄이기 위해 웹 팩컴파일러가 패키지를 조합하도록 힌트합니다.

가장 간단한 방법:

window.scrollTo({top: 0, left: 0, behavior: 'smooth' });

이 간단한 JavaScript 코드는 모든 브라우저에서 작동합니다.

다음은 훅을 사용한 소규모 비의존성 솔루션입니다.

const useSmoothScrollTo = id => {
    const ref = useRef(null)
    useEffect(() => {
        const listener = e => {
            if (ref.current && location.hash === id) {
                ref.current.scrollIntoView({behavior: 'smooth'})
            }
        }
        window.addEventListener('hashchange', listener, true)
        return () => {
            window.removeEventListener('hashchange', listener)
        }
    }, [])
    return {
        'data-anchor-id': id,
        ref
    }
}

다음과 같이 사용합니다.

export const FeaturesSection = () => {
    const bind = useSmoothScrollTo('#features')
    return (
        <section {...bind} className={classes.features}>
        ...
        </section>
    )
}      

그러면 앱 내 다른 곳에서도 할 수 있습니다.

<a href="#features">Go to Features</a>

분명히 위와 같은 경고가 에 적용됩니다..scrollIntoView({behavior: 'smooth'})

이미 이 문제를 해결할 수 있는 몇 가지 좋은 패키지가 있습니다.

https://github.com/fisshy/react-scroll - 데모

https://www.npmjs.com/package/react-scroll-to-component 컴포넌트까지 간단하게 스크롤할 수 있습니다.

이게 도움이 됐으면 좋겠네요!

리액트에는 앵커까지 스크롤하기 위한 여러 라이브러리가 있습니다.선택할 수 있는 것은, 찾고 있는 기능이나 페이지의 기존의 설정에 의해서 다릅니다.

리액트 스크롤 가능 앵커(React Scrollable Anchor)는 URL 해시에 매핑된 앵커로 스크롤하기 위한 경량 라이브러리입니다.또한 현재 초점을 맞추고 있는 섹션을 기반으로 URL 해시를 업데이트합니다.[완전 공개]내가 이 도서관의 저자다.

다른 답변에서 언급된 React Scroll은 URL 내의 위치를 반영하지 않고 앵커까지 스크롤할 수 있는 보다 완전한 기능을 갖춘 라이브러리입니다.

이미 리액트 라우터를 사용하고 있는 경우는, 리액트 라우터 해시 링크 스크롤과 같은 것을 접속할 수도 있습니다.이 경우 URL 해시에도 연결됩니다.

API 섹션의 react-router 웹사이트가 너무 마음에 들어요.이 스크롤 ToDoc 컴포넌트는 전형적인 Vanilla의 매우 달콤한 번역입니다.JS 평활 스크롤 기능을 React로 변환합니다.이것은!에 의존합니다.

단순 후크:

function useScrollTo(): [string, () => void] {
    const id = useId();
    const handleScroll = useCallback(() => {
        const element = document.getElementById(id);
        if (element) {
            element.scrollIntoView({ behavior: 'smooth' });
        }
    }, [id]);

    return [id, handleScroll];
}

용도:

function App() {
    const [section2, scrollToSection2] = useScrollTo();

    return (
        <>
            <button onClick={scrollToSection2}>Scroll</button>

            <div id={section2}>Section 2</div>
        </>
    )
}

언급URL : https://stackoverflow.com/questions/44375093/handling-scroll-animation-in-react

반응형