이번에는 라이브러리 없이 무한 스크롤 구현을 해보겠습니다.
1. Scroll event
2. intersection observer
스크롤 이벤트의 경우 현재 위치를 구해야 합니다.
body : 3093
scrollHeight : 3093
scrollTop : 131 -> 2207
clinentHeight : 886
아래와 같이 스크롤 이벤트를 구현해주면 됩니다.
import renderList from './renderList';
const app = document.querySelector('#app');
const fetchMoreTrigger = document.querySelector('#fetchMore');
let page = 0;
const fetchMore = async () => {
const target = page ? fetchMoreTrigger : app;
target.classList.add('loading');
await renderList(page++);
target.classList.remove('loading');
};
const onScroll = e => {
const {
scrollHeigt,
scrollTop,
clientHeigt,
} = e.target.scrollingElement;
if (scrollTop + clientHeigt === scrollHeigt) {
fetchMore()
}
};
document.addEventListener('scroll', onScroll);
fetchMore();
스크롤 이벤트를 사용하면 계속 실행이 되기 때문에 성능 저하가 될 수 있기 때문에
연속으로 발생하는 이벤트에 대해서 아래와 같은 처리를 해주어야 합니다.
debounce를 활용해서 시간지연을 시켜주도록 하는 코드를 추가하여 성능을 개선할 수 있습니다.
const debounce = (event, delay) => {
let timeoutId = null;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(event.bind(null, ...arg), delay);
};
// 코드 생략 ...
document.addEventListener('scroll', debounce(onScroll, 500));
fetchMore();
500ms 동안에 발생하는 스크롤 이벤트 모두 취소하고 마지막 한 번만 실행하는 코드를 만들 수 있습니다.
HTML, CSS, 자바스크립트가 개입하지 않는 문법을 고민하는게 좋은 방법이라고 하여 자바스크립트에서 제공해주는 Intersection Observer API에 대해서도 알아보도록 하겠습니다.
Intersection Observer API는 타겟 요소와 상위 요소 또는 최상위 document 의 viewport 사이의 intersection 내의 변화를 비동기적으로 관찰하는 방법입니다.
intersection observer는 화면에 보여지는 여부를 판단합니다. 감시하고자하는 요소가 뷰포트에 들어가거나 나갈때 두 요소의 교차부분이 변경될 때 마다 실행될 콜백 함수를 등록할 수 있게 합니다. 교차 영역 관리를 최적화할 수 있는 방법입니다.
[ 공식 문서 링크 : Intersection Observer API ]
요구 사항
- 처음에 10개만 불러오기
- 1.5초가 지나면 추가로 10개 불러오기 및 스크롤이 최하단에 닿을 때마다 10개씩 추가하기
요구 사항에 맞게 구현한 화면 모습입니다.
아래와 같이 코드를 구현해주면 됩니다.
console.log(entry)를 찍어서 확인해보겠습니다.
우리가 체크해야할 부분은 isIntersecting 입니다.
isIntersecting이 false인지 true인지에 대해 관찰해주면 됩니다.
이렇게 무한스크롤을 구현해보았습니다.