우선 기본이 되는것들 부터 정리하고 알아보도록 하자
document.body.scrollTop
document.documentElement.scrollTop
: IE 브라우저에서도 작동됨.scrollHeight
: 스크롤 시키지 않았을때의 전체 높이 (컨텐츠의 전체 높이. 패딩과 테두리가 포함. 마진은 제외)clientHeight
: 요소의 내부 높이. (패딩 값은 포함,scrollHeight
, clientHeight
, scrollTop
은 모두 웹 개발 표준기구? 의 속성이 아니라서 브라우저마다 0~40px 정도씩 오류가 생길 수 있다.
따라서 이 세가지 속성 모두 제대로 사용하지 못하면 값을 전부 0으로 반환하므로, 다음과 같이 사용할 수 있다.
예시
if (document.body.scrollTop == 0) {
var top = document.documentElement.scrollTop;
} else {
var top = document.body.scrollTop;
}
또는
const scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
그런데, 무한 스크롤을 적용하려고 하는중에 handleScroll이라는 이벤트 핸들러가 작동되지 않는 오류가 있었다.
const [pocketItemIndex, setPocketItemIndex] = useState(0);
const [pocketList, setPocketList] = useState(InitialPocketList.slice(0, 6));
const handleScroll = () => {
const scrollHeight = Math.max(
document.documentElement.scrollHeight,
document.body.scrollHeight,
);
const scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
const clientHeight = document.documentElement.clientHeight;
if (scrollTop + clientHeight === scrollHeight) {
setPocketItemIndex(pocketItemIndex + 6);
setPocketList(
pocketList.concat(InitialPocketList.slice(pocketItemIndex + 6, pocketItemIndex + 12)),
);
}
};
useEffect(() => {
window.addEventListener('scroll', handleScroll);
//handleScroll이라는 이벤트 핸들러가 작동하지 않음!!
return () => window.removeEventListener('scroll', handleScroll);
}, [pocketList, isMoreInfoButtonVisible]);
이유를 알아보니,
1. height: 100%
또는 height: 100vh
일때 스크롤이벤트는 viewport height 보다 요소가 넘어갈때 발생하기 때문에, 이렇게 되어있을때 발생하지 않을 수 있고
overflow: hidden
으로 스크롤할 수 없도록 설정되어 있을때는 항상 스크롤 이벤트가 body
요소에 발생하기 때문에, 원하는 요소가 아닌 곳에 scroll event가 fire되어서 그럴 수 있다고 하였다.overflow:auto
또는 overflow:scroll
로 바꿔주기따라서 나의 경우
Globalstyle.tsx
html{
...
/* overflow:hidden; */
...
}
window.addEventListener('scroll', handleScroll);
이 부분을
document.body.addEventListener('scroll', handleScroll);
이렇게 바꿔주니 해결되었다.
그런데 1번 방법은 프로젝트 전체구조에 영향을 미치기 때문에, 2번방법을 사용하여 해결하였다.
참고