- Frederick Philips Brooks
Mythical Man-Month 저자
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">
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
</head>
<body class="img01 bg01 font10">
<header id="header">
<h1>Javascript parallax Effect01</h1>
<p>패럴랙스 이펙트 - 메뉴 효과</p>
<ul>
<li class="active"><a href="parallax01.html">1</a></li>
<li><a href="parallax01.html">2</a></li>
<li><a href="parallax01.html">3</a></li>
<li><a href="parallax01.html">4</a></li>
<li><a href="parallax01.html">5</a></li>
<li><a href="parallax01.html">6</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>
<main id="main">
<div class="parallax__wrap">
<section id="section1" class="parallax__item">
<span class="parallax_item_num">01</span>
<h2 class="prallax_item_title">Section1</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_item_desc">결과도 중요하지만, 고정을 더 중요하게 생각한다.</p>
</section>
<!-- //section1 -->
<section id="section2" class="parallax__item">
<span class="parallax_item_num">02</span>
<h2 class="prallax_item_title">Section2</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_item_desc">산다는것 그것은 치열한 전투이다.</p>
</section>
<!-- //section2 -->
<section id="section3" class="parallax__item">
<span class="parallax_item_num">03</span>
<h2 class="prallax_item_title">Section3</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_item_desc">언제나 현재에 집중할수 있다면 행복할것이다.</p>
</section>
<!-- //section3 -->
<section id="section4" class="parallax__item">
<span class="parallax_item_num">04</span>
<h2 class="prallax_item_title">Section4</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_item_desc">고통이 남기고 간 뒤를 보라! 고난이 지나면 반드시 기쁨이 스며든다.</p>
</section>
<!-- //section4 -->
<section id="section5" class="parallax__item">
<span class="parallax_item_num">05</span>
<h2 class="prallax_item_title">Section5</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_item_desc">행복한 삶을 살기위해 필요한 것은 거의 없다. </p>
</section>
<!-- //section5 -->
<section id="section6" class="parallax__item">
<span class="parallax_item_num">06</span>
<h2 class="prallax_item_title">Section6</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_item_desc">좋은 성과를 얻으려면 한 걸음 한 걸음이 힘차고 충실하지 않으면 안 된다</p>
</section>
<!-- //section6 -->
<section id="section7" class="parallax__item">
<span class="parallax_item_num">07</span>
<h2 class="prallax_item_title">Section7</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_item_desc">평생 살 것처럼 꿈을 꾸어라.그리고 내일 죽을 것처럼 오늘을 살아라.</p>
</section>
<!-- //section7 -->
<section id="section8" class="parallax__item">
<span class="parallax_item_num">08</span>
<h2 class="prallax_item_title">Section8</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_item_desc">꿈을 계속 간직하고 있으면 반드시 실현할 때가 온다. </p>
</section>
<!-- //section8 -->
<section id="section9" class="parallax__item">
<span class="parallax_item_num">09</span>
<h2 class="prallax_item_title">Section9</h2>
<figure class="prallax_item_imgWrap">
<div class="parallax_item-img"></div>
</figure>
<p class="prallax_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:ture403@gmail.com">ture403@gmail.com</a>
</footer>
</html>
css 코드입니다.
/* header */
#header {
position: absolute;
left: 20px;
top: 20px;
}
#header h1 {
margin-bottom: 0.3em;
}
#header ul {
margin-top: 0.6em;
}
#header li {
display: inline-block;
}
#header li a {
color: #fff;
border: 1px solid #fff;
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
border-radius: 50%;
text-align: center;
}
#header li.active a {
background: #fff;
color: #000;
}
/* footer */
#footer {
text-align: center;
padding: 100px 0;
}
#footer a {
color: #fff;
font-size: 14px;
}
#footer a:hover {
text-decoration: underline;
}
/* prallax_nav */
.parallax__nav {
position: fixed;
right: 20px;
top: 20px;
z-index: 2000;
background-color: rgba(0, 0, 0, 0.4);
padding: 20px 30px;
border-radius: 50px;
}
.parallax__nav li {
display: inline;
margin: 0 5px;
}
.parallax__nav li a{
display: inline-block;
padding: 5px 20px;
text-align: center;
line-height: 30px;
color: #fff;
}
.parallax__nav li.active a{
background-color: #fff;
color: #000;
border-radius: 20px;
box-sizing: content-box;
}
/* parallax_wrap */
.parallax__wrap {
max-width: 1600px;
width: 98%;
margin: 0 auto;
/* background-color: rgba(0, 0, 0, 0.4); */
}
.parallax__item {
width: 1000px;
max-width: 70vw;
margin: 30vw auto;
/* background-color: rgba(1, 0, 0, 0.4); */
margin-right: 0;
position: relative;
padding-top: 8vw;
}
.parallax__item:nth-child(even){
margin-left: 0;
text-align: right;
}
.parallax_item_num {
font-size: 35vw;
font-family:'Lato';
font-weight: 100;
position: absolute;
left: -5vw;
top: -16vw;
opacity: 0.07;
z-index: -2;
}
.parallax__item:nth-child(even) .parallax_item_num {
left: auto;
right: -5vw;
}
.prallax_item_title {
font-weight: bold;
letter-spacing: 3px;
}
.prallax_item_imgWrap {
width: 100%;
padding-bottom: 56.25%;
position: relative;
z-index: -1;
}
.parallax_item-img {
position: absolute;
left: 0;
top: 0;
background-image: url(../img/sliderEffect05-1-min.jpg);
background-size: cover;
width: 100%;
height: 100%;
filter: saturate(0);
transition: all 1s;
}
.parallax__item:nth-child(1) .parallax_item-img {
background-image: url(../img/sliderEffect01-min.jpg);
}
.parallax__item:nth-child(2) .parallax_item-img {
background-image: url(../img/sliderEffect02-1-min.jpg);
}
.parallax__item:nth-child(3) .parallax_item-img {
background-image: url(../img/sliderEffect03-1-min.jpg);
}
.parallax__item:nth-child(4) .parallax_item-img {
background-image: url(../img/sliderEffec0t4-1-min.jpg);
}
.parallax__item:nth-child(5) .parallax_item-img {
background-image: url(../img/sliderEffect05-1-min.jpg);
}
.parallax__item:nth-child(6) .parallax_item-img {
background-image: url(../img/sliderEffect06-1-min.jpg);
}
.parallax__item:nth-child(7) .parallax_item-img {
background-image: url(../img/sliderEffect07-1-min.jpg);
}
.parallax__item:nth-child(8) .parallax_item-img {
background-image: url(../img/sliderEffect08-1-min.jpg);
}
.parallax__item:nth-child(9) .parallax_item-img {
background-image: url(../img/sliderEffect09-1-min.jpg);
}
.prallax_item_desc {
font-size: 3vw;
line-height: 1.4;
margin-top: -5vw;
margin-left: -4vw;
word-break: keep-all;
}
.parallax__item:nth-child(even) .prallax_item_desc {
margin-left: auto;
margin-right: -4vw;
}
.parallax_info {
position: fixed;
left: 20px;
bottom: 20px;
background-color: rgba(0, 0, 0, 0.6);
color: #fff;
border-radius: 10px;
font-size: 14px;
line-height: 1.4;
}
@media(max-width:1200px){
.parallax__nav {
padding: 10px;
background-color: rgba(0, 0, 0, 0.9);
right: 10px;
left: 10px;
top: 10px;
border-radius: 5px;
text-align: center;
}
.parallax__nav li {
margin: 2px;
}
.parallax__nav li a {
font-size: 12px;
padding: 0px 14px;
}
}
JS코드입니다.
// 선언자
const scrollSpan =document.querySelector(".scroll span");
window.addEventListener("scroll",()=>{
let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
scrollSpan.innerText = parseInt(scrollTop);
for(let i=1; i<=9; i++){
document.querySelector(".info .offset"+i).innerText = document.getElementById("section"+i).offsetTop;
}
document.querySelectorAll(".parallax__item").forEach((el,index)=>{
// el.querySelector("span").innerText = document.getElementById(`section${index+1}`).offsetTop;
if(scrollTop >= el.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((el)=>{
el.addEventListener("click",(e)=>{
e.preventDefault();
document.querySelector("li.getAttribute('href')").scrollIntoView({
behavior : "smooth"
})
})
})
// document.querySelector(".info .offset1").innerText = document.getElementById("section1").offsetTop;
자바스크립트
- scroll span 을 선언하고 변수에 저장했습니다.
- 스크롤 했을때 안에서 동작하는 이벤트를 작성하는 방법입니다.
- 그안에 변수 scrollTop 안에 scrollY에 대한 값을 넣어주었습니다. scrollSpan안에 scrollTop값을 넣어주었습니다.
- 화면 왼쪽 밑에 값이 변경되는걸 보실수 있습니다.
- 그리고 info 안에 있는 ul li 안에 값을 넣읗겁니다. for문을 돌려서 .info offset값 안에 메인에 있는 id가 section의offsetTop값을 넣어주었습니다.
- section calss은 parallax__item에 forEach를 써서 그안에 scrollTop값과 parallax__item의offsetTop 값이 같거나 크면 그안에서 parallax__nav li를 배열안에 돌려서 class에 active가 된걸 제거합니다.
- parallax__nav li:nth-child(index+1)에 active를 붙입니다.
- parallax__nav li a를 배열로 돌려서 그안에 click 이벤트를 주었습니다. 그리도 e.preventDefault() 설정해서 1번 클릭되면 다시 클릭되지 않게 합니다.
- 그리고 그안에 화면을 부드럽게 하기 위해서 scrollIntroView를 주어서 애니메이션 효과를 주었습니다.
숙제
// for문
// for(let i=1; i<=9; i++){
// document.querySelector(".info .offset"+i).innerText = document.getElementById("section"+i).offsetTop;
// }
//forEach문
// document.querySelectorAll(".info ul li").forEach((el,index)=>{
// el.querySelector("span").innerText = document.getElementById("section"+(index+1)).offsetTop;
// })
// for of 문
// const a = document.querySelectorAll(".info ul li");
// let infoIndex = 0;
// for(let el of a){
// infoIndex++;
// el.querySelector("span").innerText = document.getElementById("section"+infoIndex).offsetTop;
// }
//for in 문
// const a = document.querySelectorAll(".info ul li");
// let infoIndex = 0;
// for (let i in a) {
// if (a.hasOwnProperty(i)) {
// infoIndex++;
// a[i].querySelector("span").innerText = document.getElementById("section" + infoIndex).offsetTop;
// }
// }
- 첫번쨰는 for문 입니다. i값을 이용해서 offset 에 i 추가하고 section에 i를 추가해주었습니다.
- 2번쨰는 forEach 문입니다. .info ul li를 forEach를 돌려서 요소에다가 span을 찾아서 그안에 section에 index+1을 해주었습니다.
- 3번쨰는 for of문 입니다. 저는 일단 가져와서 그걸 작업하기 쉽게 배열로 만들었습니다.
- 그리고 index값이 없으므로 변수 infoIndex에 0을 넣었습니다. 그리고 el에 span을 찾아서 안에서 section에 infoIndex 값을 넣어주었습니다.
- 4번쨰 for in 문 입니다. 먼저 변수안에 of문과 같이 지정했습니다.
- 그리고 hasOwnProperty로 검사를 한다음 ture면 infoIndex를 증가시키고 그다음 a[i]에 span을 찾은다음 똑같이 section에 offsetTop값을 넣었습니다.