
Intersection Observer란 뷰포트의 영역과 타겟 요소 영역의 중첩을 감지(Detect)하는 웹 API 기술이다.
쉽게 말해 사용자의 화면에 특정 요소가 보이는지의 여부와, 영역이 겹친 정도 등을 알려주는 비동기적 센서라고 할 수 있다.

Intersection Observer API의 강점은 지속적인 스크롤 이벤트 감지 없이도 효율적으로 리소스를 관리하면서 정확히 감지 기능을 수행한다는 점이다.
연속적인 스크롤 이벤트 감지가 무작위로 쏘아대다 맞으면 알려주는 기관총이라면 Intersection Observer는 정확히 타격점을 조준, 격발하는 스나이핑 라이플과 같다고 할 수 있다. 🎯
window.addEventListener('scroll', () => {
if (this.pageYOffset > 1000) { ... }
else if (this.pageYOffset > 2000) { ... }
...
});
비효율적인 스크롤 이벤트 감지 멈춰! ✋🏻
const observer = new IntersectionObserver(callback[, options]);
먼저 new 키워드로 새로운 IntersectionObserver 객체를 생성하는 것으로 관찰자(Observer)를 셋업한다.
생성자는 뷰포트(또는 지정된 root)에 감지되었을때 실행될 콜백과 옵션을 인자로 받는다.
const observer = new IntersectionObserver((entries, observer) => {
// ...do something...
}, options);
관찰자의 타겟이 감지되었을때 실행될 콜백에게 기본적으로 entries와 observer 두 개의 인자가 전달된다. (addEventListener의 콜백이 event 객체를 인자로 받는 것과 같다.)
const sections = document.querySelectorAll('section');
const io = new IntersectionObserver((entries, observer) => {
const [entry] = entries;
console.log(entry);
})
io.observe(sections[2]);
여러개의 section이 슬라이드로 구성된 페이지에서 [2]번째 섹션의 entry 정보를 콘솔에 출력해보면 아래와 같이 IntersectionObserverEntry 객체를 배열에 담아 반환한다.
아래 프로퍼티는 모두 읽기 전용이기 때문에 새로운 값(Set)을 넣어 변화를 줄 순 없다.

IntersectionObserverEntry의 속성들 ✅
boundingClientRect: 관찰 대상의 Rect 정보 Read onlyintersectionRatio: 관찰 대상이 중첩된 비율 반환 (안겹치면 0, 완전히 겹치면 1) Read onlyintersectionRect: 관찰 대상이 중첩된 영역 정보 Read onlyisIntersecting: 관찰 대상의 중첩 여부 (true or false) Read only ✅rootBounds: 지정한 루트(뷰포트의 역할을 수행)의 Rect 정보 Read onlytarget: 관찰 대상 요소 (DOM Element) Read onlytime: 관찰 대상이 노출된 시간 정보 (Time Stamp) Read only
intersectionRatio의 값이0이상일 경우root영역에 대상이 겹쳤음을 의미하고, 이는isIntersecting값이true인 경우와 같다고 볼 수 있다.
즉isIntersecting: true가 핵심 열쇠다. 🔑
root, rootMargin, threshold 등 관찰자 객체의 특성을 담은 객체.

let options = {
root: document.querySelector(`#targetArea`),
rootMargin: `0px`,
threshold: 1.0
}
let observer = new IntersectionObserver(callback, options);
// or
let observer = new IntersectionObserver(callback, {
root: document.querySelector(`#targetArea`),
rootMargin: `0px`,
threshold: 0
});
root : 기본값은 null이며 뷰포트 대신 사용할 요소를 지정할 수 있다.
rootMargin: root의 범위를 확장 또는 축소할 수 있다. 단위는 px 또는 %이며 CSS의 margin속성 표기 방법과 똑같다. (e.g. top right bottom left)
threshold: root와 관찰되는 요소가 얼마나 중첩되어야 콜백을 실행할지 결정할 수 있다. 0과 1 사이의 값으로 표현하며 배열을 넣어 중첩되는 단계별로 옵저버를 실행할 수도 있다.
- 0: 타겟의 가장자리가 root 영역에 포착되는 순간 콜백 실행
- 1: 타겟의 모든 영역이 root 영역에 들어오면 콜백 실행
- [0, ... , 1]: 타겟과 root이 중첩되는 단계별로 순차적 콜백 실행
observe()대상 요소의 관찰을 시작 👀
const io = new IntersectionObserver(callbackFn, options);
const section = document.querySelector('#section1');
io.observe(section);
unobserve()대상 요소의 관찰 중지 🛑
const io = new IntersectionObserver(callbackFn, options);
io.unobserve(section);
disconnect()관찰자(IntersectionObserver 객체)의 모든 관찰을 중단 🚫
const io = new IntersectionObserver(callbackFn, options);
io.disconnect();
파란색 공이 뷰포트에 완전히 반쯤 들어오면 공 속의 숨은 메세지를 볼 수 있는 예제를 만들었다.
Observer가 파란색 공이 뷰포트 영역 threshold 비율만큼 겹치면 isIntersecting 값을 true로 반환하며 콜백이 실행된다.
// box 클래스를 가진 DOM 요소들의 NodeList를 반환
const boxes = document.querySelectorAll('.box');
// 영역 감지되면 실행될 콜백
const animateBox = function(entries, observer) {
// Destructuring
const [{isIntersecting, target}] = entries;
// 만약 영역 감지가 true라면 class 추가, 아니면 제거
if (isIntersecting) {
target.classList.add('visible');
} else {
target.classList.remove('visible');
}
};
// intersection observer 생성자 초기화 (관찰자)
const io = new IntersectionObserver(animateBox, {
root: null,
threshold: 0.5,
})
// NodeList의 각 요소들 감시 시작
boxes.forEach(e => {
io.observe(e);
})
IE에선 전혀 지원하지 않지만 모듈을 가져옴으로써 폴리필(Polyfill)로 사용할 수 있다고 한다.
완벽하게 이해하면 다시 포스팅 할 예정

코드펜의 뷰포트 문제인지, 호환성 문제인지 잘 모르겠지만.. 해결되면 다시 업로드 예정
반면 데스크탑 브라우저에선 잘 작동된다. 🤔

// 변경 전
const io = new IntersectionObserver(animateBox, {
root: null,
threshold: 1,
})
// 변경 후
const io = new IntersectionObserver(animateBox, {
root: null,
threshold: 0.5,
})

모바일 브라우저에 표시된 코드펜의 뷰포트가 상대적으로 작아서 생긴 문제였다.
threshold를 0.5로 낮춰 요소 영역이 반만 뷰포트와 겹쳐도 isIntersecting = true 판정이 나도록 바꿨더니 잘 작동된다.
이제 잘 수 있을 것 같다. 💤
고마워요 Stack Overflow
References:
MDN: IntersectionObserver
HEROPY Tech: Intersection Observer - 요소의 가시성 관찰