IntersectionObservers는 관찰된 요소가 브라우저의 표시 영역에 들어가거나 나올 때를 알려줍니다.
브라우저 지원
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
DOM의 요소가 표시되는 표시 영역에 들어오는 시점을 추적하려 한다고 가정해 보겠습니다. 이렇게 하는 것이 좋습니다. 적시에 이미지를 지연 로드할 수도 있고, 사용자가 실제로 특정 광고 배너를 보고 있는지 확인해야 할 수도 있습니다. 스크롤 이벤트를 연결하거나 주기적 타이머를 사용하고 getBoundingClientRect()
를 호출하면 됩니다.
지정할 수 있습니다.
그러나 이 접근 방식은 getBoundingClientRect()
를 호출할 때마다 브라우저가 전체 페이지의 레이아웃을 다시 설정하게 하고 웹사이트에 상당한 버벅거림이 발생하기 때문에 속도가 매우 느립니다. 사이트가 iframe 내에 로드되고 있음을 알고 사용자가 언제 요소를 볼 수 있는지 알고 싶다면 문제가 불가능에 가깝습니다. 단일 원본 모델과 브라우저에서는 iframe이 포함된 웹페이지의 데이터에 액세스할 수 없습니다. 이는 예를 들어 iframe을 사용하여 자주 로드되는 광고에서 발생하는 일반적인 문제입니다.
IntersectionObserver
는 이 공개 상태 테스트를 더 효율적으로 만들기 위해 설계되었으며 모든 최신 브라우저에 적용됩니다. IntersectionObserver
는 관찰된 요소가 브라우저의 표시 영역에 들어가거나 나가는 시점을 알려줍니다.
IntersectionObserver
를 만드는 방법
API는 다소 작으며 다음 예를 통해 가장 잘 설명되어 있습니다.
const io = new IntersectionObserver(entries => {
console.log(entries);
}, {
/* Using default options. Details below */
});
// Start observing an element
io.observe(element);
// Stop observing an element
// io.unobserve(element);
// Disable entire IntersectionObserver
// io.disconnect();
IntersectionObserver
의 기본 옵션을 사용하면 요소가 부분적으로 뷰에 표시될 때와 완전히 표시 영역을 벗어날 때 모두 콜백이 호출됩니다.
여러 요소를 관찰해야 하는 경우 observe()
를 여러 번 호출하여 동일한 IntersectionObserver
인스턴스를 사용하는 여러 요소를 관찰하는 것이 좋습니다.
entries
매개변수는 IntersectionObserverEntry
객체의 배열인 콜백에 전달됩니다. 이러한 각 객체에는 관측된 요소 중 하나에 대해 업데이트된 교차 데이터가 포함됩니다.
🔽[IntersectionObserverEntry]
time: 3893.92
🔽rootBounds: ClientRect
bottom: 920
height: 1024
left: 0
right: 1024
top: 0
width: 920
🔽boundingClientRect: ClientRect
// ...
🔽intersectionRect: ClientRect
// ...
intersectionRatio: 0.54
🔽target: div#observee
// ...
rootBounds
은 기본적으로 표시 영역인 루트 요소에서 getBoundingClientRect()
를 호출한 결과입니다. boundingClientRect
는 관찰된 요소에서 호출된 getBoundingClientRect()
의 결과입니다. intersectionRect
는 이 두 직사각형의 교차점이며, 관찰된 요소에서 표시되는 부분을 효과적으로 알려줍니다. intersectionRatio
는 밀접하게 관련되어 있으며, 요소가 표시되는 정도를 알려줍니다. 이 정보를 원하는 대로 사용하면 애셋이 화면에 표시되기 전에 적시 로드와 같은 기능을 구현할 수 있습니다. 효율적입니다.
IntersectionObserver
는 데이터를 비동기식으로 전달하며 콜백 코드는 기본 스레드에서 실행됩니다. 또한 사양에는 실제로 IntersectionObserver
구현이 requestIdleCallback()
를 사용해야 한다고 명시되어 있습니다. 이는 제공된 콜백에 대한 호출의 우선순위가 낮으며 유휴 시간 동안 브라우저에서 실행함을 의미합니다. 이는 의식적인 설계 결정입니다.
스크롤 div
저는 요소 내에서 스크롤하는 것을 그다지 좋아하지 않지만 저는 판단하려는 입장이 아니며 IntersectionObserver
도 마찬가지입니다. options
객체는 표시 영역의 대안을 루트로 정의할 수 있는 root
옵션을 사용합니다. root
는 관찰된 모든 요소의 상위 요소여야 합니다.
모든 사물을 교차해 보세요.
아니요 형편없는 개발자네요! 사용자의 CPU 주기를 고려하는 것은 아닙니다. 예를 들어 무한 스크롤러를 생각해 보겠습니다. 이 시나리오에서는 DOM에 센티널을 추가하여 관찰 (및 재활용)하는 것이 좋습니다. 무한 스크롤러의 마지막 항목 가까이에 센티널을 추가해야 합니다. 이 센티널이 표시되면 콜백을 사용하여 데이터를 로드하고, 다음 항목을 생성하고, 이를 DOM에 연결하고, 센티널의 위치를 적절히 변경할 수 있습니다. 센티널을 적절히 재활용하면 observe()
를 추가로 호출할 필요가 없습니다. IntersectionObserver
는 계속 작동합니다.
업데이트를 더 확인하세요.
앞서 언급했듯이 콜백은 관찰된 요소가 부분적으로 시야에 들어올 때 한 번, 표시 영역을 벗어났을 때 한 번 호출됩니다. 이렇게 하면 IntersectionObserver
에서 'X 요소가 뷰에 있나요?'라는 질문에 대한 답을 얻을 수 있습니다. 그러나 일부 사용 사례에서는 이것만으로는 충분하지 않을 수 있습니다.
이때 threshold
옵션이 유용합니다. 이를 통해 intersectionRatio
기준점의 배열을 정의할 수 있습니다. intersectionRatio
가 이러한 값 중 하나를 교차할 때마다 콜백이 호출됩니다. threshold
의 기본값은 [0]
이며, 이는 기본 동작을 설명합니다. threshold
를 [0, 0.25, 0.5, 0.75, 1]
로 변경하면 요소의 4분의 1이 추가로 표시될 때마다 알림을 받게 됩니다.
다른 옵션이 있나요?
현재 위에 나열된 옵션 외에 추가 옵션이 하나밖에 없습니다. rootMargin
를 사용하면 루트의 여백을 지정하여 교차점에 사용되는 영역을 효과적으로 늘리거나 줄일 수 있습니다. 이러한 여백은 CSS 스타일 문자열인 á la "10px 20px 30px 40px"
를 사용하여 지정되며 각각 상단, 오른쪽, 하단, 왼쪽 여백을 지정합니다. 요약하자면 IntersectionObserver
옵션 구조체는 다음 옵션을 제공합니다.
new IntersectionObserver(entries => {/* … */}, {
// The root to use for intersection.
// If not provided, use the top-level document's viewport.
root: null,
// Same as margin, can be 1, 2, 3 or 4 components, possibly negative lengths.
// If an explicit root element is specified, components may be percentages of the
// root element size. If no explicit root element is specified, using a
// percentage is an error.
rootMargin: "0px",
// Threshold(s) at which to trigger callback, specified as a ratio, or list of
// ratios, of (visible area / total area) of the observed element (hence all
// entries must be in the range [0, 1]). Callback will be invoked when the
// visible ratio of the observed element crosses a threshold in the list.
threshold: [0],
});
<iframe>
매직
IntersectionObserver
는 광고 서비스와 소셜 네트워크 위젯을 염두에 두고 특별히 설계되었으며, <iframe>
요소를 자주 사용하므로 이러한 위젯이 뷰에 있는지 알면 도움이 될 수 있습니다. <iframe>
가 요소 중 하나를 관찰하면 <iframe>
를 스크롤할 때와 <iframe>
가 포함된 창을 스크롤할 때 적절한 시점에 콜백이 트리거됩니다. 후자의 경우 출처 간 데이터 유출을 방지하기 위해 rootBounds
가 null
로 설정됩니다.
IntersectionObserver
이(가) 무엇에 관한 내용이 아닌가요?
명심해야 할 점은 IntersectionObserver
는 의도적으로 픽셀이 완벽하거나 짧은 지연 시간이 아니라는 것입니다. 이들을 사용하여 스크롤 종속 애니메이션과 같은 작업을 구현하는 것은 실패할 가능성이 높습니다. 엄밀히 말하면 데이터를 사용하게 될 때쯤이면 데이터가 오래되기 때문입니다. 설명서에 IntersectionObserver
의 원래 사용 사례에 관한 자세한 내용이 포함되어 있습니다.
콜백에서 어떤 작업을 할 수 있나요?
간결함: 콜백에 너무 많은 시간을 들이면 앱이 지연됩니다. 일반적인 방법이 모두 적용됩니다.
앞으로 가서 원소와 교차하세요.
IntersectionObserver
에 대한 브라우저 지원은 모든 최신 브라우저에서 사용할 수 있으므로 양호합니다. 필요한 경우 이전 브라우저에서 polyfill을 사용할 수 있으며 WICG 저장소에서 사용할 수 있습니다. 폴리필을 사용할 경우 네이티브 구현으로 얻을 수 있는 성능상의 이점은 당연히 얻지 못합니다.
지금 IntersectionObserver
을(를) 사용할 수 있습니다. 아이디어를 알려주세요.