※패럴렉스 이펙트 메뉴 효과
전체소스 보러가기
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() 메소드에서 스크롤 동작에 적용되는 옵션 중 하나입니다. 이 옵션을 사용하면 부드러운 스크롤 효과를 적용할 수 있습니다. |