JAVASCRIPT

패럴렉스 효과 만들기 !

Kim do hyun 2023. 4. 18. 18:17
728x90
반응형

패럴렉스 효과

 

 

 

 

HTML

<!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>패럴랙스 이펙트01</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/parallax.css">
</head>
<body class="img01 bg01 Eulyoo">
    <header id="header">
        <h1>Javascript Parallax Effect01</h1>
        <p>패럴랙스 이펙트 : 메뉴 효과</p>
        <ul>
            <li class="active"><a href="parallaxEffect01.html">1</a></li>
            <li><a href="parallaxEffect02.html">2</a></li>
            <li><a href="parallaxEffect03.html">3</a></li>
            <li><a href="parallaxEffect04.html">4</a></li>
            <li><a href="parallaxEffect05.html">5</a></li>
            <li><a href="parallaxEffect06.html">5</a></li>
            <li><a href="parallaxEffect07.html">5</a></li>
        </ul>
    </header>
    <!-- header -->

    <nav class="parallax__nav">
        <ul>
            <li class="active"><a href="#section1">메뉴1</a></li>  <!-- li*9>a[href="#section$"]{메뉴$} -->
            <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">하루에 3시간을 걸으면 7년 후에 지구를 한바퀴 돌 수 있다.</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">1퍼센트의 가능성, 그것이 나의 길이다. </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*9{#section$ offset() : }>span.offset${px} -->
                <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>
    <!--//parallax__info-->

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

HTML 설명

패럴랙스 이펙트를 만들기 위한 html 코드입니다.

JAVSCRIPT

<script>
    window.addEventListener("scroll", () => {
        let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;

        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");
            }
        });

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

        // info
        document.querySelector(".scroll span").innerText = parseInt(scrollTop);


        // 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;
    });


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

    //forEach
    // document.querySelectorAll('.info li').forEach((el, i) => {
    //     document.querySelector(".info .offset"+(i+1)).innerText = document.getElementById("section"+(i+1)).offsetTop;
    // });
    //for in
    // for(let i in document.querySelectorAll(".info li")){
    //     document.querySelector(".info .offset"+(parseInt(i)+1)).innerText = document.getElementById("section"+(parseInt(i)+1)).offsetTop;
    // }
    //for of
    for (const [i, el] of document.querySelectorAll(".info li span").entries()){
        el.innerHTML = document.getElementById("section"+(parseInt(i)+1)).offsetTop;
    }
</script>

코드 설명

우선, window.addEventListener("scroll", () => {...} 부분에서는 스크롤 이벤트를 감지하고 해당 이벤트가 발생할 때마다 콜백 함수가 실행됩니다.

그리고 let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop; 코드에서는 현재 스크롤바가 위치한 높이 값을 가져옵니다. 이 값은 window.pageYOffset 또는 window.scrollY 또는 document.documentElement.scrollTop 중 하나의 값이 됩니다.

그 다음 document.querySelectorAll(".parallax__item").forEach((item, index) => {...} 부분에서는 각각의 .parallax__item 요소를 순회하며 현재 스크롤 위치를 기준으로 해당 요소들의 위치를 판단하고 .parallax__nav li 요소 중에서 활성화된 클래스인 active를 제거하고, 현재 스크롤 위치를 기준으로 활성화될 요소를 결정합니다. 그리고 document.querySelector(".parallax__nav li:nth-child("+(index+1)+")").classList.add("active"); 코드에서는 결정된 활성화될 요소에 active 클래스를 추가합니다.

document.querySelectorAll(".parallax__nav li a").forEach(li => {...} 부분에서는 .parallax__nav li 요소들에 이벤트를 바인딩합니다. 각각의 요소가 클릭되면 해당 요소의 href 속성 값을 이용하여 해당 위치로 스크롤 이동합니다.

마지막으로 document.querySelector(".scroll span").innerText = parseInt(scrollTop); 코드에서는 현재 스크롤 위치를 .scroll 요소 안에 있는 span 요소에 출력합니다.

주석 처리된 코드에서는 각각의 #section1, #section2, ..., #section9 요소의 위치를 출력하기 위한 코드가 포함되어 있습니다. 하지만 해당 부분은 주석 처리되어 있으므로 현재 코드에서는 동작하지 않습니다.

for문

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

for문을 이용하여 좌표값을 넣어주는 방법입니다.

i값에 1부터 시작하여 9까지 반복되게 만들며 .info .offset과 section에 반복되는 값인 i값을 더해 좌표값을 넣어줍니다.

forEach문

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

for문을 forEach로 변경 해보았습니다.

인자 값이 0부터 시작되기에 (i+1)을 넣어서 1부터 차례대로 늘어나게 만들어 주었습니다.

for in문

//for in
for(let i in document.querySelectorAll(".info li")){
    document.querySelector(".info .offset"+(parseInt(i)+1)).innerText = document.getElementById("section"+(parseInt(i)+1)).offsetTop;
}

for in문은 배열의 키값을 반환 하지만 숫자가 아니라 문자열을 반환 하기에 문자열을 숫자로 반환 해주는 parseInt를 이용하여 숫자로 반환 해줍니다.

for of문

//for of
for (const [i, el] of document.querySelectorAll(".info li span").entries()){
    el.innerHTML = document.getElementById("section"+(parseInt(i)+1)).offsetTop;
}

for of문은 요소를 가져오기에 직접적으로 span태그를 추가로 입력 해주었습니다.

entries()는 객체를 배열 형태로 반환 해준다고 이해 하였습니다. 이걸 사용하여 배열의 키값을 구해줍니다.