IntersectionObserver

김병엽·2024년 8월 1일

What is the intersectionObserver

  • 타겟 요소와 상위 요소 또는 최상위 document 의 viewport 사이의 intersection 내의 변화를 비동기적으로 관찰하는 방법.
const io = new IntersectionObserver(callback, options) // 관찰자 초기화
io.observe(element) // 관찰할 대상(요소) 등록

callback

  • 관찰할 대상(Target)이 등록되거나 가시성(Visibility, 보이는지 보이지 않는지)에 변화가 생기면 관찰자는 콜백(Callback)을 실행.
const options = {}
const io = new IntersectionObserver((entries, observer) => {}, options)
io.observe(element)

entries

  • IntersectionObserverEntry 인스턴스의 배열로, .observe() 메소드로 관찰하는 대상들을 의미.
  • IntersectionObserverEntry는 읽기 전용(Read only)의 다음 속성들을 포함한다.

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

const io = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    console.log(entry) // entry is 'IntersectionObserverEntry'
  })
}, options)

io.observe(element1) // 관찰 대상 1
io.observe(element2) // 관찰 대상 2
...

entry.boundingClientRect

  • 관찰 대상의 사각형 정보(DOMRectReadOnly)를 반환.

entry.intersectionRect

  • 관찰 대상과 루트 요소와의 교차하는(겹치는) 영역에 대한 사각형 정보(DOMRectReadOnly)를 반환.

entry.intersectionRatio

  • 관찰 대상이 루트 요소와 얼마나 교차하는(겹치는)지의 수치를 0.0과 1.0 사이의 숫자로 반환.

entry.isIntersecting

  • 관찰 대상이 루트 요소와 교차 상태로 들어가거나(true) 교차 상태에서 나가는지(false) 여부를 나타내는 값(Boolean)

entry.rootBounds

  • 루트 요소에 대한 사각형 정보(DOMRectReadOnly)를 반환.
  • 이는 옵션 rootMargin에 의해 값이 변경되며, 만약 별도의 루트 요소(옵션 root)를 선언하지 않았을 경우 null을 반환.

entry.target

  • 관찰 대상(Element)을 반환.

entry.time

  • 문서가 작성된 시간을 기준으로 교차 상태 변경이 발생한 시간을 나타내는 DOMHighResTimeStamp를 반환.

observer

  • 콜백이 실행되는 해당 인스턴스를 참조.
const io = new IntersectionObserver((entries, observer) => {
  console.log(observer)
}, options)

io.observe(element)


option

  • 관찰 범위를 설정하기 위한 몇 가지 옵션을 사용할 수 있음.

root

  • 관찰 대상의 가시성을 검사하기 위해 뷰포트 대신 사용할 요소 객체(루트 요소)를 지정.
  • 관찰 대상의 조상 요소이어야 하며 지정하지 않거나 null일 경우 브라우저의 뷰포트가 기본 사용됨.
  • 기본값은 null.
const io = new IntersectionObserver(callback, {
  root: document.getElementById('my-viewport')
})

rootMargin

  • 바깥 여백(Margin)을 이용해 Root 범위를 확장하거나 축소 가능.
  • CSS의 margin과 같이 4단계로 여백을 설정할 수 있으며, px 또는 %로 나타낼 수 있음.
  • 기본값은 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]`
})


method

observe

  • 대상 요소의 관찰을 시작.
const io1 = new IntersectionObserver(callback, options)
const io2 = new IntersectionObserver(callback, options)

const div = document.querySelector('div')
const li = document.querySelector('li')
const h2 = document.querySelector('h2')

io1.observe(div) // DIV 요소 관찰
io2.observe(li) // LI 요소 관찰
io2.observe(h2) // h2 요소 관찰

unobserve

  • 대상 요소의 관찰을 중지.
  • 관찰을 중지할 하나의 대상 요소를 인수로 지정해야 함.
  • IntersectionObserver 인스턴스가 관찰하고 있지 않은 대상 요소가 인수로 지정된 경우 아무런 동작도 하지 않음.
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 요소 관찰 중지

콜백의 두 번째 인수 observer가 해당 인스턴스를 참조하므로, 다음과 같이 작성할 수도 있다.

const io1 = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    // 가시성의 변화가 있으면 관찰 대상 전체에 대한 콜백이 실행되므로,
    // 관찰 대상의 교차 상태가 false일(보이지 않는) 경우 실행하지 않음.
    if (!entry.isIntersecting) {
      return
    }
    // 관찰 대상의 교차 상태가 true일(보이는) 경우 실행.
    // ...

    // 위 실행을 처리하고(1회) 관찰 중지
    observer.unobserve(entry.target)
  })
}, options)

disconnect

  • IntersectionObserver 인스턴스가 관찰하는 모든 요소의 관찰을 중지.
const io1 = new IntersectionObserver(callback, options)
const io2 = new IntersectionObserver(callback, options)

// ...

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

io2.disconnect() // io2가 관찰하는 모든 요소(LI, H2) 관찰 중지

Reference

https://www.heropy.dev/p/ydKoQO

profile
선한 영향력을 줄 수 있는 개발자가 되자, 되고싶다.

0개의 댓글