Intersection Observer API는 타켓 요소와 상위 요소 또는 최상위 document의 viewport(현재 화면에 보여지고 있는 다각형(보통 직사각형)의 영역) 사이의 intersection 내의 변화를 비동기적으로 관찰하는 방법이다
Intersection Observer API 는 요소가 다른 요소(viewport)에 들어가거나 나갈 때 또는 요청한 부분만큼 두 요소의 교차부분이 변경될 때마다 실행될 콜백 함수를 등록할 수 있게 한다
즉 사이트는 요소의 교차를 지켜보기 위해 메인 스레드를 사영할 필요가 없어지고 브라우저는 원하는 대로 교차 영역 관리를 최적화 할 수 있다
정확히 몇 픽셀 겹쳐졌고 어떠한 픽셀이 겹쳐졌는지 Intersection Observer API가 알려줄 수 없다
그러나 "N%" 정도 교차한 경우 상호작용이 이루어져야 한다
와 같은 더 일반적인 사용 사례를 다룰 수 있다
Intersection Observer API는 다음과 같은 상황에 호출되는 콜백을 생서앟는 기능을 제공한다
대상(target)으로 칭하는 요소가 뷰포트나 특정요소(이 API에서 이를 root요소 혹은 root로 칭함)와 교차함
observer가 최초로 타켓을 관측하도록 요청받을 때마다
일반적으로 요소의 교차성이 가장 가까운 스크롤 가능한 조상에 의해 변경되길 원할 것이다 (혹은 대상 요소가 다른 요소의 자손이 아니라면 뷰포트에 의해 변경될 수 있다) document의 루트 요소를 기준으로 해당 요소를 관칙하기 위해서는 null
을 설정해야 한다
뷰포트 혹은 다른 요소를 root로 사용하건 간에 이 API는 같은 방식으로 동작한다
대상 요소의 가시성이 변경될 때마다 당신이 등록한 콜백 함수를 실행되며 그것은 당신이 원하는 만큼 root요소와 교차한다
root 와 대상 요소가 교차하는 정도를 intersection ratio라고 한다
이것은 대상 요소의 가시성 퍼센티지를 0.0 ~ 1.0의 숫자로 표현한다
intersection observer를 생성하기 위해서는 생성자 호출 시 콜백 함수를 제공해야 한다
이 콜백 함수는 threshold가 한 방향 혹은 다른 방향으로 교차할 때 실행된다
let options = {
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: 1.0
}
let observer = new intersectionObserver(callback, options);
threshold: 1.0
은 대상 요소가 root
에 지정된 요소 내에서 100% 보여질 때 콜백이 호출된 것을 의미한다
IntersectionObserver()
생성자에 전달되는 options
객체는 observer 콜백이 호출되는 상황을 조작할 수 있다. 이는 아래와 같은 필드를 가진다
root
root
값이 null
이거나 지정되지 않을 때 기본값으로 설정된다rootMargin
root
가 가진 여백이다margin
속성과 유사하다root
요소의 각 측면의 bounding box를 수축하거나 증가시키며 교차성을 개선하기 전에 적용된다threshold
0.5
로 설정하면 된다[0, 0.25, 0.5, 0.75, 1]
과 같은 배열을 설정하면 된다0
이며 (이는 요소가 1픽셀이라도 보이자 마자 콜백이 실애호딤을 의미한다)1.0
은 요소의 모든 픽셀이 화면에 노출되기전에는 콜백을 실행시키지 않음을 의마한다관찰자를 생성한 후에는 관찰할 대상 요소를 지정해야 한다
let target = document.querySelector('#listItem');
observer.observe(target);
대상이 지저오딘 임계값을 충족할 때마다 IntersectionObserver
콜백이 호출된다
콜백은 IntersectionObserverEntry
개체 목록과 관찰자를 수신한다
useEffect(() => {
const options = {};
const callback = (entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
// 스크롤이 이미지 최상단 도착시
// target element:
// entry.boundingClientRect => DOMRectReadOnly {x: 16, y: 763, width: 330, height: 24, top: 763, …}
// entry.intersectionRatio => 0.0416666679084301
// entry.intersectionRect => DOMRectReadOnly {x: 16, y: 763, width: 330, height: 1, top: 763, …}
// entry.isIntersecting => true
// entry.rootBounds => DOMRectReadOnly {x: 0, y: 0, width: 362, height: 764, top: 0, …}
// entry.target => <img src="...." src="...." />
// entry.time => 2752.600000023842
}
});
};
const observer = new IntersectionObserver(callback, options);
observer.observe(imgRef.current);
}, [])
콜백이 메인 스레드에서 실행된다