[React] 스크롤 이벤트 활용하기
FrontEnd/React

[React] 스크롤 이벤트 활용하기

728x90

이번에 프로젝트를 진행하다가 스크롤 이벤트를 활용할 상황이 생겨서 공부하게 되었다.

 

 

 

 

 

 

 

원래 스크롤이벤트를 활용하기 위해서는 window.addEventListener 함수를 활용하여 이벤트를 등록할 수 있다. 이를 훅으로 만들어 두면 보다 편하게 사용할 수 있다.

 

 

import { useEffect } from 'react';

// 스크롤이벤트 등록해주는 훅
export const useWindowScrollEvent = (
  listener: (this: Window, ev: Event) => any,
) => {
  useEffect(() => {
    window.addEventListener('scroll', listener);

    return () => {
      window.removeEventListener('scroll', listener);
    };
  }, []);
};

 

위와같이 스크롤이벤트를 등록해주는 훅을 생성해주고

 

const handleScrollAnimation = () => {
    console.log('스크롤이벤트 동작!!');
  };
  useWindowScrollEvent(handleScrollAnimation);

쓰고싶은 곳에서 위와같이 훅을 사용할 수 있다. 스크롤 이벤트가 발생할때마다 handleScrollAnimation 함수를 실행하게 된다.

 

 

 

내가 스크롤 이벤트가 필요한 이유는 특정 요소의 애니메이션을 스크롤을 내려서 해당 요소에 도착했을때 애니메이션을 시작하게 하고 싶었기 때문이었다.

 

 

따라서 해당 요소가 내가 보고있는 화면에 있는지 체크해주는 함수를 사용했다.

 

 

//현재 viewport 안에 요소가 있는지 확인하는 함수
export const checkIsInViewport = (el: HTMLElement | null) => {
  if (el === null) return false;
  if (!el || !window) {
    return false;
  }

  const { top: elementTop, bottom: elementBottom } = el.getBoundingClientRect();

  return elementBottom > 0 && elementTop <= window.innerHeight;
};

 

리액트에서 useRef를 활용하면 요소 정보를 가져올 수 있고, 이를 활용해서 내가 보고있는 부분에 해당 요소가 있으면 true를 만들어주는 함수를 작성했다.

 

 

const [animation, setAnimation] = useState(false);
  const notebookRef = useRef<HTMLDivElement>(null);

  //스크롤이 노트북까지 가면 애니메이션 동작
  const handleScrollAnimation = () => {
    setAnimation(
      notebookRef?.current ? checkIsInViewport(notebookRef?.current) : false,
    );
  };
  useWindowScrollEvent(handleScrollAnimation);

 

 

따라서 원하는 부분의 ref를 따온 후, 요소가 화면에 있는지 체크하여 화면에 있을때 className을 추가해주어 애니메이션을 시작하게 해 주었다.

 

<div
          className={animation ? 'animation' : 'notebook-non'}
          ref={notebookRef}
        >
          <NoteBookSVG width="500px" />
        </div>

 

 

아래처럼 스크롤을 눌러 해당 요소부분에 왔을때 애니메이션이 동작하게 된다.

 

 

728x90