IntersectionObserver 활용한 스크롤 구현

2020. 6. 26. 08:55웹/Javascript

IntersectionObserver MDN

  • 대상 요소와 그 상위 요소 혹은 최상위 도큐먼트인 viewport와의 교차 영역에 대한 변화를 비동기적으로 감지할 수 있게 도와주는 API
  • IntersectionObserver 가 생성되면, 루트 내에서 설정된 비율 만큼의 가시성을 계속 감시하도록 설정. 한번 생성되고 나면, 설정 값은 변경될 수 없으므로, 생성된 감시자 객체는 가시성 정도의 변화를 감시하는 데에만 쓰일 수 있음. 하지만 동일한 감시자 객체로 여러 대상 요소를 감시할 수 있음

IntersectionObserver.IntersectionObserver()

  • IntersectionObserver 객체를 생성

  • 해당 객체는 대상 요소의 가시성이 하나 이상의 설정된 정도 값을 넘을 경우 주어진 콜백 함수를 실행

  • 매개변수

    • callback : 대상 요소의 화면에 보이는 부분 백분율이 역치보다 클 때 호출할 함수

      • entries  : 더 보이거나 덜 보이게 되면서 통과한 역치를 나타내는, IntersectionObserverEntry 객체의 배열

      • observer : 자신을 호출한 IntersectionObserver.

    • options : 옵저버를 조정할 수 있는 옵션 객체

 

new IntersectionObserver(callback[, options]);

 

 

 

구현 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="./intersectionObserverTest.js"></script>
    <style>
        h3 {
            text-align: center;
        }

        li {
            list-style: none;
            width: 100%;
            height: 50px;
            line-height: 50px;
            border: 1px solid;
        }

        .loader {
            height: 20px;
            width: 100%;
        }
    </style>
</head>


<body>
    <div class="header">
        <h3>intersectionObserver 활용한 스크롤 구현</h3>
    </div>
    <div class="content">
        <ul></ul>
        <!-- content 영역 안의 loader div 영역을 viewport 와의 교차 지점 대상 -->
        <div class="loader"></div>
    </div>
</body>
</html>

 

intersectionObserverTest.js

window.onload = function () {
  const count = 30;
  let index = 0;


  /**
   * Data Fetch Function
   */
  const fetchData = () => {
    return new Promise((resolve, reject) => {
      document.querySelector(".loader").innerHTML = "loading ...";

      setTimeout(() => {
        const container = document.querySelector(".content>ul");
        const fragment = document.createDocumentFragment();
        for (let i = index; i < index + count; i++) {
          const item = document.createElement("li");
          item.innerHTML = `text - ${i}`;
          fragment.appendChild(item);
        }
        container.appendChild(fragment);
        index += count;
      }, 1000);
    });
  };


  /**
   * IntersectionObserver Function
   */
  const intersectionObserver = new IntersectionObserver(([loader]) => {
    if (loader.intersectionRatio <= 0) {
      return;
    }
    fetchData().then(() => {
      document.querySelector(".loader").innerHTML = "";
    });
  });


  intersectionObserver.observe(document.querySelector(".loader"));
};

 

출력결과 - 1)

출력결과 - 2)

출력결과 - 3)

 

 

참고

https://velog.io/@yejinh/Intersection-Observer%EB%A1%9C-%EB%AC%B4%ED%95%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

https://heropy.blog/2019/10/27/intersection-observer/

 

' > Javascript' 카테고리의 다른 글

Scroll 이벤트를 활용한 스크롤 구현  (0) 2020.06.25
이벤트 전달 방식(버블링, 캡처, 위임)  (0) 2020.06.15
call, apply, bind 메서드  (0) 2020.03.10
스코프와 클로저  (0) 2020.03.05
스코프 체인  (0) 2020.03.05