Infinite scroll은 사용자가 스크롤을 내리면 추가적인 콘텐츠를 동적으로 로드하는 기술입니다.
스크롤 이벤트를 감지하고 추가 콘텐츠를 가져오기 위해 이벤트 리스너를 등록합니다.
window.addEventListener('scroll', loadMoreContent);
추가 콘텐츠를 가져오기 위해 서버 API를 호출합니다. 이때 비동기적으로 호출하며, 새로운 데이터를 로드할 때마다 페이지 번호 또는 커서 위치 등을 파라미터로 전달합니다.
function loadMoreContent() {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
const nextPage = currentPage + 1;
const url = `https://api.example.com/content?page=${nextPage}`;
fetch(url)
.then(response => response.json())
.then(data => {
// 가져온 데이터를 처리합니다.
// DOM 요소를 생성하여 새로운 콘텐츠를 추가합니다.
// ...
// 현재 페이지 번호를 업데이트합니다.
currentPage = nextPage;
})
.catch(error => console.error(error));
}
}
가져온 데이터를 처리하여 DOM에 새로운 콘텐츠를 추가합니다.
function loadMoreContent() {
// ...
fetch(url)
.then(response => response.json())
.then(data => {
// 가져온 데이터를 처리합니다.
const newContent = createNewContent(data);
// DOM 요소를 생성하여 새로운 콘텐츠를 추가합니다.
const container = document.querySelector('#content-container');
container.appendChild(newContent);
// ...
})
.catch(error => console.error(error));
}
새로운 콘텐츠를 추가한 후, 다음 페이지 번호를 업데이트합니다.
function loadMoreContent() {
// ...
fetch(url)
.then(response => response.json())
.then(data => {
// 가져온 데이터를 처리합니다.
// ...
// 현재 페이지 번호를 업데이트합니다.
currentPage = nextPage;
})
.catch(error => console.error(error));
}
마지막 콘텐츠에 도달하여 스크롤 이벤트 리스너가 필요 없어진 경우, 이벤트 리스너를 지웁니다.
if (total === end) {
window.removeEventListener('scroll', loadMoreContent)
return
}
아래에서 사용하는 외부 API 👉🏻 https://jsonplaceholder.typicode.com/
총 100개의 데이터를 한 페이지에 10개씩 로드하면서, scroll이 바닥에 도달할 경우 페이지를 +1 하며 10개의 데이터를 더 로드한다.
let currentPage = 1;
let total = 10;
const limit = 10;
const end = 100;
const $posts = document.querySelector('.posts');
window.addEventListener('load', () => {
loadPosts(currentPage, limit);
});
window.addEventListener('scroll', handleScroll);
const getPosts = async (page, limit) => {
const API_URL = `https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=${limit}`
const res = await fetch(API_URL);
if (!res.ok) {
throw new Error('에러가 발생했습니다.');
}
return await res.json();
}
const loadPosts = async (page, limit) => {
const res = await getPosts(page, limit);
showPosts(res);
}
const showPosts = (posts) => {
posts.forEach((post) => {
const $post = document.createElement('div');
$post.classList.add('post');
$post.innerHTML = `
<div class="header">
<div class="id">${post.id}</div>
<div class="title">${post.title}</div>
</div>
<div class="body">${post.body}</div>
`
$posts.appendChild($post);
})
}
onst handleScroll = () => {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight) {
currentPage++;
total += 10;
loadPosts(currentPage, limit);
return;
}
}
const handleScroll = () => {
...
if (total === end) {
window.removeEventListener('scroll', handleScroll);
return;
}
...
}
데이터 100개를 다 로드한 경우, scroll 이벤트 리스너를 삭제했다.