JAVASCRIPT

패럴렉스 이펙트 메뉴 효과를 알아 봅시다.

이미사용 2023. 4. 18. 22:42
명언
-
728x90
반응형

※패럴렉스 이펙트 메뉴 효과

 

전체소스 보러가기

css 보러가기

 

HTML

    <nav class="Parallax__nav">
        <ul>
            <li class="active"><a href="#section1">메뉴1</a></li>
            <li><a href="#section2">메뉴2</a></li>
            <li><a href="#section3">메뉴3</a></li>
            <li><a href="#section4">메뉴4</a></li>
            <li><a href="#section5">메뉴5</a></li>
            <li><a href="#section6">메뉴6</a></li>
            <li><a href="#section7">메뉴7</a></li>
            <li><a href="#section8">메뉴8</a></li>
            <li><a href="#section9">메뉴9</a></li>
        </ul>
    </nav>
    <main id="main">
        <div class="Parallax__wrap">
            <section id="section1" class="Parallax__item">
                <span class="Parallax__item__num">01</span>
                <h2 class="Parallax__item__title">section1</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">삶은 탐구하는 모험이다.</p>
            </section>
            <!-- //section1 -->

            <section id="section2" class="Parallax__item">
                <span class="Parallax__item__num">02</span>
                <h2 class="Parallax__item__title">section2</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">오늘 당신이 할 수 있는 최선의 일을 하라.</p>
            </section>
            <!-- //section2 -->

            <section id="section3" class="Parallax__item">
                <span class="Parallax__item__num">03</span>
                <h2 class="Parallax__item__title">section3</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">비난은 쓸모없는 짓이다.</p>
            </section>
            <!-- //section3 -->
            
            <section id="section4" class="Parallax__item">
                <span class="Parallax__item__num">04</span>
                <h2 class="Parallax__item__title">section4</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">우리의 삶은 우리가 생각하는 것처럼 빠르지 않고, 우리가 생각하는 것보다 짧다.</p>
            </section>
            <!-- //section4 -->

            <section id="section5" class="Parallax__item">
                <span class="Parallax__item__num">05</span>
                <h2 class="Parallax__item__title">section5</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">머리로 생각하는 것보다는 마음으로 생각하고 행동하라.</p>
            </section>
            <!-- //section5 -->
            
            <section id="section6" class="Parallax__item">
                <span class="Parallax__item__num">06</span>
                <h2 class="Parallax__item__title">section6</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">인생은 문제다. 그것을 해결해 나가는 과정에서 삶이 만들어진다.</p>
            </section>
            <!-- //section6 -->

            <section id="section7" class="Parallax__item">
                <span class="Parallax__item__num">07</span>
                <h2 class="Parallax__item__title">section7</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">성공은 단순히 실패를 거듭하고 계속하는 것이다.</p>
            </section>
            <!-- //section7 -->
            
            <section id="section8" class="Parallax__item">
                <span class="Parallax__item__num">08</span>
                <h2 class="Parallax__item__title">section8</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">기회는 항상 어려운 일 모습으로 찾아온다.</p>
            </section>
            <!-- //section8 -->

            <section id="section9" class="Parallax__item">
                <span class="Parallax__item__num">09</span>
                <h2 class="Parallax__item__title">section9</h2>
                <figure class="Parallax__item__imgWrap">
                    <div class="Parallax__item__img"></div>
                </figure>
                <p class="Parallax__item__desc">목표를 지닌 사람들만이 인생에서 진정으로 살아간다.</p>
            </section>
            <!-- //section9-->
        </div>

    </main>
    <!-- main -->
    <aside class="Parallax__info">
        <div class="scroll">scrollTop : <span>0</span>px</div>
        <div class="info">
            <ul>
                <li>#section1 offset() : <span class="offset1">0</span>px</li>
                <li>#section2 offset() : <span class="offset2">0</span>px</li>
                <li>#section3 offset() : <span class="offset3">0</span>px</li>
                <li>#section4 offset() : <span class="offset4">0</span>px</li>
                <li>#section5 offset() : <span class="offset5">0</span>px</li>
                <li>#section6 offset() : <span class="offset6">0</span>px</li>
                <li>#section7 offset() : <span class="offset7">0</span>px</li>
                <li>#section8 offset() : <span class="offset8">0</span>px</li>
                <li>#section9 offset() : <span class="offset9">0</span>px</li>
            </ul>
        </div>
    </aside>

    <footer>
        <a href="mailto:ghkddn132@naver.com">ghkddn132@naver.com</a>
    </footer>
    <!-- footer -->

 

