스크롤 할 수 있는 높이= scrollHeight
사용자가 볼 수 있는 높이=clientHieght
scrollTop= 원 글 맨 처음~ 화면에 보이는 부분 제일 위까지 길이
따라서 scollHeight-scrollTop이 clientHeight와 같으면 맨 아래까지 스크롤이 내려갔다는 것을 알 수있다. (맨 아래로 내리면 scollTop이 보이는 부분을 제외한 만큼 길어질테니까)
예를 들어 원 글의 길이가 0-1000px, 화면 범위가 0-100px
마우스 휠로 끝까지 스크롤 내릴 수 있는 길이= 101-1000px=899px
scrollTop은 최대 899px이다.
따라서 무한 스크롤링을 하려면
scrollHeight-scrollTop=clientHeight값과 같으면 된다.
10을 붙인 이유는 미세한 오차 때문이다.
atImgList.scrollHeight - catImgList.scrollTop <= catImgList.clientHeight + 10
스크롤이 생길 때마다 위에 코드가 실행되므로 성능 상 좋지 않다.
또한 스크롤 하단바를가 하단바에 도달했다면 스크롤을 조금만 계속해도 중복적으로 계속 실행되는 문제가 있다
쓰로틀링을 사용하면 이벤트가 일정한 주기마다 실행되므로 위에 문제를 해결할 수 있다.
addEventListener가 실행되면 throttling도 실행된다.
catImgList.addEventListener('scroll',
//0.2초마다 infinityScroll을 실행한다.
throttling(infinityScroll,200));
throttling이 실행되면 timer는 null이 되고
return함수에 timer변수가 있기 때문에 timer 변수가 클로저가 된다.
(timer 변수는 return에서 호출되는 함수밖에 바꾸지 못한다.)
setTimeout
= timer id를 반환하기 때문에 호출 시점에 숫자가 할당된다.
callback
= 함수가 호출되면 다시 timer에 null로 바꾸어 함수 호출이 가능한 상태로 바꾼다.
delay
= 몇 밀리초 동안 콜백 함수가 실행되지 않아야 하는지를 나타낸다.
const throttling = (callback, delay) => {
let timer = null;
return () => {
if (timer === null) {
timer = setTimeout(() => {
callback();
timer = null;
}, delay);
}
};
};
다시 돌아와서..
만약 scroll이 감지되면 throttling에서 timer이 null인 것을 확인하고,
만약 null이라면 setTimout이 timer에 어떠한 숫자를 할당한다.
timer = setTimeout(() => {
그리고 0.2초 뒤에 함수를 실행한 뒤 timer를 다시 null값으로 바꾼다.
timer = null;
이 말은 즉, 0.2초 동안은 timer가 어떠한 숫자가 할당 되어있기 때문에 실행되지 않는다!
0.2초 후 timer가 null값이 될 때 접근할 수 있다.