본문 바로가기
JAVASCRIPT

패럴랙스 이펙트(Parallax Effect) : 메뉴 효과

by dongjin6539 2023. 4. 18.
728x90
반응형

패럴랙스 이펙트(Parallax Effect) : 메뉴 효과

수업 시간에 배운 내용을 복습하면서 해보겠습니다.

코드 보기(HTML, JAVASCRIPT / CSS1 / CSS2) / 완성화면

 

 

 

코드 블럭

<!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="font01">
    <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">6</a></li>
            <li><a href="parallaxEffect07.html">7</a></li>
        </ul>
    </header>
    <!-- //header -->

    <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>
    <!-- //nav -->

    <main class="main">
        <div class="parallax__wrap">
            <section id="section1" class="parallax__item">
                <span class="parallax__item__num">01</span>
                <h2 class="parallax__item__title">Section01</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">Section02</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">Section03</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">Section04</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">Section05</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">Section06</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">Section07</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">Section08</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">Section09</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>
    <!-- //parallax__info -->

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

구성

  • header 태그를 사용해서 제목과 목록을 태그를 사용해 각각 만들어줍니다.
  • nav 태그를 사용해서 메뉴 목록을 태그를 사용해서 만들어줍니다.
  • main 태그를 사용해서 구역 안에 section 태그를 사용해서 각각 알맞는 구성의 태그와 텍스트를 입력해줍니다.
  • aside 태그를 사용해서 section 태그의 좌표 값을 입력해주게끔 만들어줍니다. 

 

CSS

 

JAVASCRIPT

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

자바스크립트 구성

  • window 화면을 scroll 했을 때의 효과를 가져오기 위해서 addEventListener("scroll") 메서드를 사용해줍니다.
  • 스크롤 했을 때 높이 값을 구해주는 방법을 입력해줍니다.(방법 : window.pageYOffset || window.scrollY || document.documentElement.scrollTop)
  • // info 부분에 가서 offset을 입력할 선택자 위치를 가져와서 .innerText를 입력해서 데이터 값을 입력해줍니다.
  • 화면을 스크롤 했을 때 화면의 위치와 코드 블럭의 nav 태그 메뉴 부분의 위치가 같게 나오게 해주겠습니다. 먼저 각각 section 태그의 class 명을 가져와서 선택자를 만들고 다중이이므로 querySelectorAll을 사용하고 forEach( )를 사용해줍니다. 그리고 if문을 사용해서 보이는 화면의 높이값이 section태그의 높이값보다 높거나 같으면 메뉴 부분에 스타일 active를 classList.remove를 이용해서 지워주고 화면의 위치와 같은 메뉴 부분에 스타일 active를 classList.add를 이용해서 입력해줍니다. 
  • 다음은 메뉴 버튼을 클릭했을 때 화면의 알맞은 section으로 이동하게 해주겠습니다. 선택자로 nav 태그의 ul 태그의 li 태그의 a 태그를 만들어줍니다. 다중이이므로 forEach( )를 사용해주고 클릭했을 때의 효과를 주기 위해 addEventListener("click") 메서드를 사용해줍니다. 현재 메뉴 부분에 active 효과가 있는 것을 명시적으로 없애주기 위해 preventDefault( ) 메서드를 사용해줍니다. 다음은 선택자로 li 태그의 getAttribute( )를 사용해 a 태그의 href 속성을 가져오게 해주고 scrollintoView( )를 사용해서 호출된 요소를 사용자에게 보여주게하고 behavior: "smooth"를 입력해서 좀 더 부드럽게 요소를 호출 시켜줍니다.

 

// info 부분을 for문으로 변경
for(let i=1; i<10; i++){
    document.querySelector(`.info .offset${i}`).innerText = document.getElementById(`section${i}`).offsetTop;
};

 

// info 부분을 forEach( )로 변경
document.querySelectorAll(".info li span").forEach((e, i) => {
    e.innerHTML = document.getElementById(`section${i+1}`).offsetTop;
});

 

// info 부분을 for in 문으로 변경
const spans = document.querySelectorAll(".info li span");
    for(let i in spans){
        if(spans.hasOwnProperty(i)){
            const e = spans[i];
            e.innerText = document.getElementById(`section${parseInt(i)+1}`).offsetTop;
        }
}
  • hasOwnProperty( ) 메서드 : 객체가 특정 속성을 직접 소유하고 있는지 여부를 나타내는 불리언 값을 반환합니다.
  • parseInt( ) 함수 : 문자열 인자를 파싱하여 특정 진수(수의 진법 체계에서 기준이 되는 값)의 정수를 반환합니다.
// info 부분을 for of 문으로 변경
const spans = document.querySelectorAll(".info li span");
let i = 1;
for(let e of spans){
    e.innerHTML = document.getElementById(`section${i}`).offsetTop;
    i++;
}

 

참고

  • 속성, 메서드
속성, 메서드 설명
preventDefault( ) 어떤 이벤트를 명시적으로 처리하지 않은 경우, 해당 이벤트에 대한 사용자 에이전트의 기본 동작을 실행하지 않도록 지정합니다.
getAttribute( ) 해당 요소에 지정된 값을 반환 합니다. 만약 주어진 속성이 존재 하지 않는 다면, null 값이나 ""(빈문자열); 을 반환 할 것입니다.
scrollintoView( ) 호출된 요소가 사용자에게 표시되도록 scrollIntoView( ) 요소의 조상 컨테이너를 스크롤합니다.
offsetTop 요소의 X축 값(문서 기준)
filter 흐림 효과나 색상 변형 등 그래픽 효과를 요소에 적용합니다. 보통 필터는 이미지, 배경, 테두리 렌더링을 조정하는 데 쓰입니다.

 

728x90
반응형