스크림도르 작업을 진행 중에 모바일 화면에서도 어느 정도는 사이트를 이용할 수 있게 해야한다는 생각이 들어서 반응형 작업을 진행하였다. 갈 수록 기존의 사이트들에 비해 무언가 부족하다는 생각을 했는데, 다른 유튜브, 트위터 등의 사이트를 보니 아래로 스크롤을 할 때에는 header와 하단의 navigation이 사라지고, 위로 스크롤 할 때만 생겨난다는 사실을 확인할 수 있었다. 그래서 우리도 구현해보기로 결심!
먼저 JS에서 스크롤 이벤트를 다룬다는 사실만 알고 있었지 어떻게 이용하는지는 자세히 몰라서 조사를 시작했다.
이전에 사용했던 Intersection Observer는 특정 element가 inView되는 경우에 사용하는 것 같아서 패스하고, 전역적인 window에다가 스크롤 다운 / 업을 분기로 나누어서 throttle을 걸어서 구현해보기로 했다.
https://stackoverflow.com/questions/62497110/detect-scroll-direction-in-react-js
요 페이지에서 구현한 코드를 뜯어보았다.
const [scrollDir, setScrollDir] = useState("scrolling down");
useEffect(() => {
const threshold = 0;
let lastScrollY = window.pageYOffset;
let ticking = false;
const updateScrollDir = () => {
const scrollY = window.pageYOffset;
if (Math.abs(scrollY - lastScrollY) < threshold) {
ticking = false;
return;
}
setScrollDir(scrollY > lastScrollY ? "scrolling down" : "scrolling up");
lastScrollY = scrollY > 0 ? scrollY : 0;
ticking = false;
};
const onScroll = () => {
if (!ticking) {
window.requestAnimationFrame(updateScrollDir);
ticking = true;
}
};
window.addEventListener("scroll", onScroll);
console.log(scrollDir);
return () => window.removeEventListener("scroll", onScroll);
}, [scrollDir]);
살펴보니 이전의 window.pageYOffset
을 넣어두고 새로운 값과 비교해서 커지면 down, 작아지면 up이라고 나누는 방식이었다.
문제는 이 코드를 app에 작성을 해보았을 때, 제대로 되지 않는 다는 점!!
그래서 서칭을 좀 해보니
지금 우리의 경우, window에서 스크롤 이벤트가 일어나는 것이 아니라 특정 div 안에서 스크롤 이벤트가 일어나는 경우에는(overflow : auto / scroll 등이 걸려있어서) 해당 element 안에서 직접 event를 체크해야 한다는 것이었다.!!!
우리 프로젝트의 기본 레이아웃은 다음과 같이 설정되어 있다.
문제는 nav는 언제나 고정된 상태로 PAGE에서만 스크롤이 일어나니 위의 문제로 제대로 된 SCROLL EVENT
를 잡아주는 못하는 것이었다.
저 PAGE
컴포넌트 안 에서 scroll event를 잡아주면 해결!