반응형
js와 css로 페이지네이션, 스크롤 인터렉티브를 만들어보자!
목표 Goal💨
- 버튼으로 페이지 이동
- 스크롤로 페이지 이동
- 네비게이션 요소로 페이지 이동
- 현재 페이지 표시
- 페이지 이동시 배경화면, 이미지, 프로그래스바(Progress Bar) 부드럽게 변경(트렌지션)
Preview
👍여기 클릭
HTML
html은 간단한 태그들로 구성됩니다. 목표에서 설명한 것들을 구현하기 위한 요소들을 생성해줍니다.
- 이전, 다음 페이지로 이동하는 버튼과 Progress Bar를 작성하고, 그에 맞는 클래스 이름을 지정합니다.
- section 태그는 각 페이지별로 보여줄 내용을 포함합니다. 페이지 번호(혹은 제목), 내용, 이미지로 구성했습니다.
- ul태그는 네비게이션 역할을 하기 위해 page수(section수) 와 동일하게 만들어 줍니다.
<body>
<ul class="pointer">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="navi">
<button class="preBtn">PREV</button>
<button class="nextBtn">NEXT</button>
<div class="progressBar"></div>
<h1><span>1</span> 페이지 입니다.</h1>
</div>
<section>
<h2>page 1</h2>
<p>~~설명~~</p>
<img src="~원하는 사진~" alt="">
</section>
<section>
<h2>page 2</h2>
<p>~~설명~~</p>
<img src="~원하는 사진~" alt="">
</section>
<section>
<h2>page 3</h2>
<p>~~설명~~</p>
<img src="~원하는 사진~" alt="">
</section>
<section>
<h2>page 4</h2>
<p>~~설명~~</p>
<img src="~원하는 사진~" alt="">
</section>
</body>
CSS
아래 주석에 자세한 설명을 참고해주세요!
- 부드럽게 변경할 요소들, 애니메이션을 주고 싶은 요소들에는transition을 작성하여, 애니메이션 효과를 줄 수 있습니다.
- all : 해당 클래스(혹은 태그)에서 일어나는 모든 변화에 대해 적용한다는 뜻입니다.
- 1s : 변화 효과가 1초 지속(소수점 단위도 설정 가능)
- ease-in-out : 가감속 효과, 속도의 변화량 조절. 다양한 옵션을 여기서 확인 가능!
- position: fixed 로 요소를 고정 위치에 둘 수 있습니다
<style>
body {
transition: all 1s ease-in-out;
overflow-x: hidden; /* 넘치는거 안보이게 함 */
}
section img{
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%); /* 축이 좌상단이라 중앙으로 이동 */
height: 300px;
opacity: 0;
transition: all 1s ease-in-out;
}
section.active img { /* section에 active라는 class가 있을때 img의 스타일 */
opacity: 1;
}
.navi {
position: fixed;
left: 50%;
top: 25%;
transform: translate(-50%, -50%);
z-index: 100;
}
button {
font-size: 20px;
padding: 10px 30px;
cursor: pointer;
}
section {
position: relative;
height: 100vh; /* 전체 화면 꽉 채우기 */
width: 100vw; /* 전체 화면 꽉 채우기 */
border-top: dashed 2px black
}
.pointer {
position: fixed;
right: 3vw;
top: 40%;
z-index: 100;
}
li {
list-style: none;
width: 12px;
height: 12px;
margin-top: 15px;
cursor: pointer;
background-color: #666;
border-radius: 50%;
transition: background 1s ease-out;
}
li.active {
background-color: rgb(15, 15, 15);
}
.progressBar {
margin-top: 20px;
background-color: black;
height: 5px;
border-radius: 5px;
text-align: start;
width: 10%;
transition: all .1s ease-out;
}
</style>
Java Script
- pageChange() : 변경된 페이지 번호를 span 태그에 반영하고, 배경 색상 변경, pageNum에 해당하는 이미지만 보이게 하기, pageNum에 해당하는 네비게이션만 진한색으로 하기, 스크롤값에 맞게 프로그래스바 변경하기
- pageChangeBtn() : 버튼으로 이동한 경우 한번에 여러 스크롤을 뛰어 넘어야 해서 필요. pageNum에 해당하는 section의 Top으로 스크롤 부드럽게 이동하기
- 스크롤 이벤트 : 스크롤값을 감지하여 페이지의 중간이상을 넘어가면 pageNum을 바꾸고, pageChange() 실행하기
<script>
window.onload = function(){
const preBtn = document.querySelector(".preBtn")
const nextBtn = document.querySelector(".nextBtn")
const span = document.querySelector('span')
const bgColor = ["#E99497", "#F3C583", "#E8E46E", "#CDF0EA"]
const section = document.querySelectorAll('section')
const body = document.querySelector('body')
const img = document.querySelector('img')
const li = document.querySelectorAll('li')
const progressBar = document.querySelector('.progressBar')
const scrollHeight = body.scrollHeight
let pageNum = 0 // 페이지 인덱스 0~3, 페이지는 1~4
const totalNum = section.length // 전체 길이
preBtn.addEventListener('click', function() {
if (pageNum > 0) {
pageNum --
pageChange()
pageChangeBtn()
}
})
nextBtn.addEventListener('click', function() {
if (pageNum < totalNum-1) {
pageNum ++
pageChange()
pageChangeBtn()
}
})
li.forEach((ele, idx) => {
ele.addEventListener('click', function(){
pageNum = idx
pageChange()
pageChangeBtn()
})
})
function pageChange(){
span.innerText = pageNum + 1 // 페이지 번호 변경
body.style.backgroundColor = bgColor[pageNum] // 배경색 변경
for(var i=0; i<totalNum; i++){ // section태그에서 active 클래스 다 빼기
section[i].classList.remove("active");
li[i].classList.remove("active");
}
section[pageNum].classList.add("active"); // 현재 page의 section태그에 active 클래스 넣기
li[pageNum].classList.add("active")
const scroll = this.scrollY
progressBar.style.width = `${(scroll+section[0].offsetHeight)/scrollHeight*100}%`
}
function pageChangeBtn(){
window.scrollTo({ // ~로 스크롤하기
top: section[pageNum].offsetTop, // 각 section 상단에 맞추기
behavior: 'smooth'
})
}
// 페이지 로드되면 바로 실행
pageChange()
window.addEventListener("scroll", function(event){ // 스크롤 이벤트 감지
const scroll = this.scrollY // 스크롤값
for (let i=0; i<totalNum; i++){
// 페이지가 중간 이상 넘어가면 다음페이지로 간주
if (scroll > section[i].offsetTop - window.outerHeight/2 &&
scroll < section[i].offsetTop - window.outerHeight/2 + section[i].offsetHeight) {
pageNum = i
break
}
}
pageChange()
})
}
</script>
참고
반응형
'Language > Java Script' 카테고리의 다른 글
[Vanilla Java Script] 변수 let, const, var (0) | 2021.06.24 |
---|---|
[Java Script + CSS] js와 css로 간단한 toggle animation 만들기 (0) | 2021.06.22 |