ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JS / 바닐라로 sticky 스티키 메뉴 구현하기
    Web dev/JavaScript 2023. 4. 16. 23:50
    728x90
    반응형

    이번에는 바닐라스크립트로 스티키메뉴를 구현해보았다.

    스티키메뉴를 구현하려면 스크롤좌표,메뉴의 좌표, 높이등을 구해야 하는데 제이쿼리와 어떻게 다른지 알아보았다.

     

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

    // 바닐라 스크립트 
    let scrollPosition = document.documentElement.scrollTop;
    
    // window.scrollY 익스에서 안됌
    // window.pageYOffset 가능
    // 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. 스티키를 구현할 때는 주의사항이 있다. fixed를 하면서 메뉴가 띄어지면 그만큼 공백이 생겨 픽스되는 순간 뚱땅 거린다.

    그러므로 메뉴를 감싸는 div에 높이갚을 주고 fixed클래스는 그 안에 놈에게 주면 된다.

    <!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="./css/reset.css">
    
        <style>
            .fixed{position: fixed; top: 0; left: 0; right: 0;}
            .visual{height: 500px; background-color: skyblue; margin-bottom: 50px;}
            .contents_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="contents_box" style="background-color: orange;">한식</div>
        <div class="contents_box" style="background-color: yellow;">양식</div>
        <div class="contents_box" style="background-color: red;">중식</div>
        <div class="contents_box" style="background-color: blue;">일식</div>
        <div class="contents_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>

    우선 단순하게 스티키기능만 구현한거라 if문에 별다른 조건을 걸지 않았다.

    다음번에는 해당카테고리에 맞춰 메뉴에 엑티브효과를 줄 것이다.

    기본적인 기능이지만 가져다 쓰기만 하다가 바닐라로 구현해보니 차이점도 알아가고 좋다.

    728x90
    반응형

    댓글

Designed by Tistory.