scroll event handler가 작동하지 않을때

우선 기본이 되는것들 부터 정리하고 알아보도록 하자

스크롤의 현재 위치를 알 수 있는 방법

  1. document.body.scrollTop
  2. *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 보다 요소가 넘어갈때 발생하기 때문에, 이렇게 되어있을때 발생하지 않을 수 있고

  1. overflow: hidden으로 스크롤할 수 없도록 설정되어 있을때는 항상 스크롤 이벤트가 body요소에 발생하기 때문에, 원하는 요소가 아닌 곳에 scroll event가 fire되어서 그럴 수 있다고 하였다.
    -> overflow:auto 또는 overflow:scroll로 바꿔주기

따라서 나의 경우

1. globalStyles에 정의되어있던 overflow:hidden 부분을 삭제해주거나,

Globalstyle.tsx

html{
...
/* overflow:hidden; */
...
}

2.

window.addEventListener('scroll', handleScroll);

이 부분을

document.body.addEventListener('scroll', handleScroll);

이렇게 바꿔주니 해결되었다.

그런데 1번 방법은 프로젝트 전체구조에 영향을 미치기 때문에, 2번방법을 사용하여 해결하였다.


참고

좋은 웹페이지 즐겨찾기