[WEB] 프론트엔드

IntersectionObserver 활용하기

[FE] Lighthouse 2023. 11. 18. 15:11

IntersectionObserver

랜딩페이지 작업 중 특정 색션에 접근 시 애니메이션이 발생하도록 구현해야 했습니다.
`Scroll` 이벤트를 활용해 구현을 할 수 있지만,
사용해본 경험이 있는 `IntersectionObserver` 을 활용해 구현했습니다.

과정

먼저 ref 객체를 만들어 관찰해야할 요소에 바인딩 해줍니다.

 

<CompanySection ref={companySectionRef}>
    <InfoBox>
      <h2>안심업체</h2>
        <p className="desc">
          소중한 우리 집,
          <br />
          안심하고 맡겨보세요.
        </p>
      </InfoBox>
 </CompanySection>

 

IntersectionObserver 객체를 생성하고, observer 콜백 함수와 옵션 객체를 인자로 넘겨줍니다.
콜백 함수의 매개변수로 entries 를 받을 수 있습니다.
entries 는 IntersectionObserverEntry 객체의 배열인데, 해당 객체는 관찰하기로 한 타겟과 루트가 교차되는 정보를 담고 있습니다.

 

> IntersectionObserverEntry
https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry

 

IntersectionObserverEntry - Web APIs | MDN

The IntersectionObserverEntry interface of the Intersection Observer API describes the intersection between the target element and its root container at a specific moment of transition.

developer.mozilla.org

 

저는 교차되는 순간을 감지하여 애니메이션이 발현되기를 원했습니다.
하여 `entries` 배열을 돌아 entry 의 `isIntersecting` 값을 체크했고,
해당 값이 `true` 일 때 애니메이션이 발현되도록 코드를 작성했습니다.

해당 컴포넌트가 마운트 되는 시점부터 해당 ref 를 감시해야 하므로 `useEffect` 내부에 코드를 작성했습니다. `IntersectionObserver` 객체를 생성한 후 `observe` 메서드를 통해 ref 감시를 시작합니다.

컴포넌트의 생명주기가 끝나 unmount 된다면 해당 옵저버도 감시를 그만둬야합니다.
하여 `useEffect` 의 cleanup 함수를 통해 `disconnect` 시켜줍니다.
`disconnect` 해주지 않으면 메모리를 계속 잡아먹게 됩니다!

 

useEffect(() => {
    const observer = new IntersectionObserver(
        (entries) => {
            entries.forEach(({ isIntersecting }) => {
            setIsCompanyAnimationOn(isIntersecting);
            });
        },
        { threshold: 0.5 },
    );

    if (companySectionRef?.current) {  
      observer.observe(companySectionRef.current);  
    }  
    return () => observer.disconnect();  
}, []);

 

자세한 내용은 MDN 을 참고하시면 좋습니다.

> https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver

예전에 Intersection Observer 을 활용해 무한 스크롤을 구현해본 코드도 첨부해봅니다.

> https://github.com/kangactor123/rq-with-recoil/blob/master/src/component/InfiniteScroll/InfiniteScroll.tsx