티스토리 뷰

 

Intersection Observer란?

Intersection Observer란 브라우저 뷰포트(Viewport)와 선택된 요소(Element)의 교차점을 관찰하는 API이다. 쉽게 말하면 선택된 요소가 사용자 화면에 현재 보이는지 보이지 않는지를 구별하는 기능을 제공한다.

 

Intersection Observer의 생성과 구조

new IntersectionObserver()를 통해 인스턴스(io)를 생성, 관찰자(Observer)를 초기화, 관찰할 대상(Element)을 지정하여 사용할 수 있다. 생성자는 2개의 인수(callback, options)를 가진다.

const io = new IntersectionObserver(callback, options) // 관찰자 초기화
io.observe(element)	// 관찰할 대상(요소) 등록

 

callback


관찰할 대상이 등록되거나 가시성에 변화가 발생하면 관찰자는 콜백을 실행하며 콜백은 2개의 인수(entries, observer)를 가지고 있다.

 

entries, observer


entries는 IntersectionObserverEntry 인스턴스의 배열이며 IntersectionObserverEntry는 읽기 전용(Read only)의 다음 속성들을 포함하고 있다. 

  • boundingClientRect: 관찰 대상의 사각형 정보(DOMRectReadOnly)
  • intersectionRect: 관찰 대상의 교차한 영역 정보(DOMRectReadOnly)
  • intersectionRatio: 관찰 대상의 교차한 영역 백분율(intersectionRect 영역에서 boundingClientRect 영역까지 비율, Number)
  • isIntersecting: 관찰 대상의 교차 상태(Boolean)
  • rootBounds: 지정한 루트 요소의 사각형 정보(DOMRectReadOnly)
  • target: 관찰 대상 요소(Element)
  • time: 변경이 발생한 시간 정보(DOMHighResTimeStamp)

 

observer는 콜백이 실행되는 해당 인스턴스를 참조한다.

const io = new IntersectionObserver((entries, observer) => {
  console.log(observer)
}, options)

io.observe(element)

 

options


root, rootMargin, threshold


root는 타겟의 가시성을 검사하기 위해 뷰포트 대신 사용할 요소 객체(루트 요소)를 지정한다. 타겟의 조상 요소여야 하며 지정하지 않거나 null의 경우 브라우저의 뷰포트가 기본적으로 사용된다.

const io = new IntersectionObserver(callback, {
  root: document.getElementById('my-viewport')
})

 

rootMargin은 바깥 여백(margin)을 이용해 root범위를 확장 또는 축소할 수 있다. 

기본값은 0px 0px 0px 0px이며 단위를 꼭 입력하여야 한다.

const io = new IntersectionObserver(callback, {
  rootMargin: '200px 0px'
})

 

threshold는 옵저버가 실행되기 위해 타겟의 가시성이 얼마나 필요한지 백분율로 표시하는 것으로 기본값은 Array타입의 [0]이지만 Number 타입의 단일 값으로도 작성할 수 있다.

  • 0: 타겟의 가장자리 픽셀이 Root 범위를 교차하는 순간(타겟의 가시성이 0%일 때) 옵저버가 실행
  • 0.3: 타겟의 가시성 30%일 때 옵저버가 실행
  • [0, 0.3, 1]: 타겟의 가시성이 0%, 30%, 100%일 때 모두 옵저버가 실행
const io = new IntersectionObserver(callback, {
  threshold: 0.3 // or `threshold: [0.3]`
})

 

 

Methods


observe(), unobserve()


observe()는 대상 요소의 관찰을 시작하는 메소드이다. 

const io = new IntersectionObserver(callback, options)

const div = document.querySelector('div')

io.observe(div) // DIV 요소 관찰

 

unobserve()는 대상 요소의 관찰을 중지하는 메소드이다.

관찰을 중지할 하나의 대상 요소를 인수로 지정해야 하며 해당 인스턴스가 관찰하고 있지 않은 대상 요소가 인수로 지정된 경우 아무 동작도 하지 않는다.

const io1 = new IntersectionObserver(callback, options)
const io2 = new IntersectionObserver(callback, options)

// ...

io1.observe(div)
io2.observe(li)
io2.observe(h2)

io1.unobserve(h2) // nothing..
io2.unobserve(h2) // H2 요소 관찰 중지

 

 

 

Intersection Observer 적용

 

나는 Intersection Observer를 무한 스크롤 기능을 구현하는데 사용하였다.

 

관찰 등록과 관찰 중지


처음 API통신을 해서 가져온 데이터를 원하는 만큼만 지정하여 Intersection Observer를 사용하여 관찰 요소로 등록하였다.

callback에서 이미 보여진 이미지들은 unobserve()를 통해 관찰 중지시켰다.

const options = {threshold: 0};
// 관찰 대상이 등록되거나 가시성에 변화가 생길 경우 callback을 실행
const callback = (entreis, observer) => {
    entreis.forEach((entry) => {
        if(entry.isIntersecting) {  // 관찰 대상이 보일 경우
            observer.unobserve(entry.target);   // 관찰 대상을 관찰 중지함
            entry.target.src = entry.target.dataset.src;    // entry의 data-src를 img 태그 src에 저장                     
        }
    })
};
const io = new IntersectionObserver(callback, options);
// lazy 클래스를 가지고 있는 element를 모두 가져옴
const lazyImages = Array.from(document.getElementsByClassName("lazy"));
console.log("lazyImages: ", lazyImages);        
lazyImages.forEach((image) => {
    io.observe(image); // 각각의 element를 관찰
})

 

관찰 대상 업데이트


무한스크롤 기능의 경우 스크롤이 화면 하단에 닿은 경우 다음 데이터셋이 기존 데이터셋에 이어져서 사용자에게 보여져야 한다.

이 경우 Intersection Observer 인스턴스에 새로운 데이터셋을 관찰 등록해 주어야 한다.

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함