본문 바로가기
Javascript

Intersection Observer API를 통한 스크롤 이벤트 구현

by 타로 스토리 2023. 7. 4.
반응형

Intersection Observer API는 웹 페이지의 특정 요소가 뷰포트나 다른 요소와 교차하는지 관찰하는 데 사용됩니다. 예를 들어, 사용자가 웹 페이지를 스크롤 할 때 특정 요소가 화면에 보이는지 확인하는데 사용할 수 있습니다. 이는 Infinite Scroll(무한 스크롤), Lazy Loading(지연된 이미지 로딩), Animation Triggering(애니메이션 트리거링) 등에 유용하게 사용됩니다.

 

타겟 요소와 상위 요소 또는 최상위 document의 viewport 사이의 intersection 내의 변화를 비동기적으로 관찰하여 이벤트를 실행시키는 방법입니다.

기존의 scroll 이벤트나 wheel 이벤트를 통해 Intersection을 구현했지만 반복되는 이벤트 호출등으로 성능상의 문제가 발생되는 경우가 많아 throttle이나 debounce등의 추가 기능을 통해 문제를 해결해야만 했습니다. 

 

Intersection Observer API 는 감시하고자 하는 대상 요소가 viewport에서 보여지거나 사라질때 또는 요청한 부분만큼 두 요소의 교차부분이 생길 때 마다 실행될 콜백 함수를 등록합니다. 즉, 사이트는 요소의 교차를 지켜보기 위해 메인 스레드를 사용할 필요가 없어지고 브라우저는 원하는 대로 교차 영역 관리를 최적화가 가능합니다.

교차영역을 구분하는 방법은 %의 형태로 이뤄지며 몇픽셀 단위의 교차검증은 할 수 없습니다.

 

Intersection Observer 생성하기

Intersection Observer를 사용하려면 먼저 IntersectionObserver 객체를 생성해야 합니다. 이 객체를 생성할 때 콜백 함수와 옵션 객체를 인자로 전달할 수 있습니다.

 

let observer = new IntersectionObserver(callback, options);

 

콜백 함수

콜백 함수는 감시 대상의 교차 상태가 변경될 때 호출됩니다. 이 콜백은 IntersectionObserverEntry 객체의 배열과 observer 객체 자체를 인수로 받습니다.

function callback(entries, observer) {
  entries.forEach(entry => {
    // 교차 상태 처리
  });
}

 

옵션

options 객체는 다음과 같은 프로퍼티를 가질 수 있습니다.

  • root: 대상 요소와 교차할 기준이 되는 요소입니다. null로 설정하면 브라우저의 뷰포트를 기준으로 합니다.
  • rootMargin: root 요소의 여백을 설정합니다. 여백은 "top right bottom left" 형식의 문자열로 지정됩니다. 기본값은 0입니다.
  • threshold: 교차 상태를 알리는 데 사용되는 요소의 교차 비율을 설정합니다. 0과 1 사이의 숫자로 설정할 수 있으며, 배열로 여러 임계값을 설정할 수도 있습니다.

 

감시 시작과 중지

감시할 요소를 지정하려면 observe() 메서드를 사용합니다.

observer.observe(targetElement);

 

감시를 중지하려면 unobserve 메서드를 사용합니다.

observer.unobserve(targetElement);

 

isIntersecting 활용

let observer = new IntersectionObserver(
  (entries, observer) => {
    entries.forEach((entry) => {
      let lazyImage = entry.target;
      if (entry.isIntersecting) {
        lazyImage.src = lazyImage.dataset.src;
        lazyImage.classList.add("visible");
      } else {
        lazyImage.classList.remove("visible");
      }
    });
  },
  {
    root: null,
    rootMargin: "0px",
    threshold: 0.5
  }
);

document.querySelectorAll("img[data-src]").forEach((img) => {
  observer.observe(img);
});

콜백함수에서 대상 타겟이 화면에 들어올때 클래스를 추가하고 사라질때 삭제합니다. 옵션의 속성으로 50%이상 타겟이 화면에 나타나면 클래스를 추가하고 그 이하 값이 되면 클래스를 삭제하도록 옵션을 설정합니다.

isIntersecting은 Boolean 값을 갖으며 타겟이 화면에 나타날때 True를 반환합니다.

 

See the Pen IOAPI LAZYLOAD by SM (@SM-the-decoder) on CodePen.

 

 

 

 

intersectionRatio를 활용

<div id="target-element">내용</div>

 

.active {
  background-color: yellow;
}

 

const targetElement = document.getElementById('target-element');

const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
        if (entry.intersectionRatio >= 0.25) {
            entry.target.classList.add('active');
        } else {
            entry.target.classList.remove('active');
        }
    });
}, {
    threshold: 0.25
});

observer.observe(targetElement);

위의 코드에서 IntersectionObserver를 생성할 때 threshold를 0.25로 설정했습니다. 이는 요소의 25%가 교차될 때 콜백 함수를 호출하도록 지시합니다. 콜백 함수 내에서 intersectionRatio가 0.25 이상인 경우 대상 요소에 'active' 클래스를 추가하고, 그렇지 않으면 제거합니다.

 

intersectionRatio는 IntersectionObserver API에서 사용되는 속성으로, 타겟 요소와 상위 요소 또는 뷰포트 사이의 교차 영역의 비율을 나타냅니다. 즉, 타겟 요소의 노출 비율을 0과 1 사이의 값으로 표현합니다.

  • intersectionRatio가 0이면, 타겟 요소가 전혀 보이지 않는 것을 의미합니다.
  • intersectionRatio가 1이면, 타겟 요소가 완전히 보이는 것을 의미합니다.
  • intersectionRatio가 0과 1 사이의 값이면, 타겟 요소의 일부분만 보이는 것을 의미합니다.

 

See the Pen Untitled by SM (@SM-the-decoder) on CodePen.

 

 

 

 

반응형

'Javascript' 카테고리의 다른 글

Element.animate()  (0) 2023.07.28
setTimeOut  (1) 2023.07.16
자바스크립트 대괄호 표기법  (0) 2023.07.01
Javascript 한줄 함수 모음  (0) 2023.06.12
JavaScript에서 배열을 병합하는 5가지 방법  (0) 2023.06.01

댓글