한번씩 읽고 가세요.
“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”
- Frederick Philips Brooks
Mythical Man-Month 저자
패럴럭스 효과
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>패럴럭스</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/parallax.css">
</head>
<body class="bg02 img02 font08">
<header id="header">
<h1>Javasrcipt parallax Effect01</h1>
<p>패럴럭스 이펙트 : 메뉴효과</p>
<ul>
<li class="active"><a href="parallax01.html">1</a></li>
<li><a href="parallax02.html">2</a></li>
<li><a href="parallax03.html">3</a></li>
<li><a href="parallax04.html">4</a></li>
<li><a href="parallax05.html">5</a></li>
<li><a href="parallax06.html">6</a></li>
<li><a href="parallax07.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>
<!-- parallax__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">Section1</h2>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc">결과도 중요하지만, 과정을 더 중요하게 생각한다.</p>
</section>
<!--//section-->
<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>
<!--//section-->
<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><!--//section-->
<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">삶은 짧고 예술은 길다.
</section>
<!--//section-->
<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>
<!--//section-->
<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>
<!--//section-->
<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>
<!--//section-->
<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>
<!--//section-->
<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>
<!--//section-->
</div>
</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 id="footer">
<a href="mailto:esansi@naver.com">esansi@naver.com</a>
</footer>
이번엔 스크롤 이벤트와 offsettop값을 활용하여 페이지를 만들어보았습니다.
window.addEventListener("scroll", () => {
let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
//info
document.querySelector(".scroll span").innerText = parseInt(scrollTop);
//for문
for(let i = 1; i <= 9 ; i++){
document.querySelector(`.info .offset${i}`).innerText = document.getElementById(`section${i}`).offsetTop;
//각 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"
})
})
})
});
window에 addEventListener를 사용해 scroll 효과를 줍니다.
그 안에 변수 scrollTop를 생성합니다. scrollTop은 offset값을 가져오기 위해 3가지 방법 을 사용할수있습니다.
window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
이렇게 세가지가 사용가능합니다.
for(let i = 1; i <= 9 ; i++){
document.querySelector(`.info .offset${i}`).innerText = document.getElementById(`section${i}`).offsetTop;
}
for문을 사용해 info offset{i}에 document.getElementById(section${i}).offsetTop를 사용하여 id가 section${i}인 요소의 offsetTop 값을 가져옵니다.
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__item")에forEach를 사용합니다. 만약 scrollTop 값이 item.offsetTop-2보다 크거나 작을 경우 .parallax__nav li의 li들에게 classList.remove로 active값을 삭제시켜줍니다.
document.querySelector(".parallax__nav li:nth-child(" + (index + 1) + ")").classList.add("active")
li 자식중 index+1값에 만족하는 li 에게 active를 부여합니다.
그렇게 하면 스크롤 위치 값이 이미지의 위치값보다 커질 경우 nav li에 active가 활성화 됩니다.
document.querySelectorAll(".parallax__nav li a").forEach((li) => {
li.addEventListener("click", (e) => {
e.preventDefault();
document.querySelector(li.getAttribute("href")).scrollIntoView({
behavior: "smooth"
마지막으로 .parallax__nav li a 를 forEach 문을 활용해 li라고 지명시켜주고 li에 클릭 이벤트를 줍니다.
preventDefault()를 사용하고 이벤트를 중지하고
li.getAttribute("href")에
scrollIntoView() 메소드는 DOM 요소를 스크롤하여 화면에 보이도록 하는 효과를 주고 smooth 를 주어 부드럽게 넘어가게 해줍니다.
미션
forEach
document.querySelectorAll(".info ul li").forEach((el,index)=>{
el.querySelector("span").innerText = document.getElementById(`section${index+1}`).offsetTop;
})
for in
const arr = document.querySelectorAll(".info ul li")
for(let index in arr){
const el = arr[index];
el.querySelector("span").innerText = document.getElementById(`section${parseInt(index)+1}`).offsetTop;
}
for of
const arr = document.querySelectorAll(".info ul li");
let index = 0;
for (const el of arr) {
el.querySelector("span").innerText = document.getElementById(`section${index + 1}`).offsetTop;
index++;
}