JavaScript 슬라이드 만들기

DANO PARK·2022년 4월 25일
9
post-thumbnail

목표 설정

  • 슬라이드 끝부분에서는 슬라이드 이미지가 빈 화면으로 넘어가지 않게 하기
  • n개의 슬라이드를 넣어도 별도 수정없이 동작 가능하게 하기
  • 다양한 크기의 이미지를 넣어도 별도 수정없이 동작 가능하게 하기
  • 하나의 함수로 버튼 두 개를 관리하기

HTML

<html>
<div class="kind_wrap">
  <div class="kind_slider">
    <ul class="slider">
        <li><img src="https://via.placeholder.com/800x200.png?text=1" alt=""></li>
        <li><img src="https://via.placeholder.com/800x200.png?text=2" alt=""></li>
        <li><img src="https://via.placeholder.com/800x200.png?text=3" alt=""></li>
        <li><img src="https://via.placeholder.com/800x200.png?text=4" alt=""></li>
        <li><img src="https://via.placeholder.com/800x200.png?text=5" alt=""></li>
    </ul>
  </div>
  <div class="arrow">
      <a href="" class="prev">이전</a>
      <a href="" class="next">다음</a>
  </div>
</div>
</html>

CSS

<style>
* {
  margin:0; 
  padding:0;
}
li {
  list-style: none;
}
.kind_wrap {
  border:2px solid black; 
  width:100%; 
  max-width:800px; 
  margin:0 auto; 
  position: relative;
}
.kind_wrap > .kind_slider {
  overflow: hidden;
}
.kind_wrap > .kind_slider .slider { 
  position: relative; 
  transition: 0.5s;
}
.kind_wrap > .kind_slider .slider li {
  float:left;
}
.kind_wrap > .kind_slider img {
  vertical-align: top;
}
.kind_wrap .arrow > a.prev {
  position: absolute; 
  left:-50px; 
  top:100px;
}
.kind_wrap .arrow > a.next {
  position: absolute; 
  right:-50px; 
  top:100px;
}
</style>

Javascript

<script>
window.onload = function() {
  const kindWrap =  document.querySelector('.kind_wrap');
  const slider = kindWrap.querySelector('.slider');
  const slideLis = slider.querySelectorAll('li')
  const moveButton = kindWrap.querySelector('.arrow');

  /* ul 넓이 계산해 주기 */
  const liWidth = slideLis[0].clientWidth;
  const sliderWidth = liWidth * slideLis.length;
  slider.style.width = `${sliderWidth}px` ;

  /* 리스너 설치하기 */
  let currentIdx = 0; // 슬라이드 현재 번호
  let translate = 0; // 슬라이드 위치 값
  moveButton.addEventListener('click', moveSlide);

  function moveSlide(event) {
    event.preventDefault();
    if (event.target.className === 'next') {
      if (currentIdx !== slideLis.length -1) {
        translate -= liWidth;
        slider.style.transform = `translateX(${translate}px)`;
        currentIdx += 1;
      }
    } else if (event.target.className === 'prev') {
        if (currentIdx !== 0) {
          translate += liWidth;
          slider.style.transform = `translateX(${translate}px)`;
          currentIdx -= 1;
        }
      }
  }

}
</script>

출력 화면

하나의 함수로 버튼을 설정하라는 조건이 있어서 if문을 두 번 감싸 코드를 작성했다.

클릭 이벤트가 발생했을때 클릭한 곳의 클래스 명이 'next'이면 이미지가 오른쪽에서 왼쪽으로, 'prev'이면 왼쪽에서 오른쪽으로 넘어가도록 설정했다.

이 다음부턴 이미지를 움직이게 하되, 첫번째와 마지막번째는 버튼이 동작하지 않게 하는 조건을 달아야했다. 초반엔 if문을 이용해 이 조건에 해당할 경우 버튼이 동작하지 않게 하는 방법을 찾기 위해 많이 헤멨다. 그러나 간단하게도 이 조건에 해당하지 않을 경우 이미지를 동작하게 하여 문제를 해결했다.

위의 코드를 보면, currentIdx가 0 또는, ul태그의 개수가 아닐 경우 코드가 실행된다.

코드가 실행되면 이미지는 이미지의 가로 넓이 값만큼 옮겨지며, currentIdx는 ±1만큼 수정된다.

return을 활용한 다른 코딩 방법

<script>
  function moveSlide(event) {
    event.preventDefault();
    if (event.target.className === 'next') {
      if (currentIdx === slideLis.length - 1) return;
        currentIdx++;
        translate += -liWidth;
        slider.style.left = `${translate}px`;
    } else {
      if (currentIdx === 0) return;
        currentIdx--;
        translate += liWidth;
        slider.style.left = `${translate}px`
    }
  }
</script>

위와 같은 방법을 응용하여 아래와 같은 슬라이드도 만들 수 있었다.

응용 화면

다음 글에서 계속

profile
단오해서 단호박!

3개의 댓글

comment-user-thumbnail
2022년 4월 25일

코딩천재 기백님

1개의 답글
comment-user-thumbnail
2023년 11월 5일

뭐 좀 여쭤봐도 될까요 ㅠㅠ ?!

답글 달기