스크롤 시 header에 그림자 보여주기
JAVASCRIPT ·스크롤 여부를 확인하는 방법
처음에는 new IntersactionObserver
를 적용해 헤더의 바로 다음 요소가 가려지기 시작하면 스크롤이 되었다는 상태값을 바꿔주는 형식을 적용하고자 했었습니다. 하지만, 스크롤이 되는 순간부터 window.scrollY
값이 바뀐다는 것을 알게 되었고, 굳이 더 복잡한 방식을 적용할 필요가 없다고 생각해 window.scrollY
를 이용해 처리를 하도록 했습니다.
그리고 스크롤이 되는 상황에 대해서 화면이 인지하고 상태를 바꿔야하기 때문에, window.onscroll
에 함수를 적용해주었습니다.
const useIsTopState = () => {
const [isTop, setIsTop] = useState(true);
// 페이지의 최상단에 있는지를 나타내는 state
window.onscroll = () => {
setIsTop(!window.scrollY);
// 스크롤되는 화면의 최상단에 있을 시 scrollY = 0 이므로 isTop이 true가 됨
};
return isTop;
};
상태를 받은 header의 스타일 변경하기
isTop 상태를 받은 header가 true
일 때에만 그림자를 보여주지 않도록 설정을 해, 스크롤이 되는 상황에서 지속적으로 그림자를 보여주도록 설정했습니다.
const Chatrooms = () => {
...
const isTop = useIsTopState();
// isTop 상태를 받아옴
...
<S.Wrapper>
<S.HeaderWrapper isTop={isTop}>
// 사용하고자 하는 header에 적용
<TopFixedWarning text='채팅 연결 끊김' otherStyle={S.TopFixedWarningStyle} />
<S.Header onClick={() => setIsConnected(!isConnected)}>
...
export const HeaderWrapper = styled.div<{ isTop: boolean }>`
${({ theme: { colors, defaultWidth, defaultPadding }, isTop }) => css`
${defaultWidth};
...
transition: all 0.3s;
// 그림자가 부드럽게 사라지고 나타나기 위해 설정
${!isTop &&
css`
box-shadow: 2px 4px 6px rgba(0, 0, 0, 0.08);
// 최상단에 있을 때에만 그림자가 안 보이도록 설정
`}
위 코드들을 적용해줌으로써, 스크롤 상황에 대한 그림자 표현을 할 수 있었습니다.

window.onscroll 값을 초기화해야 하는지
useEffect(() => {
return () => {
window.onscroll = null;
};
}, []);
기존에는 위와 같이 화면을 나가는 경우 window,onscroll
을 초기화하도록 설정을 해주었습니다. 초기화를 하지 않는 경우, 이 함수가 사용되지 않는 곳에서도 지속적으로 함수가 작동해 불필요한 연산이 될 것이라는 예상 때문이었습니다. 하지만, 아래와 같이 useEffect
가 없어도 화면 전환 시 onScroll
의 함수는 없어진다는 것을 확인할 수 있었습니다. (console.log()
로 확인)
