반응에서 스크롤 애니메이션 처리
React에서 스크롤 위치를 올바르게 처리하는 방법은 무엇입니까?UX가 좋아져서 부드러운 스크롤이 정말 좋아요.리액트에서 DOM을 조작하는 것은 안티패턴이기 때문에 어떻게 하면 어떤 위치/요소로 부드럽게 스크롤할 수 있을까요?보통 요소의 scrollTop 값을 변경하지만 이는 DOM에서의 조작이므로 허용되지 않습니다.
코드:
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
'programing' 카테고리의 다른 글
| 오브젝트 어레이를 JSON 경유로 ASP에 투고합니다.넷 MVC3 (0) | 2023.04.05 |
|---|---|
| inMemory에 사용자를 추가하려면 어떻게 해야 합니까?구축 후 인증 빌더를 사용하시겠습니까? (0) | 2023.04.05 |
| angular js에 사용할 apache 2에 대한 규칙 다시 쓰기 (0) | 2023.04.05 |
| MERN에서 백엔드 및 프런트엔드의 파일 구조를 구성하는 방법 (0) | 2023.04.05 |
| 플러그인에서 제목 태그를 변경하도록 wp_title을 설정하시겠습니까? (0) | 2023.04.05 |