코딩 공부 일지/JavaScript

JS 예제) 바닐라 자바스크립트로 무한 루프 슬라이드 구현하기

헬로코딩 2022. 1. 24. 22:00
728x90

// 바닐라 자바스크립트로 무한 루프 슬라이드 구현하기

우리에겐 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)}%`;
    })
  }
});

 

헷갈릴 수도 있지만 코드 한줄 한줄 뜯어보면 전혀 어렵지 않은 무한 루프 슬라이드 구현하기였다.

728x90