infiniteScroll 기법

SHINWON KIM·2024년 12월 18일

infiniteScroll(무한 스크롤): 사용자가 특정 페이지를 스크롤하여 하단에 도달했을 때, API가 호출되며 데이터를 비동기로 가져와서 콘텐츠가 끊기지 않고 계속 로드되는 기법이다. 이 기법은 특히 긴 리스트의 콘텐츠를 제공하는 웹사이트에서 자주 사용된다. ex) 소셜 미디어, 뉴스 피드, 상품 목록

JS로 비동기 데이터 가져오기(무한 스크롤 구현하기)

  1. 스크롤 이벤트 감지: 사용자가 페이지를 스크롤할 때 스크롤 위치를 체크하여 페이지 끝에 다다르면 추가 데이터를 요청한다.
  2. 비동기 요청(AJAX): 서버에서 데이터를 비동기적으로 가져와서 화면에 표시한다. 일반적으로 fetch / XMLHttpRequest를 사용하여 데이터를 요청한다.
  3. 서버에서 데이터 제공: 서버는 클라이언트가 요청할 때마다 데이터를 페이지네이션 형태로 반환한다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Infinite Scroll</title>
  <style>
    #loading {
      text-align: center;
      font-size: 16px;
      padding: 10px;
    }
  </style>
</head>
<body>
  <div id="content"></div>
  <div id="loading" style="display: none;">Loading...</div>

  <script>
    let page = 1;
    let isLoading = false;

    // 데이터를 가져오는 함수
    async function loadData(page) {
      const loadingElement = document.getElementById('loading');
      loadingElement.style.display = 'block'; // 로딩 중 표시

      try {
        const response = await fetch(`https://example.com/api/data?page=${page}`);  // 실제 API로 대체
        const data = await response.json();

        // 데이터를 화면에 추가
        const contentElement = document.getElementById('content');
        data.items.forEach(item => {
          const div = document.createElement('div');
          div.className = 'item';
          div.innerHTML = item.name;  // 데이터에 맞게 처리
          contentElement.appendChild(div);
        });

        page++; // 다음 페이지 번호로 증가
      } catch (error) {
        console.error("데이터를 가져오는 중 오류가 발생했습니다:", error);
      } finally {
        loadingElement.style.display = 'none'; // 로딩 완료
        isLoading = false;
      }
    }

    // 스크롤 이벤트 처리
    window.addEventListener('scroll', () => {
      const scrollHeight = document.documentElement.scrollHeight;
      const scrollPosition = window.innerHeight + window.scrollY;

      if (scrollPosition >= scrollHeight - 200 && !isLoading) {  // 200px 여유
        isLoading = true;
        loadData(page);
      }
    });

    // 첫 번째 데이터 로드
    loadData(page);
  </script>
</body>
</html>
  • loadData(page): fetch API를 사용하여 서버에서 데이터를 비동기적으로 요청한다. 이때, page 값을 URL 파라미터로 전달하여 서버에서 해당 페이지에 맞는 데이터를 받아온다. 데이터를 받아오면 #content 영역에 동적으로 콘텐츠를 추가한다.

  • scroll 이벤트: 사용자가 페이지를 스크롤할 때, 문서의 스크롤 위치(window.scrollY)와 전체 문서의 높이(document.documentElement.scrollHeight)를 비교한다.
    사용자가 페이지 하단에 가까워지면(여기서는 200px 여유를 둔 상태) loadData() 함수를 호출하여 데이터를 추가로 로드한다.
    로딩 중일 때 추가적인 요청을 방지하기 위해 isLoading 플래그를 사용하여 요청이 진행 중인지를 추적한다.

  • 서버 응답 형식: 서버에서 데이터를 반환할 때는 items 배열을 포함하는 JSON 형식으로 응답한다.

[json]

{
  "items": [
    {"name": "Item 1"},
    {"name": "Item 2"},
    {"name": "Item 3"}
  ]
}

0개의 댓글