-
[JS] 무한스크롤(infinite scroll) : 스크롤이 문서의 끝에 닿았을 때, 추가 콘텐츠를 로드해보자Javascript 2023. 5. 1. 23:01

infinite scroll 방법 1 )
const onScroll = () => { const { scrollTop, scrollHeight, clientHeight } = document.documentElement if (scrollTop + clientHeight >= scrollHeight - 5) { // 화면의 끝 -5px 위치까지 스크롤되면 구현될 코드 넣기 } }이 조건식은 보통 스크롤이 문서의 끝 부분에 도달했을 때, 새로운 콘텐츠를 동적으로 로드하기 위해 사용된다.
즉, 현재 스크롤 위치와 브라우저 창의 높이를 합친 값이 문서 전체의 스크롤 가능한 높이에서 일정 값(5px)을 뺀 값보다 크거나 같으면, 문서의 끝 부분에 도달한 것으로 간주하여 추가적인 콘텐츠를 로드하도록 한다.
보통 무한 스크롤 구현 시 자주 사용되는 코드이다.
여기서 5px는 추가적인 로딩을 트리거하는 스크롤 위치에 대한 여유 공간으로 사용될 수 있다.
이 값은 조정될 수 있으며, 실제 사용 시에는 문서의 크기와 스크롤 위치, 브라우저 창의 높이 등을 고려하여 적절한 값을 설정해야 한다.
방법 2) Intersection Observer API
- 타겟 요소와 상위 요소 또는 최상위 document의 viewport(현재 화면에 보여지는 영역) 사이의 intersection 내의 변화를 비동기적으로 관찰하는 방법
- 실제로 화면에 표시되고 있는 데이터만 불러오게 할 수 있다.
- 컨텐츠 요소가 viewport에 포함되는지 여부를 판단하는 기능을 제공
- https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
Intersection Observer API - Web APIs | MDN
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.
developer.mozilla.org
https://ddiddibbung.tistory.com/manage/posts/
Tistory
좀 아는 블로거들의 유용한 이야기
www.tistory.com
방법 3)
라이브러리를 가져다 쓴다. 초간단!

import useInfiniteScroll from "react-infinite-scroll-hook"; const [infiniteRef] = useInfiniteScroll({ loading: false, hasNextPage: pokemons.next !== "", onLoadMore: async () => { const morePokemons = await fetchPokemons(pokemons.next); setPokemons({ ...morePokemons, results: [...pokemons.results, ...morePokemons.results], }); }, disabled: false, rootMargin: "0px 0px 0px 0px", }); ... <Loading ref={infiniteRef}> <LoadingImage src="https://i.namu.wiki/i/YGWPqZiWe2tAWHNcNlARMQ71LWuIuSRxkigcdOgsQ4kP8Je0Fdq8UGuoLRN_1e65foPl3oYHwtJ5QaCQnQZQYw.gif" alt="피카츄" /> </Loading>불필요한 API 호출을 최적화하기 위해 Intersection Observer 라이브러리도 갖다 쓰도록 하자.
import { useIntersectionObserver } from "react-intersection-observer-hook"; const [ref, { entry }] = useIntersectionObserver(); const isVisible = entry && entry.isIntersecting; useEffect(() => { if (!isVisible) { return; } (async () => { const response = await fetchPokemonInfo(props.name); setPokemons(response); })(); }, [props.name, isVisible]); return ( <Item onClick={handleCardClick} color={pokemons?.color} ref={ref}> ... </Item> );'Javascript' 카테고리의 다른 글
[JS] classList.toggle()로 클래스를 추가·제거하자 (0) 2023.05.02 [JS] 검색 기능 구현 (0) 2023.05.02 [JS] 스크롤 프로그레스 바 구현하기 (0) 2023.04.29 [JS] throttle & debounce (0) 2023.04.29 [JS] querySelector과 querySelectorAll (0) 2023.04.28