코드노트

Intersection Observer API 사용방법 본문

Code note/자바스크립트

Intersection Observer API 사용방법

코드노트 2023. 1. 9. 16:57

영화검색 사이트를 만들면서 무한스크롤을 구현하는데  Intersection Observer API를 사용했다.

일반적으로는 addEventListener를 사용해서 구현하지만 문제점이 꽤 많았다.

- 스크롤을 할때마다 이벤트가 발생하는 문제점

- 스크롤 이벤트가 무거워질수록 위험하다는 점

등등 여러 문제점들이 있기에 다른방법을 찾다가  Intersection Observer API를 알게 되었다!

 

 

Movie Search

 

strong-rolypoly-f45a54.netlify.app

위 사이트에서 구현해보았는데 사용법도 어렵지 않고 활용도가 많을 것 같다.

이번에 사용하면서 막히던 부분들이 있었기 때문에

Intersection Observer API에 대해서 정리해보려고 한다.

 

See the Pen Untitled by beomjunkwon (@bjkwon) on CodePen.


Intersection Observer API

- 페이지가 스크롤 될 때 이미지 또는 기타 콘텐츠가 지연 로드된다.

- 사용자가 페이지를 넘길 필요가 없도록 스크롤 할 때 더 많은 콘텐츠가 로드되고 렌더링되는 무한 스크롤을 구현한다.

- 사용자가 결과를 볼 수 있는지 여부에 따라 작업 또는 애니메이션 프로세스를 수행할지 여부를 결정

 

▶ 지정한 두 요소의 교차 부분만큼 변경이 되기 시작하면 콜백이 실행

* 즉 두 요소의 상태를 감지하여 콜백 함수를 실행

 

const divEl = document.querySelector("div");
const option = {
    root: null,
    rootMargin: "0px 0px 0px 0px",
    thredhold: 0,
}

const onIntersect = (entries, observer) => { 
    // entries는 IntersectionObserverEntry 객체의 리스트로 배열 형식을 반환합니다.
    entries.forEach(entry => {
        if(entry.isIntersecting){
            const item = document.querySelector("ul");
            item.insertAdjacentHTML("beforeend", `
               추가할 요소
            `)
        }
    });
};

const observer = new IntersectionObserver(callback, option);
observer.observe(divEl);

new IntersectionObserver() 를 통해서 생성한 인스턴스를 관찰자로 초기화하고 관찰할 대상을 지정

2개의 인수를 가진다( callback, options )

 

* 위 코드에서는 관찰하는 대상을 지정하고 callback을 사용하지 않아도 되기 때문에 사용하지 않음.


callback

- 콜백 함수는 요소가 한 방향 혹은 다른 방향으로 교차할 때 실행

 

option

root

- 타겟과 어떤 요소를 교차할지 결정

- 기본값은 null(브라우저 뷰포트), 엘리먼트로 설정하면 해당 엘리먼트와 타겟을 감시

 

rootMargin

- root의 범위를 지정

- css marigin과 유사 "0px 0px 0px 0px"

- 기본값은 0

 

thredhold

- 타겟이 얼마만큼 보였을 때 콜백함수를 실행할지 지정

- 0~1의 숫자로 지정

ex ) 25%마다 실행하고 싶으면? [0, 0.25, 0.5, 0.75, 1] 배열로 설정 가능

 

const elEl = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    console.log(entry) // IntersectionObserverEntry 객체를 배열로 반환
  })
}, options)

elEl.observe(element)

entries

* IntersectionObserverEntry 인스턴스의 배열

- 속성 정리

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


IntersectionObserver 메서드

 

observe()

const el = new IntersectionObserver(callback, options)

const elEl = document.querySelector("div")
const elEl2 = document.querySelector("div")

el.observe(elEl)
el.observe(elEl2)

- 타겟을 관찰 할 때

- 하나의 인스턴스로 여러개 감시 가능

 


unobserve()

const el = new IntersectionObserver(callback, options)

const elEl = document.querySelector("div")
const elEl2 = document.querySelector("div")

el.unobserve(elEl)
el.unobserve(elEl2)


------------------------------------------------------

const elEl = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
   
   if(!entry.isIntersecting) { // 가시성의 변화가 있으면 관찰 대상 전체에 대한 콜백이 실행, 관찰 대상의 교차 상태가 false(보이지 않으)면 실행하지 않음
     return 
   }
   // true(보이면)면 실행
   
   // 위 실행을 1회 처리하고 관찰 중지
   observer, undbserve(entry.target)
  })
}, options)

- 관찰을 멈추고 싶을 때

- 인스턴스가 관찰하고 있지 않은 대상의 요소가 인수로 지정되면 아무런 동작을 하지 않음.

 

disconnect()

const el = new IntersectionObserver(callback, options)

const elEl = document.querySelector("div")
const elEl2 = document.querySelector("div")

el.observe(elEl)
el.observe(elEl2)

el.disconnect()

- 관찰하고 있는 다수의 타겟을 모두 멈추고 싶을 때 사용

- 관찰 대상의 인스턴스에 메서드를 사용 ( 관찰하고 있는 모든 요소 중지 )

 

 

ex)