Intersection Observer는 간단하게 말하면 관측 대상 요소가 관측된 경우에 웹페이지가 특정 행동을 하도록 만드는 것이다.
그때문에 사용자가 보는 화면 뷰포트가 가장 중요한 개념이다.
그중에서 무한 스크롤은 유튜브 같이 다양한 컨텐츠가 거의 무한이 있는 경우에 유용하게 사용되고 있다.
그 중 관측 대상 요소가 언제, 어떻게 '관측'됐다고 간주될지를 정밀하게 제어하는 데 사용되는 옵션이 있다.
바로 rootmargin과 threshold이다.
IntersectionObserver를 생성할 때는 두 번째 인자로 options 객체를 전달할 수 있다.
이 객체에는 root, rootMargin, threshold 세 가지 속성이 포함될 수 있다.
const options = {
root: document.querySelector('#scrollArea'), // 관찰 기준 영역 (기본값: null = 뷰포트)
rootMargin: '0px 0px -50px 0px', // root 영역의 마진
threshold: 0.5 // 교차 비율 임계값
};
const observer = new IntersectionObserver(callback, options);
(root는 교차 검사의 기준이 되는 뷰포트 역할을 하는 조상 요소를 지정하며, null이면 브라우저의 기본 뷰포트이다.)
📌 rootMargin (루트 마진)
rootMargin은 CSS의 margin 속성과 유사하게, root 요소의 경계를 기준으로 가상의 여백을 설정하여 교차 영역을 확장하거나 축소하는 역할을 한다. 이 값은 문자열 형태로 지정한다.
간단히 말하자면 rootMargin은 뷰포트의 감지 영역를 확장하거나 축소하여, 요소가 언제 '보인다'고 판단할지를 조절하는 옵션이다.
- 개념: root 요소의 실제 경계(Bounding Box)에 지정된 margin 값을 적용하여, 실제 교차 여부를 판정하는 영역을 조절한다.
- 문법: CSS margin과 동일한 형식의 문자열 ('top right bottom left'). 픽셀(px) 또는 퍼센트(%) 단위를 사용한다.
- '0px' (모든 방향 0)
- '-10px 0px -50px 0px' (상 -10px, 하 -50px, 좌우 0px)
- 효과:
- 양수 값: root 영역의 경계를 바깥쪽으로 확장한다. 예를 들어 bottom 마진을 양수로 주면, 실제 뷰포트 하단보다 더 아래 영역까지 교차 영역으로 간주한다.
- 음수 값: root 영역의 경계를 안쪽으로 축소한다. 예를 들어 bottom 마진을 음수로 주면, 실제 뷰포트 하단 경계보다 더 위쪽에서 교차 영역이 끝나게 된다.
- 주요 사용 목적:
- 미리 로딩 (Pre-loading) / 이른 트리거: bottom 마진을 양수로 설정하여, 요소가 실제 뷰포트에 보이기 전에 미리 isIntersecting 상태를 true로 만들 수 있다. 무한 스크롤에서 다음 콘텐츠를 미리 로딩하는 데 매우 유용하다. (예: '0px 0px 300px 0px')
- 늦은 트리거 / 완전히 보일 때: 모든 방향에 음수 마진을 적용하여, 요소가 뷰포트 안쪽으로 완전히 들어왔을 때만 isIntersecting 상태를 true로 만들 수 있다.
- 수평 스크롤: 좌우 마진을 조절하여 수평 스크롤 시의 교차 영역을 조절할 수 있다.
✨ (Negative rootMargin 효과)
rootMargin에 음수 값을 사용하면, 교차를 감지하는 영역이 실제 root 요소(보통 뷰포트)의 경계보다 안쪽으로 축소된다.
⚙️ 작동 원리: 교차 영역 축소
- 음수 top 마진 (예: '-50px 0px 0px 0px'): 실제 뷰포트 상단 경계보다 50px 아래에서부터 교차 영역이 시작된다. 즉, 요소가 뷰포트 상단에 50px 미만으로 걸쳐있을 때는 교차하는 것으로 간주하지 않는다.
- 음수 bottom 마진 (예: '0px 0px -100px 0px'): 실제 뷰포트 하단 경계보다 100px 위쪽에서 교차 영역이 끝난다. 요소가 뷰포트 하단에서 100px 이내로 들어와야만 교차 영역에 진입할 수 있다.
- 음수 left/right 마진: 좌우 경계 안쪽으로 교차 영역이 축소된다.
따라서 rootMargin에 음수 값을 적용하면, 관찰 대상 요소가 화면(뷰포트)에 보이기 시작했더라도 즉시 isIntersecting 상태가 true가 되는 것이 아니라, 축소된 교차 영역 안으로 충분히 더 들어와야만 true가 되고 콜백 함수가 트리거될 수 있다. 즉, 사용자가 말한 대로 "특정 지점까지 도달해야만 작동하게" 만들 수 있다.
🎯 주요 사용 목적
음수 rootMargin은 다음과 같은 경우에 유용하게 사용될 수 있다.
- 요소가 완전히 또는 충분히 보일 때만 감지: 요소가 뷰포트 가장자리에 살짝 걸치는 것이 아니라, 뷰포트 안쪽으로 확실히 들어왔을 때 특정 동작(예: 애니메이션 시작, 분석 이벤트 전송)을 트리거하고 싶을 때 사용한다. 예를 들어, 광고가 화면 중앙 부근에 위치했을 때만 노출로 집계하는 경우.
- 가장자리 '데드존(Dead Zone)' 생성: 뷰포트의 가장자리 근처에서는 교차 이벤트를 무시하고 싶을 때 사용할 수 있다.
- 정밀한 트리거 시점 제어: 스크롤 위치에 따라 매우 구체적인 지점에서만 인터랙션을 발생시켜야 할 때 활용될 수 있다.
threshold 값과 조합하여 (예: 음수 rootMargin과 threshold: 1.0을 함께 사용), "요소가 뷰포트 안쪽의 특정 영역에 100% 완전히 보일 때" 와 같은 조건을 만들 수도 있다.
📌 threshold (임계값)
threshold(임계값)는 관찰 대상 요소가 root 요소(및 rootMargin으로 조절된 영역)와 얼마나 교차했을 때(얼마나 보였을 때) 콜백 함수를 실행할지를 지정하는 값이다.
- 개념: 타겟 요소의 **가시성 비율(Visibility Ratio)**이 지정된 threshold 값을 넘나들 때마다 콜백 함수가 호출된다.
- 값: 0.0에서 1.0 사이의 숫자 또는 이런 숫자들의 배열로 지정한다.
- 0: 타겟 요소의 단 1픽셀이라도 교차 영역에 들어오거나 나갈 때 콜백 실행.
- 1: 타겟 요소가 100% 완전히 교차 영역 안에 들어오거나 나갈 때 콜백 실행.
- 0.5: 타겟 요소가 50% 이상 교차 영역 안에 보이게 되거나 50% 미만으로 보이게 될 때 콜백 실행.
- 배열 [0, 0.25, 0.5, 0.75, 1]: 타겟 요소의 가시성 비율이 0%, 25%, 50%, 75%, 100% 경계를 넘나들 때마다 콜백이 실행된다. 예를 들어, 0% -> 30%로 변하면 0과 0.25를 교차했으므로 콜백이 두 번 호출될 수 있다. (실제 호출 횟수는 브라우저 최적화에 따라 다를 수 있음)
- 기본값: 0 (1픽셀이라도 보이면 콜백 실행)
- 주요 사용 목적:
- 무한 스크롤 / 지연 로딩: 0 또는 매우 작은 값(0.01, 0.1)을 사용하여 요소가 뷰포트에 진입하는 초기 시점을 감지한다. (rootMargin과 함께 자주 사용됨)
- 광고 노출 측정 / 분석: 0.5 (50% 이상 노출) 또는 1 (100% 노출)을 사용하여 요소가 사용자에게 의미 있는 수준으로 노출되었는지 판단한다. 배열을 사용하여 노출 정도의 변화를 추적할 수도 있다.
- 애니메이션 트리거: 특정 비율만큼 요소가 보였을 때 애니메이션을 시작하는 등의 상호작용 구현.
⚙️ rootMargin과 threshold의 관계
두 옵션은 함께 작동하여 교차 판정 방식을 결정한다.
- rootMargin이 먼저 적용되어 "어디서" 교차를 확인할지 **영역(Area)**을 정의한다.
- 그 다음, 정의된 영역 내에서 타겟 요소의 가시성 비율이 threshold 값을 **넘나드는 "시점(Timing)"**에 콜백 함수가 호출된다.
예를 들어, rootMargin: '0px 0px 300px 0px' 이고 threshold: 0.5 라면, 옵저버는 "뷰포트 하단 300px 아래까지 확장된 영역 안에서, 타겟 요소가 50% 이상 보이게 되거나 50% 미만이 되는 순간"에 콜백 함수를 실행한다.
💡 요약
- rootMargin: 교차 판정 영역을 뷰포트(또는 root 요소) 기준으로 확장하거나 축소한다. (단위: px 또는 %, CSS margin과 유사)
- threshold: 지정된 영역 내에서 타겟 요소가 얼마나 보여야 콜백을 실행할지 **비율(Ratio)**을 지정한다. (값: 0.0 ~ 1.0 사이 숫자 또는 숫자 배열)
이 두 옵션을 조합하여 무한 스크롤, 지연 로딩, 가시성 기반 분석 등 다양한 기능을 정밀하게 구현할 수 있다.
'자바 스크립트(java script) > 개념 조각' 카테고리의 다른 글
자바스크립트의 예약어(Reserved Word) (0) | 2025.04.05 |
---|---|
크기가 0인 요소도 IntersectionObserver의 대상이 될 수 있나? (0) | 2025.03.31 |
✨ this 참조 대상 (0) | 2025.03.29 |
✨ 화살표 함수와 일반 함수의 변환 (0) | 2025.03.29 |
자바스크립트 프로토타입(Prototype) (0) | 2025.03.26 |