본문 바로가기
Effect/ParallaxEffect

[자바스크립트 응용] 페럴렉스 효과02 / 스크롤변화에 따른 효과 적용하기

by 코린이 박원장👶 2022. 9. 12.

패럴랙스 효과 02

패럴랙스 스크롤링은 사용자가 마우스를 스크롤할 때, 원거리에 있는 배경 이미지는 느리게 움직이게 하고, 근거리에 있는 사물 이미지는 빠르게 움직이도록 함으로써 입체감을 느낄 수 있게 만든 디자인 기법입니다. 오늘은 저번시간에 이어서 사이드바 메뉴로 구성하는 방식에 대해 알아보겠습니다.


▶ 저번시간과 원리는 별반 다를게 없습니다. 'parallax__info span'에 현재 scrollTop값을 입력되게 해주고, 'scrollTop >= 각 섹션 offsetTop' 일때 해당되는 섹션의 메뉴버튼에 active클래스를 붙여줍니다.
또, 메뉴버튼에 해당되는 a링크에 preventDefault를 부여해서 a태그 고유기능은 막고 scrollIntoView를 주어서 다른 스크롤이동 효과를 부여해줍니다.

JS 소스

document.querySelectorAll("#parallax__dot a").forEach((el) => {
    el.addEventListener("click", (e) => {
        e.preventDefault();

        // window.scroll(0, 1000);
        // window.scroll({ left: 0, top: 2000 });
        // window.scroll({ left: 0, top: 2000, behavior: "smooth" });

        // window.scrollTo(0, 1000);            //To --> 절대위치
        // window.scrollTo({ left: 0, top: 2000 });
        // window.scrollTo({ left: 0, top: 2000, behavior: "smooth" });

        // window.scrollBy(0, 1000); //by --> 현재위치 기준
        // window.scrollBy({ left: 0, top: 2000 });
        // window.scrollBy({ left: 0, top: 2000, behavior: "smooth" });

        document.querySelector(el.getAttribute("href")).scrollIntoView({ behavior: "smooth" });
    });
});

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

    document.querySelector("#parallax__info span").innerText = Math.floor(scrollTop);

    document.querySelectorAll(".content__item").forEach((e, i) => {
        if (scrollTop >= e.offsetTop - window.innerHeight / 2) {
            document.querySelectorAll("#parallax__dot li").forEach((li) => {
                li.classList.remove("active");
            });
            document.querySelector("#parallax__dot li:nth-child(" + (i + 1) + ")").classList.add("active");
        }
    });
});

■ 핵심 파헤치기🪓

✔ preventDefault

기본(default) 막다(prevent).
원래 a태그나 submit태그는 누르게 되면 href를 통해 이동하거나 창이 새로고침되어 실행되는 기능을 가지고있습니다. 이 메서드는 이러한 태그의 기본 이벤트(동작)을 막는 기능을 합니다.
이 속성은 이벤트 메서드 입니다. 밑에 간단한 예시를 만들어 봤으니 눌러보시고 파악해보세요.

메서드 미적용_ 눌러보세요 (구글로 새창이동)
메서드 적용_ 눌러보세요

<a href="http://www.google.com" target="_blank">메서드 미적용</a>
<a href="http://www.google.com" target="_blank" class="t_ablock">메서드 적용</a>

//스크립트
const ablock = document.querySelector(".t_ablock");
ablock.addEventListener("click", el => {
     el.preventDefault();
     alert("알람문구")
});

✔ getAttribute

선택한 요소의 특정 속성값을 가져옵니다.

문법 : element.getAttribute( 'attributename' )

여기서는 a링크의 href값을 가져오는게 되겠군요. 메뉴1의 href를 예시로 들자면 #section1을 가져오겠네요

✔ documentElement.scrollTop

let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;

스크롤바의 현재 위치를 가져오는 방법인데요. 모든 문법이 현재위치를 가져올 수 있습니다. 다만 IE브라우저의 경우 window.scrollY의 프로퍼티가 존재하지 않습니다. 이 경우 document.documentElement.scrollTop;를 사용합니다. 그래서 호환을 위해서 위와 같이 문법을 사용한 것입니다. 저렇게 사용하면 IE 및 대부분 브라우저에서 현재 스크롤위치를 반환하게 됩니다.

✔ scrollIntoView

