스크롤 방향에 반응하는 헤더

Taek·2020년 6월 14일
5
post-custom-banner

스크롤이 아래로 향하면 숨기고, 위를 향하면 보여주는 헤더가 있으면 좋을 것 같다는 생각이 들어 transition을 활용해 간단한 애니메이션으로 구현했다.

2021.05.30 내용 추가 - 스크롤 이벤트에 throttle 적용


// Header Component

import { useState, useEffect, useRef } from 'react';
import styled from 'styled-components';

const HeaderArea = styled.div`
    position: relative;
    width: 100%;
    height: 80px;
`;

const HeaderWrap = styled.div`
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1;
    width: 100%;
    height: 80px;
    transition: 0.4s ease;
    background-color: #f00;
    &.hide {
        transform: translateY(-80px);
    }
`;

const throttle = function (callback, waitTime) {
    let timerId = null;
    return (e) => {
        if (timerId) return;
        timerId = setTimeout(() => {
            callback.call(this, e);
            timerId = null;
        }, waitTime);
    };
};

const Header = () => {
    const [hide, setHide] = useState(false);
    const [pageY, setPageY] = useState(0);
    const documentRef = useRef(document);

    const handleScroll = () => {
        const { pageYOffset } = window;
        const deltaY = pageYOffset - pageY;
        const hide = pageYOffset !== 0 && deltaY >= 0;
        setHide(hide);
        setPageY(pageYOffset);
    };

    const throttleScroll = throttle(handleScroll, 50);

    useEffect(() => {
        documentRef.current.addEventListener('scroll', throttleScroll);
        return () => documentRef.current.removeEventListener('scroll', throttleScroll);
    }, [pageY]);

    return (
        <HeaderArea>
            <HeaderWrap className={hide && 'hide'}>Header Contents ...</HeaderWrap>
        </HeaderArea>
    );
};

export default Header;
post-custom-banner

4개의 댓글

comment-user-thumbnail
2021년 5월 18일

deltaY >= 0; 해주는 이유가 궁금한데 왜 주신건지 알 수 있을까욥?

1개의 답글
comment-user-thumbnail
2021년 7월 28일

안녕하세요. 잘 가져다 썼습니다. 감사말씀 드리고 싶습니다. 정말 감사드려요.

답글 달기
comment-user-thumbnail
2022년 4월 14일

안녕하세요 코드 남겨주신 덕분에 많은 도움이 되었습니다 진짜 감사드려요!!😊

답글 달기