[API] IntersectionObserver

해달·2022년 5월 19일
0

프로젝트 무한스크롤 구현에 사용하려고 팀원분이 만들어두었던 훅을 보게되었는데
IntersectionObserver API를 처음 알게되어 내용을 찾아보았다

IntersectionObserver

브라우저의 Viewporttarget으로 설정한 엘리먼트의 교차영역을 관찰하며 요소가 뷰포트와의 겹치는 영역이 있는지 구별하는 기능을 제공해주는 API다

Viewport는 화면 크기를 이야기하며 웹 페이지가 브라우저 화면상에서 실제로 표시되는 영역이다

new IntersectionObserver 생성자 함수로 생성한 인스턴스로 관찰자를 초기화하고 인수로 콜백,옵션 을 가진다

let observer = new IntersectionObserver(callback, options); // 관찰자 초기화

observer.observe(element) // 관찰할 대상(요소) 등록

콜백함수는 관찰대상이 등록 되거나
가시성의 변화(Visibility, 보이는지 보이지 않는지) 가 생기면
관찰자는 콜백을 실행한다

관찰대상 엘리먼트와 루트 엘리먼트와 겹치는 영역이 생기면 옵저버는 콜백함수를 실행하게 된다.

콜백함수는 entries,observer를 인수로 받는다.


entries

IntersectionObserver 인스턴스의 배열이다

IntersectionObserverEntry : 인터페이스는 특정 전환 순간에 대상 요소와 해당 루트 컨테이너 간의 교차를 설명한다

let callback = (entries, observer) => {
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // target element:
    //   entry.boundingClientRect 
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  });
};

interface IntersectionObserverEntry {
    readonly boundingClientRect: DOMRectReadOnly;
    readonly intersectionRatio: number;
    readonly intersectionRect: DOMRectReadOnly;
    readonly isIntersecting: boolean;
    readonly rootBounds: DOMRectReadOnly | null;
    readonly target: Element;
    readonly time: DOMHighResTimeStamp;
}

hook에서 사용 된 isIntersecting는 관찰 대상 엘리먼트가 루트와 영역이 겹치는지 여부를 나타낸다

observer

콜백이 실행되는 해당 인스턴스를 참조한다

옵저버의 메소드는 3가지가 있다 (관찰자 메소드)

observe() : 관찰 대상의 관찰을 시작한다
unobserve() : 관찰 대상의 관찰을 중지한다
disconnect() : intersectionObserver 인스턴스들의 모든 관찰을 중지한다

options

인터섹션옵저버 생성자함수를 선언 할 때 옵션값도 넘기게되는데
옵션값으로는 root, rootmargin, thresholds 를 갖는다

threshold는 옵저버의 콜백함수가 실행되기 위해서 관찰대상의 엘리먼트와 루트 앨리먼트가 겹치는 영역이 얼마나 필요한지 백분율로 표시한다
ex) 0.5로 설정을 하게 되면 관찰 대상 엘리먼트가 루트엘리먼트와 50% 겹칠 때 옵저버가 콜백함수를 실행한다


useIntersectionObserver hook

import { useEffect, useRef, useState } from 'react';

export default function useIntersectionObserver() {
  const ref = useRef<HTMLDivElement>(null);
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      setVisible(entry.isIntersecting);
    });
    // 등록되거나 가시성의 변화가 생길 때 실행되는 콜백
    
    
    if (ref.current) {
      observer.observe(ref.current); // 관찰할 대상(요소) 등록
    }
    return () => {
      observer.disconnect();
    };
  }, [ref]);

  return { ref, visible };
}

같이 프로젝트를 진행해준 팀원 덕분에 새로운 내용들을 많이 공부하게되는거 같아서 항상 감사한마음이다 🙂

훅은 구현해두었지만 결론적으로는 라이브러리를 사용하는 형태로 훅을 사용하지 않게 되었다
훅을 통해서 구현되는 방식을 추가적으로 공부하게 되었고 유용한 라이브러리도 알아갈 수 있었다


reference

Intersection Observer MDN

참고블로그

react-intersection-observer 라이브러리

0개의 댓글