JS/vanilla로 스티키 스티키 메뉴 구현하기

이번에는 바닐라 스크립트로 스티키 메뉴를 구현했습니다.

고정 메뉴를 구현하려면 스크롤 좌표, 메뉴 좌표 및 높이를 찾아야 합니다.

1. 현재 스크롤 좌표 구하기 scrollTop과 scrollTop()의 차이점

// 바닐라 스크립트 
let scrollPosition = document.documentElement.scrollTop;

// window.scrollY는 익스에서 안되기 때문에
// document.documentElement.scrollTop 아래처럼 할수도 있지만 그냥 이것만 쓰는게 나을듯
// let scrollPosition = window.scrollY || document.documentElement.scrollTop;

// 제이쿼리
let scrollPosition = $(window).scrollTop();

2. 요소의 최상위 위치 가져오기 getBoundingClientRect().top과 offset().top의 차이점

// 바닐라 자바스크립트 getBoundingClientRect() 사용
let categoryPosition = document.querySelector(".category_tab_wrap").getBoundingClientRect().top;

// 제이쿼리 사용 offset() 사용
let categoryPosition = $(".category_tab_wrap").offset().top;

3. Sticky 구현 시 주의 사항이 있습니다. 고정된 상태에서 메뉴가 뜨면 그만큼 여백이 생기기 때문에 고정되는 순간 버벅거린다.

따라서 메뉴를 감싸는 div에 많은 비용을 지불하고 그 안에 있는 사람에게 고정 클래스를 제공하십시오.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>카테고리 탭</title>

    <link rel="stylesheet" type="" href="http://92yeol.m/./css/reset.css">

    <style>
        .fixed{position: fixed; top: 0; left: 0; right: 0;}
        .visual{height: 500px; background-color: skyblue; margin-bottom: 50px;}
        .contenns_box{height: 500px;}

        .category_tab_wrap{height: 38px; margin: 50px;}
        .category_tab_inner{max-width: 1200px; margin: 0 auto;}
        .category_list{display: flex; justify-content: center;}
        .category_list .item + .item{margin-left: 10px;}
        .category_list .item a{display: block; padding: 10px 15px; border-radius: 50px; border: 1px solid #000; background-color: #fff;}
        .category_list .item.on a{background-color: #000; color: #fff;}
    </style>
</head>
<body>
    <div class="visual">비쥬얼</div>
    <div class="category_tab_wrap">
        <div class="category_tab_inner">
            <ul class="category_list">
                <li class="item on"><a href="javascript:;" title="한식 선택">한식</a></li>
                <li class="item"><a href="javascript:;" title="양식 선택">양식</a></li>
                <li class="item"><a href="javascript:;" title="중식 선택">중식</a></li>
                <li class="item"><a href="javascript:;" title="일식 선택">일식</a></li>
                <li class="item"><a href="javascript:;" title="기타 선택">기타</a></li>
            </ul>
        </div>
    </div>
    <div class="contenns_box" style="background-color: orange;">한식</div>
    <div class="contenns_box" style="background-color: yellow;">양식</div>
    <div class="contenns_box" style="background-color: red;">중식</div>
    <div class="contenns_box" style="background-color: blue;">일식</div>
    <div class="contenns_box" style="background-color: skyblue;">기타</div>
</body>
<script>
    const js = {
        sticky(){
            let categoryInner = document.querySelector(".category_tab_inner");
            let scrollPosition = document.documentElement.scrollTop;
            let categoryPosition = document.querySelector(".category_tab_wrap").getBoundingClientRect().top;

            if(0 >= categoryPosition){
                categoryInner.classList.add("fixed");
            }else{
                categoryInner.classList.remove("fixed");
            }
        },
        
        init(){
            window.addEventListener("scroll",js.sticky);
        }
    }
    js.init();
</script>
</html>

다음에는 카테고리에 따라 메뉴에 능동적인 효과를 주도록 하겠습니다.

기본적인 기능인데 그냥 가져와서 바닐라로 구현해 놓았으니 차이점을 알겠고 좋습니다.