일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- http
- SasS
- JavaScript
- 코린이
- useEffect
- 코딩초보
- 코딩독학
- scss
- React Native
- 리덕스
- 리액트
- git
- 프론트엔드
- html기초
- react-router
- async
- 타입스크립트
- TypeScript
- 코딩공부
- 리액트 네이티브
- redux
- 자바스크립트
- CSS
- 깃
- 사용하는 이유
- Vue3
- 코딩기초
- react
- 비동기
- 참조자료형
- Today
- Total
맨 땅에 프론트엔드 개발자 되기
JS 예제) 바닐라 자바스크립트로 무한 루프 슬라이드 구현하기 본문
// 바닐라 자바스크립트로 무한 루프 슬라이드 구현하기
우리에겐 Swiper라는 아주 좋은 플러그인 툴이 있지만 초급자 입장에서 Swiper는 아직 익숙치 않고 변형하고 싶을 때 조정하기가 어려워서 슬라이드의 기본 원리를 깨우치기 위해 바닐라 자바스크립트로 무한 루프 슬라이드를 구현해보았다.
기본 원리는 슬라이드 리스트 중 맨 앞에 맨 끝 슬라이드를 복제하고, 맨 뒤에 맨 처음 슬라이드를 복제해서 먼저 복제된 슬라이드로 이동을 시키고 setTimeout을 이용해서 원래 가야할 슬라이드로 순식간에 이동시키는 방식이다.
슬라이드의 구조를 보자면
10 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10 / 1
이렇게 되어있는 것이다.
슬라이드를 움직이기 위해서 슬라이드를 감싸고 있는 부모요소가 2개가 필요하다.
슬라이드 부모요소를 레이어 1이라고 하고, 슬라이드 부모요소의 부모요소를 레이어 2라고 한다면 레이어 2는 가만히 놔두고 레이어 1을 움직여서 슬라이드를 움직이는 것처럼 보이게 한다. 그래서 레이어 1의 넓이는 슬라이드 넓이 X 슬라이드 개수가 된다.
구조를 알았으니 이제 코드를 짜 볼 시간! 아래의 코드를 보자.
HTML과 CSS는 간단하게만 구현했다.
#HTML
<section>
<h2>Infinite Loop Slide</h2>
<div class="container">
<div class="displayWrap">
<div class="slideWrap">
<p class="slide slide1">01</p>
<p class="slide slide2">02</p>
<p class="slide slide3">03</p>
<p class="slide slide4">04</p>
<p class="slide slide5">05</p>
<p class="slide slide6">06</p>
<p class="slide slide7">07</p>
<p class="slide slide8">08</p>
<p class="slide slide9">09</p>
<p class="slide slide10">10</p>
</div>
</div>
<div class="pagination">
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
<a href="javascript:void(0)"></a>
</div>
<div class="btn-prev"></div>
<div class="btn-next"></div>
</div>
</section>
#CSS
*{text-align: center;}
p{margin: 0;}
section{
width: 100%; height: 100vh;
background-color: #fff;
}
h2{margin: 50px auto;}
.container{
position: relative;
}
.displayWrap{
width: 70%; height: 60vh;
margin: 0 auto;
overflow: hidden;
position: relative;
}
.slideWrap{
height: 100%;
display: flex;
position: absolute;
left: 0; top: 0;
}
.slideWrap .slide{
width: 100%; height: 100%;
font-size: 50px;
display: flex;
justify-content: center; align-items: center;
}
.slide1{background-color: tomato;}
.slide2{background-color: salmon;}
.slide3{background-color: orange;}
.slide4{background-color: gold;}
.slide5{background-color: yellowgreen;}
.slide6{background-color: limegreen;}
.slide7{background-color: seagreen;}
.slide8{background-color: skyblue;}
.slide9{background-color: royalblue;}
.slide10{background-color: darkorchid;}
.pagination{
width: 100%; text-align: center;
margin: 50px 0;
}
.pagination a{
display: inline-block;
margin: 0 10px;
width: 15px; height: 15px;
border-radius: 15px;
background-color: #eee;
}
.pagination a.active{
background-color: #555;
}
.btn-prev,.btn-next{
position: absolute;
width: 50px; height: 50px;
top: 0; bottom: 0;
margin: auto 0;
background-color: #fff;
cursor: pointer;
}
.btn-prev{
left: 100px;
border-top: 1px solid #555;
border-left: 1px solid #555;
transform: rotate(-45deg);
}
.btn-next{
right: 100px;
border-bottom: 1px solid #555;
border-right: 1px solid #555;
transform: rotate(-45deg);
}
#JAVASCRIPT
const slideWrap = document.querySelector('.slideWrap');
const slide = document.querySelectorAll('.slide');
const nav = document.querySelectorAll('.pagination a');
nav[0].classList.add('active');
const firstEl = slideWrap.firstElementChild;
const lastEl = slideWrap.lastElementChild;
let cloneFirst = firstEl.cloneNode(true);
let cloneLast = lastEl.cloneNode(true);
slideWrap.appendChild(cloneFirst);
slideWrap.insertBefore(cloneLast, slideWrap.firstElementChild);
slideWrap.style.width = `${100*(slide.length+2)}%`;
slideWrap.style.left = '-100%';
맨 처음 슬라이드와 맨 끝 슬라이드를 cloneNode 메소드를 이용해 복제한다.
그리고 맨 끝 슬라이드를 맨 앞에 추가, 맨 처음 슬라이드를 맨 뒤에 추가 시키고 레이어 1을 슬라이드 1개 넓이만큼 왼쪽으로 이동시킨다.
레이어 1의 넓이는 (슬라이드 개수 + 복제된 슬라이드 2개) X 슬라이드 1개의 넓이이다.
그런 다음 버튼을 누를 때마다 레이어 1을 왼쪽 혹은 오른쪽으로 움직이면 된다.
맨 처음 슬라이드에서 맨 끝 슬라이드로 이동할 때 혹은 맨 끝 슬라이드에서 맨 처음 슬라이드로 이동할 때는 다른 때와 같이 슬라이드를 이동시킨 뒤 진짜 슬라이드로 0.05초 후 순식간에 움직인다.
그러면 무한 루프 슬라이드의 움직임이 구현된다.
const nextBtn = document.querySelector('.btn-next');
const prevBtn = document.querySelector('.btn-prev');
let current = 0;
nextBtn.addEventListener('click',function(){
if(current < slide.length - 1){
current++;
nav[current-1].classList.remove('active');
nav[current].classList.add('active');
slideWrap.style.transition = '500ms';
slideWrap.style.left = `-${100 * (current + 1)}%`;
}else{
current++;
slideWrap.style.transition = '500ms';
slideWrap.style.left = `-${100 * (current + 1)}%`;
current = 0;
nav[slide.length-1].classList.remove('active');
nav[current].classList.add('active');
setTimeout(function(){
slideWrap.style.transition = '0ms';
slideWrap.style.left = `-${100 * (current + 1)}%`;
},550);
}
});
prevBtn.addEventListener('click',function(){
if(current > 0){
current--;
nav[current+1].classList.remove('active');
nav[current].classList.add('active');
slideWrap.style.transition = '500ms';
slideWrap.style.left = `-${100 * (current + 1)}%`;
}else{
slideWrap.style.transition = '500ms';
slideWrap.style.left = '0%';
current = slide.length - 1;
nav[0].classList.remove('active');
nav[current].classList.add('active');
setTimeout(function(){
slideWrap.style.transition = '0ms';
slideWrap.style.left = `-${100 * (current + 1)}%`;
})
}
});
헷갈릴 수도 있지만 코드 한줄 한줄 뜯어보면 전혀 어렵지 않은 무한 루프 슬라이드 구현하기였다.
'코딩 공부 일지 > JavaScript' 카테고리의 다른 글
호이스팅 (Hoisting) (0) | 2022.02.09 |
---|---|
코딩독학) 배열 (Array) (+ 몇 가지 JavaScript 메소드) (0) | 2022.02.08 |
코딩독학) JavaScript 생성자 함수와 클래스 함수 (ES6) (0) | 2022.02.07 |
코딩독학) script 태그, async와 defer (0) | 2022.02.07 |
JS 예제) 반복문을 활용한 구구단 출력하기 (0) | 2022.01.26 |