Intersection Observer

devAnderson·2022년 2월 21일
0

TIL

목록 보기
60/106

일반적으로 무한스크롤과 같이 lazy-loading 을 통해서 데이터를 특정 조건적으로 호출해야 할 경우가 존재한다.
scroll 이벤트로도 할 수 있겠지만, scroll을 사용하게 된다면 매 스크롤마다 이벤트가 발생하므로 성능저하에 영향을 준다.

이럴때 사용할 수 있는 API가 바로 Intersection Observer이다.

구조

IO는 new를 통해 객체를 생성하고, 이 객체의 메서드인 observer에게 인자로 요소(element)를 전달함으로서 해당 요소와 랜더링 파트간의 관계를 추적할 수 있다.

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

callback

IntersectionObserver의 첫째 인자로 들어오는 콜백은 entries, observer라는 parameter 에 해당 intersection에 필요한 정보들을 담아 제공해준다.

const io = new IntersectionObserver((entries, observer) => {}, options)
io.observe(element)
  • entries
    추적하고 있는 요소가 브라우저의 DOM 랜더링 요소에서 보여지게 되는 데이터값들을 담아둔 객체이다. 포함된 요소는 아래와 같다.
스크린샷 2022-02-21 오후 1 16 28
  • boundingClientRect : element.getClientBoundingRect() 과 동일한 결과를 보여준다. 해당 요소가 브라우저의 랜더링 파트에서의 위치값을 알려준다.
    스크린샷 2022-02-21 오후 1 15 16

  • intersectionRect = 추적하는 요소의 겹치는 장소에 대한 시각정보를 나타낸다
    스크린샷 2022-02-21 오후 1 18 06

  • intersectionRatio = 추적하는 요소가 교차하는 비율을 0~1사이로 나타낸다.

  • intersection = 추적하는 요소가 현재 교차상태인지를 나타내준다.

  • target = 관찰 요소 그 자체를 알려준다

  • time = 교차상태의 변경된 시간을 DOMHighResTimeStamp로 나타낸다 (RAF의 인자에 들어가는 것과 같은 종류다)

  • observer
    observer은 현재 콜백을 실행하는 인스턴스의 정보를 나타낸다.
const io = new IntersectionObserver((entries, observer) => {
  console.log(observer)
}, options)

io.observe(element)
스크린샷 2022-02-21 오후 1 20 27

options = InsersectionObserver의 두번째 매개변수(객체).

  • root = 추적하는 타겟의 기준점을 설정한다. 정하지 않으면 default로 null이고, viewport를 사용한다.
  • rootMargin = root의 영역을 확장할 수 있다. css margin과 형태가 동일하게 string 값이다.
  • threshold = 옵저버가 실행되기 위한 역치를 나타낸다. 타겟의 가시성을 0~1사이의 비율로 나타내며 해당 비율에 도달하는 순간 콜백이 실행된다.

method

new를 통해 IO를 초기화하면, 해당 객체가 제공하는 메서드가 몇가지 있다

  • 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 = 요소의 관찰을 중지한다.
    보통 인스턴스의 콜백 파라메터 두번째 인자인 observer가 해당 인스턴스를 칭하고 있으므로 아래와 같은 방식으로 많이 사용된다.
const io1 = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    // 관찰 대상의 교차 상태가 false일(보이지 않는) 경우 실행하지 않음.
    if (!entry.isIntersecting) {
      return
    }
    // 관찰 대상의 교차 상태가 true일(보이는) 경우 실행.
    // ...

    // 위 실행을 처리하고(1회) 관찰 중지
    observer.unobserve(entry.target)
  })
}, options)
  • disconnect = observer 객체가 관찰하고 있는 entry 요소들의 모든 관찰을 중지한다.
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) 관찰 중지

실제 용례 (무한스크롤)

현재 기업과제로 주어진 내용을 보면 무한스크롤과 관련된 내용이 몇몇 보인다.
여지껏 사용해본적이 없었지만 활용 빈도가 높아보이므로 미리 익혀둘 필요가 있다고 생각했다.

논리는 이렇다
스크린샷 2022-02-21 오후 1 41 40

가장 가볍게 생각했을 때, 어떤 특정 요소가 감지가 되면 (threshold 옵션에 따라) 콜백 함수가 실행되게 만들면 된다.

일반적으로 마지막 요소가 보이면 서버로부터 데이터를 호출하게 하면 될 것이고, 그 전까지 (즉, 데이터를 받아오지 않아 배열의 마지막 부분에 왔을 경우) 로딩 부분을 보여주고 있다가, 데이터가 패칭이 완료되면 해당 로딩 요소를 제거하고 그 자리를 추가되는 데이터들로 채워넣으면 될 것이다.

해당 사용 용례 reference

오늘 오후에 추가로 실제 구현해보며 따라하도록 하자

profile
자라나라 프론트엔드 개발새싹!

0개의 댓글