이 메서드는 화면의 특정 위치로 이동시켜주는 함수입니다. 요소 기반이므로 특정 요소를 기준으로 스크롤을 이동시킵니다. 여기서는 a링크의 href를 요소로 지정해주었으므로 지정한 href요소로 이동을 시켜주겠네요. 그리고 3개의 문법(아무것도 사용하지 않고 그냥 사용 / 불린을 사용 / 옵션값 사용)중 옵션값을 사용하는 문법을 이용해줍니다. behavior는 전환방식을 설정해줄 수 있는데 여기서는 'smooth'를 사용하여 부드럽게 이동하는 설정을 해줍니다.

- true : 요소의 상단 기준으로 스크롤 이동
- false : 요소의 하단 기준으로 스크롤 이동
- behavior : 전환 방식(애니메이션) 정의함 : auto || smooth
- block : 수직 정렬 : strat || center || end || nearest
- inline : 수평 정렬 : strat || center || end || nearest

✔ Math.floor()

소수점 이하를 버림하는 메서드입니다. 참고로 음수(-)는 편하게 생각하면 소숫점앞자리 숫자에서 -1을 하세요.(이해못하는 문과는 외웁니다...)

- 내 멋대로 원리 이해하기 (믿거나 말거나)
5.5라는 숫자에서 소숫점이하를 버림하면 5가 반환이됩니다. 여기까지는 이해가 쉬운데요. 소숫점이하를 버리게되면 반환되는 값는 원래 값보다 작아지잖아요? 그래서 음수의 경우도 반환되는 숫잔 원래 숫자보다 작아지게 되는거죠. 그래서 -3.4라는 숫자가 버림을 받게 되면 -3이아니라 -3.4보다 작은 -4가 반환되는 겁니다.

■ 코드 내멋대로 풀어헤치기👕

점점 어려워지고 있기도하고 해서, 오늘도 역시 제가 이해한대로 그냥 풀어볼까합니다. 언제든 틀린점이 있다면 지적은 감사합니다.😙

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

☞ 사이드바 메뉴 클릭시 이동하는 스크립트입니다.
1. 사이드바 메뉴(#parallax__dot a)는 여러개이므로 다중선택자로 여러개를 선택한 뒤 el로 뽑아냅니다.

2. 이후 버튼을 클릭했을 때 preventDefault로 a태그 고유기능을 막아줍니다.

3. document.querySelector(el.getAttribute("href")).scrollIntoView({ behavior: "smooth" });

Click 상세설명이미지
window.addEventListener("scroll", () => {
    let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;

    document.querySelector("#parallax__info span").innerText = Math.floor(scrollTop);

    document.querySelectorAll(".content__item").forEach((e, i) => {
        if (scrollTop >= e.offsetTop - window.innerHeight / 2) {
            document.querySelectorAll("#parallax__dot li").forEach((li) => {
                li.classList.remove("active");
            });
            document.querySelector("#parallax__dot li:nth-child(" + (i + 1) + ")").classList.add("active");
        }
    });
});

☞ 패럴렉스에 관련된 스크립트입니다.
1. 변수 scrollTop에 현재 스크롤 위치값을 저장시킵니다.

2. 현재 스크롤 위치값을 소숫점이하를 버림하여 '#parallax__info span'에 입력합니다.

3. 조건 : 현재 스크롤 위치값이 요소의 y축값에서 브라우저의 높이값/2를 뺀 값보다 크거나 같은 경우 실행문을 실행합니다.
   [브라우저의 높이값 1/2를 빼는 이유?]

Click 상세설명이미지

※ 꼭 브라우저 높이값 1/2를 빼야하는 건 아닙니다. 300, 500 등 수치를 입력하여도 무관합니다. 다만, 이러한 고정값은 반응형에서 불리하게 작용할 수 있습니다.
저는 개인의 방식과 취향을 존중합니다.


4. 조건에 해당하면 사이드바 메뉴(#parallax__dot li)들의 .active를 제거하고 해당 섹션에만 .active를 붙여 활성화효과를 부여합니다.
  · nth-child에 index값을 그냥 적용하지 않고 +1을 한 이유?
    첫번째 요소는 0으로 반환되는 이유때문에 +1을 해서 순서를 맞춰주기 위함입니다.

- 끝.이.에.요 -

728x90

댓글


HTML이미지
HTML이미지

JAVASCRIPT

자세히 보기
HTML이미지