JAVASCRIPT

        window.addEventListener("scroll", () => {
            let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
            
            // info
            document.querySelector(".scroll span").innerText = parseInt(scrollTop);

·우선  window.addEventListener("scroll",를 통해 윈도우에 스크롤을 했을때 이벤트가 함수가 실행 되도록 하였습니다.

·변수를 하나 만들어 Y값을 가져오는 3개의 속성중 가져오는 값이 하나라도 있으면 저장 하도록 하였습니다.

· 그후 .scroll span에 소수점을 제외한 변수 scrollTop값을 가져 옵니다. 그럼 스크롤을 할때마다 y의값이 scroll span에 적용됩니다.

document.querySelector(".info .offset1").innerText = document.getElementById("section1").offsetTop;
document.querySelector(".info .offset2").innerText = document.getElementById("section2").offsetTop;
document.querySelector(".info .offset3").innerText = document.getElementById("section3").offsetTop;
document.querySelector(".info .offset4").innerText = document.getElementById("section4").offsetTop;
document.querySelector(".info .offset5").innerText = document.getElementById("section5").offsetTop;
document.querySelector(".info .offset6").innerText = document.getElementById("section6").offsetTop;
document.querySelector(".info .offset7").innerText = document.getElementById("section7").offsetTop;
document.querySelector(".info .offset8").innerText = document.getElementById("section8").offsetTop;
document.querySelector(".info .offset9").innerText = document.getElementById("section9").offsetTop;

˙그후 밑에 각 section이 시작하는 Y위치를 가져오기 위해 하나하나씩  넣어 주었습니다.

 

※for문으로 반복하기

          for(let i=1; i<10; i++){
              document.querySelector(".info .offset"+i).innerText = document.getElementById("section"+i).offsetTop;
          }

for문으로 1~9까지 반복하여 적용 해줍니다.

 

※forEach문으로 반복하기

            document.querySelectorAll(".info li").forEach((el, i) => {
                document.querySelector(".info .offset"+(i+1)).innerText = document.getElementById("section"+(i+1)).offsetTop;
            })

·info li를 forEach 문으로 하여 info li의 갯수만큼 반복합니다.

·el값과 i인덱스를 가져와 반복해 줍니다.

 

※for...of문으로 반복하기

            const h = document.querySelectorAll(".info li");
            let infoindex = 0;
            for(let i of h){
                infoindex++;
                i.querySelector("span").innerText = document.getElementById("section"+infoindex).offsetTop;
            }

for...of문을 사용하여 .info li 의 갯수만큼 for문을 반복하게 두고 index값을 구하기위해 0부터 시작하고 ++를 해주면서 index값이 나옵니다 .info li 에 있는 span에 section의 Y값을 저장해 주었습니다.

 

※for...in문으로 반복하기

            const h = document.querySelectorAll(".info li");
            let infoindex = 0;
            for (let i in h){
                // console.log(i)
                if(h.hasOwnProperty(i)){
                    // console.log(i)
                    infoindex++;
                    h[i].querySelector("span").innerText = document.getElementById("section" + infoindex).offsetTop;
                }
            }

for...of문과 같이 변수 를 저장해 준후 h 에있는  hasOwnProperty 을 조건문 으로 .info li 바로밑에 있는 요소들 만 가져와 그곳의 span에 각 section의 Y값을 저장해 주었습니다.

 

            document.querySelectorAll(".Parallax__item").forEach((item, index) => {
                if(scrollTop >= item.offsetTop - 2){
                    document.querySelectorAll(".Parallax__nav li").forEach((li) => {
                        li.classList.remove("active");
                    });
                    document.querySelector(".Parallax__nav li:nth-child("+(index+1)+")").classList.add("active");
                };
            });

·그후 .Parallax__item의 값들을 가져와 forEach문으로 실행한후 scrollTop=내가스크롤한값 이 Parallax__item 고정되어 있는 메뉴의 높이 값 -2 보다 높을때 Parallax__nav li 에있는 active를 지워준후 그스크롤이 위치한 곳의 메뉴에 클라스 active를 넣어줍니다.

        document.querySelectorAll(".Parallax__nav li a").forEach(li => {
            li.addEventListener("click", (e) => {
                e.preventDefault();
                document.querySelector(li.getAttribute("href")).scrollIntoView({
                    behavior: "smooth"
                });
            });
        });

·메뉴를 클릭 했을때 그 해당 배경으로 갈수 있도록 만들어준 것입니다.

·이때 기본 적인 효과를 preventDefault()를 통해 없애주고 클릭한 장소의 href값이 일치하는 배경과 메뉴가 보이도록 해주었습니다.

 

pageYOffset 현재 문서에서 수직 방향으로 스크롤된 양을 나타내는 JavaScript 프로퍼티입니다. 이 값은 브라우저 창의 스크롤 위치에 따라 계속해서 변경됩니다.
scrollY 현재 문서가 수직 방향으로 스크롤된 거리를 나타내는 JavaScript의 속성(property) 중 하나입니다. 이 속성은 브라우저 창 상단에서 문서의 최상단까지 스크롤된 거리를 픽셀 단위로 반환합니다.
documentElement.scrollTop 문서의 최상위 엘리먼트, 즉 <html> 요소의 스크롤된 수직 거리를 나타내는 속성입니다.
offsetTop 요소의 상위 요소(부모 요소)의 상단 경계(border-top 라인)와의 거리를 나타내는 속성입니다.
preventDefault() JavaScript 이벤트 객체의 메소드 중 하나입니다. 이 메소드를 호출하면 이벤트의 기본 동작을 취소할 수 있습니다.
scrollIntoView() 메소드는 해당 요소가 보이도록 스크롤을 조정하는 JavaScript 메소드입니다. 이 메소드는 호출된 요소가 현재 뷰포트(viewport) 안에 있지 않으면 스크롤을 조정하여 요소가 보이도록 합니다.
behavior: "smooth" scrollIntoView() 메소드에서 스크롤 동작에 적용되는 옵션 중 하나입니다. 이 옵션을 사용하면 부드러운 스크롤 효과를 적용할 수 있습니다.