사이트의 게시글 목록에서 게시글 수가 많아지면 자연스럽게 페이징으로 처리하게된다.
그 중 Infinite Scroll에 대해서 알아봤다.
처음엔 5개의 div element가 화면에 나타난다.
구현 방식은 throttling을 이용했다. 스크롤 할 때마다 불필요한 이벤트가 실행되어 throttling으로 일정 시간동안 이벤트가 실행이 되지 않게 했다.
원래라면 ajax를 사용하여 데이터를 불러오는 형식으로 하고싶었지만 준비된게 없어서 스크롤을 내리면 5개의 div element가 추가되는 형식으로 했다.
export const throttling = (fn, time) => {
let timer;
return () => {
if (!timer) {
timer = setTimeout(() => {
fn();
timer = false;
}, time);
}
};
};
간단하게 throttling 기능을 구현했다.
그런 뒤 window에 scroll 이벤트를 달아준다. 다음과 같은 방식으로 달아주면 된다.
window.addEventListener(
"scroll",
throttling(() => {
if (window.scrollY + window.innerHeight >= document.body.offsetHeight) {
main.render();
}
}, 700)
);
(전체 문서 길이는 document.body.offsetHeight
, 스크롤 된 길이는 scrollY
, 사용자 화면은 innerHeight
로 뒀다.)
현재 사용자 화면의 높이와 스크롤 된 길이의 합이 전체 문서의 길이보다 크거나 같으면 element를 추가하도록 했다.
그 다음에 스크롤이 끝부분에 오게 되면 element를 추가하게 하는 로직을 짜야한다.
render() {
this.target.innerHTML += Array.from({ length: 5 }).reduce(
(acc, cur, index) => {
acc += `<div class=board>${this.maxId}번째 게시글입니다.</div>`;
this.maxId += 1;
return acc;
},
``
);
}
scrollY, innerHeight, offsetHeight는 각각 무슨 의미를 가지는 걸까?
window.scrollY
는 세로 스크롤바가 얼마만큼 이동을 했는지 픽셀 단위로 나타낸다.
현재 뷰포트의 위쪽 모서리의 Y좌표를 반환하고, 뷰포트가 없을 경우 0을 반환한다고 한다.
뷰포트는 브라우저에서 화면 크기를 얘기하며 메뉴바, 탭영역을 제외한 순수한 화면 영역을 뜻한다.
참고로 window.pageYOffset === window.scrollY;//true
이다.
브라우저 간의 호환성을 위해선 scrollY보단 pageYOffset을 사용하는 것을 권장한다고 한다. (역시나 IE가 문제다.)
window.innerHeight
는 뷰포트의 가로 스크롤을 포함한 세로 길이를 뜻한다.
HTMLElement.offsetHeight
는 세로 padding 및 border를 포함한 요소의 높이를 정수로 반환합니다.
clientHeight
element.clientHeight
는 offsetHeight처럼 요소의 높이를 반환하지만 padding만을 포함하고 border과 스크롤은 제외된다.
scrollHeight
element.scrollHeight
는 요소 콘텐츠의 총 높이를 나타내며, 바깥으로 넘쳐서 보이지 않는 콘텐츠도 포함합니다.
스크롤을 끝으로 내릴때마다 element가 추가되는 것을 볼 수 있다.