
Intersection observer는 기본적으로 브라우저 뷰포트(Viewport)와 설정한 요소(Element)의 교차점을 관찰하며, 요소가 뷰포트에 포함되는지 포함되지 않는지 구별하는 기능을 제공합니다.
이 기능은 비동기적으로 실행되기 때문에, scroll 같은 이벤트 기반의 요소 관찰에서 발생하는 렌더링 성능이나 이벤트 연속 호출 같은 문제 없이 사용할 수 있습니다.
const observer = new IntersectionObserver((entries, observer) => { ,,, }, options) // 관찰자 초기화
observer.observe() // 관찰 대상 등록
new IntersectionObserver()호출하여 반환된 객체를 통해 observe 메서드를 호출하여 관찰할 대상을 등록할 수 있습니다.
IntersectionObserver 생성자 함수는 두 개의 인수를 전달받습니다.
(entries, observer) => { ,,, }
: 첫 번째 인수로 전달되는 콜백 함수는 관찰 대상이 등록되거나 교차 이벤트가 발생하면 호출되는 함수입니다.
콜백 함수가 호출될 때 전달 받는 첫 번째 인수(entries)는 관찰 대상을 요소로 갖는 배열을 전달받습니다. 관찰 대상은 아래와 같은 메서드와 프로퍼티를 갖고 있습니다
boundingClientRect : 관찰 대상의 사각형 정보, Element.prototype.getBoundingClientRect 메서드와 동일한 정보를 반환합니다
intersectionRect : 관찰 대상과 루트 요소간 교차한 영역 정보
isIntersecting : 관찰 대상과 루트 요소간 교차 상태를 불리언 값으로 반환
intersectionRatio : 관찰 대상이 루트 요소와 얼마나 교차하는(겹치는)지의 수치를 0.0과 1.0 사이의 숫자 반환
rootBounds : 지정한 루트 요소의 사각형 정보
target : 관찰 대상 요소
observer : 콜백이 실행되는 해당 인스턴스를 참조합니다.
options
root : 루트 요소를 설정할 수 있습니다. 생략한 경우 기본값으로 브라우저의 뷰포트가 루트 요소로 설정됩니다.
threshold : 콜백 함수가 실행될 루트 요소와 관찰 대상간 교차 비율을 0부터 1사이 숫자값으로 설정할 수 있습니다. 기본값은 0으로 교차되는 순간 실행되며, 만약 0.3으로 설정시 30% 교차되는 시점에 콜백 함수가 실행됩니다.
observer : 루트 요소와 관찰 대상간 관찰을 시작하게 됩니다.
unobserver : 관찰 대상 요소의 관찰을 중지합니다. 이때 인수로 관찰을 중지할 관찰 대상을 전달해주어야 합니다.
disconnect : 모든 관찰 대상에 대해 관찰을 중지합니다.
const useTargetIntersecting = (targets: RefObject<Element>[]) => {
const [isTargetsVisible, setIsTargetsVisible] = useState<boolean[]>(new Array(targets.length).fill(false))
useEffect(() => {
// 옵저버 생성
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry, i) => {
if(!entry.isIntersecting) return
const prev = isTargetsVisible.slice(0, i)
const next = isTargetsVisible.slice(i, -1)
setIsTargetsVisible([...prev, true, ...next])
observer.unobserver(entry.target)
})
})
// 관찰 대상 등록
targets.forEach((target, i) => {
if(target.current && !isTargetsVisible[i]) {
observer.observe(target.current)
}
})
return () => observe.disconnect()
}
return isTargetsVisible
}
export default useTargetIntersecting