지난 번에는 Intersection Observer API
를 이용한 무한스크롤 구현에 대해 살펴본 만큼 오늘은 스크롤 이벤트를 이용한 무한스크롤링에 대해 조금 더 공부를 해보았습니다.
스크롤이 끝나는 경우 추가적인 정보를 불러오도록 하기 위해 먼저, 스크롤이 끝났는지를 확인해야합니다. 이를 확인하기 위해 scrollingElement
속성을 사용할 수 있습니다.
scrollingElement
속성은 문서를 스크롤하는 element에 대한 읽기전용 참조를 반환합니다.
표준 모드에서는 문서의 루트경로인 document.documentElement
를 quirks 모드에 있는 경우에는 HTML body요소가 있고 스크롤이 가능한 경우 해당 요소를 반환하고, 그렇지 않은 경우 null을 반환합니다.
MDN문서를 확인하면 보다 자세한 내용을 확인할 수 있습니다.
const onScroll = e => {
console.dir(e.target.scrollingElement)
};
document.addEventListener("scroll", onScroll);
콘솔창에서 해당 속성을 확인해보면, scrollHeight
, scrollTop
, clientHeight
속성이 있는 것을 확인할 수 있습니다. 이 세가지 속성을 이용하면 스크롤이 끝났는지를 계산할 수 있습니다.
스크롤이 가장 하단에 위치한 경우 scrollTop
과 clientHeight
를 더한 값은 scrollHeight
가 되게 됩니다.
이를 이용해 스크롤 이벤트를 작성하면 아래와 같습니다.
const onScroll = e => {
console.dir(e.target.scrollingElement)
const {
clientHeight,
scrollTop,
scrollHeight
} = e.target.scrollingElement;
if (scrollTop + clientHeight === scrollHeight ) {
loadMore()
}
};
document.addEventListener("scroll", onScroll);
scrollTop + clientHeight === scrollHeight
인 경우 추가적인 정보를 실행하는 함수를 불러오면 스크롤이벤트 구현이 끝나게 됩니다.😊
다만, 지난 번 정리를 한 것과 같이 스크롤이 발생할 때마다 함수가 실행되기에 너무 많은 리소르를 낭비하게 됩니다. 이를 trottle
, debounce
를 통해 보안할 수 있습니다.
일정시간마다 한번씩 실행시키는 것이 trottle
, 연속적으로 발생하는 일에 대해 처음 또는 마지막 한번만 실행하는 방법이 debounce
입니다.
export const debounce = (func, delay) => {
}
함수를 받아 일정시간이 지난 후에 실행을 시키게 됩니다. 즉, 함수가 실행되는 시간을 지연시키는 것입니다. 현재는 스크롤이 제일 마지막에 위치하는 경우 함수를 실행시키고 있기에 마지막 한번만 실행시키도록 구현해보도록 하겠습니다.
만약, 그 지연되는 시간 동안 동일한 이벤트가 발생하는 경우 앞의 함수를 취소하고 마지막 함수를 실행시키면 됩니다.
export const debounce = (func, delay) => {
let timeoutId = null;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(func.bind(null, ...args), delay)
}
}
document.addEventListener("scroll", debounce(onScroll, 300));