[infinite-scroll] 스크롤을 끝까지 땡긴다는 건?

김민석·2021년 6월 8일
1

NodeBird 클론코딩

목록 보기
9/10
	useEffect(() => {
		const onScroll = e => {
			// timer가 없으면 scroll event 시행
			console.log(
				document.documentElement.scrollHeight,
				window.innerHeight,
				document.documentElement.clientHeight,
				window.scrollY,
			);
			if (!timer.currnet) {
				timer.current = setTimeout(() => {
					timer.current = null;
					if (document.documentElement.scrollHeight === window.scrollY + window.innerHeight) {
						console.log('the end');
					}
				}, 200);
			}

		};
		window.addEventListener('scroll', onScroll);
		return () => {
			window.removeEventListener('scroll', onScroll);
		};
	});

참고: 쓰로틀링

실행 횟수에 제한을 거는 것이다.
위 함수를 예를 들면, 어떤 작동을 200ms에 1번만 작동할 수 있게 제한을 걸었다.


이 네가지를 차례로 찍어본 결과

document.documentElement.scrollHeight
document.documentElement.clientHeight
window.scrollY

아래와 같은 결과가 나왔다.

각 변수에 대한 자세한 설명

따라서 위에서 내가 쓴 변수들 중에서,

  • window.innerWidth는 현재로써는 사용하면 안되는 속성이며,
  • document.scrollHeight의 경우는 엄밀하게 계산하자면 아래와 같이 계산해야한다.
let scrollHeight = Math.max(
  document.body.scrollHeight, document.documentElement.scrollHeight,
  document.body.offsetHeight, document.documentElement.offsetHeight,
  document.body.clientHeight, document.documentElement.clientHeight
);

문제 :
1) chrome을 핸드폰 사이즈마냥 좁게 만들었을 때 스크롤바가 중간으로 오지 않고 계속 아래 박혀 있는 문제가 있다.
2) 현재 redux saga에서 delay를 주어 ajax 요청을 흉내내었는데 이것과 throttle과 같이 썼을 때,

throttle은 스크롤 내리는 중에 요청을 여러번 보내지 않게 하기 위함임.

이상한 행동을 하는 것처럼 보인다. (setTimeOut 관련 문제라고 '의심' 중이지만 확실하지 않다!)
우선 delay를 제거하니 예상대로 작동하는 모습을 보였다.


	useEffect(() => {
		const onScroll = () => {
			if (
				Math.max(
					document.body.scrollHeight,
					document.documentElement.scrollHeight,
					document.body.offsetHeight,
					document.documentElement.offsetHeight,
					document.body.clientHeight,
					document.documentElement.clientHeight,
				) -
					300 <
				window.pageYOffset + document.documentElement.clientHeight
			) {
				if (hasMorePosts && !loadPostLoading) {
					dispatch({
						type: LOAD_POSTS_REQUEST,
					});
				}
			}
		};
		window.addEventListener('scroll', onScroll);
		return () => {
			window.removeEventListener('scroll', onScroll);
		};
	}, [hasMorePosts, loadPostLoading]);

0개의 댓글