[F-Lab 모각코 챌린지 - 61일차] - Intersection Observer

Big One·2023년 7월 10일
0

F-Lab

목록 보기
34/69

Intersection observer란?

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

  • intersection : 교차지점

Intersection이 필요한 이유

  • 페이지가 스크롤 되는 도중에 발생하는 이미지나 다른 컨텐츠의 지연 로딩.
  • 스크롤 시에, 더 많은 컨텐츠가 로드 및 렌더링되어 사용자가 페이지를 이동하지 않아도 되게 하는 infinite-scroll 을 구현.
  • 사용자에게 결과가 표시되는 여부에 따라 작업이나 애니메이션을 수행할 지 여부를 결정.

구문

new IntersectionObserver(callback[, options]);

callback

대상 요소의 보이는 영역 비율이 넘을 때 호출할 함수입니다. callback은 두 개의 매개변수(entries, observer)를 받습니다.

  • entries: 더 드러나거나 가려져서 지정한 역치를 넘어가게 된 요소를 나타내는 IntersectionObserverEntry 객체의 배열
  • observer: 콜백을 호출할 IntersectionObserver

options

감지기를 조절할 수 있는 객체입니다.

  • root: 대상 요소의 조상 Element 또는 document 여기에 지정한 요소 또는 문서를 감지기의 뷰포트로 사용합니다.
  • rootMargin: 교차 계산시 루트 영역으 ㅣ크기를 키우거나 줄이고자할 때 사용합니다. 여백이랑 비슷함
  • threshold: 0.0 ~ 1.0 사이의 숫자, 숫자 배열을 지정합니다. 감시하는 대상이 뷰포트에 나타나는 영역의 비율을 나타냅니다.

반환 값

지정한 root 내에서 주시중인 요소의 가시성이 threshold를 위아래로 넘어가는 경우를 감지할 수 있는 새로운 IntersectionObserver.observe() 메서드를 호출해서 새로운 요소를 주시할 수 있습니다.

메서드

  • disconnect: 모든 대상으 ㅣ주시를 해제합니다.
  • observe: 주어는 대상 요소를 주시합니다.
  • takeRecords: 모든 주시 대상에 대한 IntersectionObserverEntry 배열을 반환합니다.
  • unobserve: 특정 대상 요소에 대한 주시를 해제합니다.

쓰로틀링 개념을 적용하고 IntersectionObserver를 사용하여 무한 스크롤을 구현해 보았습니다.

//HTML
<section class="data-list">
</section>

// JS
const renderBox = (start, end, bgColor) => {
  for (let i = start; i < start + end; i++) {
    const div = document.createElement('div');
    div.setAttribute('class', 'dummy-box');
    div.style.height = '300px';
    div.style.lineHeight = '300px';
    div.style.border = '1px';
    div.style.borderColor = 'black';
    div.style.borderStyle = 'solid';
    div.style.backgroundColor = bgColor;
    div.innerHTML = 'dummyBox' + i;
    document.querySelector('.data-list').appendChild(div);
  }
}
renderBox(0, 10);
const loadMoreBox = (moreCnt) => {
  let dummyBoxCnt = document.querySelectorAll('.dummy-box').length;
  const bgColor = dummyBoxCnt > 60 ? 'skyblue' : 'orange';
  renderBox(dummyBoxCnt, moreCnt, bgColor);
}
const ioCallback = (entries, io) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      io.unobserve(entry.target);
      setTimeout(() => {
        loadMoreBox(10);
        observeLastItem(io, document.querySelectorAll('.dummy-box'));
      }, 200);
    }
  });
};

const observeLastItem = (io, items) => {
  const lastItem = items[items.length - 1];
  io.observe(lastItem);
};
const io = new IntersectionObserver(ioCallback, {threshold: 0.7});
observeLastItem(io, document.querySelectorAll('.dummy-box'));

observerLastItem 을 함수로 분리하였고 ioCallback 을 통해 실행 재실행 시키면서 감시대상을 맨 마지막 요소로 변경해주었습니다.

profile
이번생은 개발자

0개의 댓글