🔗 레퍼런스

https://www.wavve.com/

 

Wavve(웨이브)

세상 얕은 콘텐츠부터 세상 딥한 콘텐츠까지 JUST DIVE! Wavve

www.wavve.com

 


 

✅  구현 사항

1. 한 눈에 데이터 3개 노출하기 (swiper-slide)

2. 버튼으로 슬라이드 동작 구현하기 (swipe-button-next / swipe-button-prev)

 


 

html

<!-- 슬라이드 영역 -->
            <div id="main-banner" class="swiper-container banner">
                <div class="main01-nav">

                    <!-- bullet -->
                    <div class="swiper-pagination swiper-pagination-bullets">
                        <span class="swiper-pagination-bullet"></span>
                        <span class="swiper-pagination-bullet"></span>
                        <span class="swiper-pagination-bullet"></span>
                        <span class="swiper-pagination-bullet"></span>
                        <span class="swiper-pagination-bullet"></span>
                    </div>

                    <!-- prev, next -->
                    <button class="swiper-button-next"></button>
                    <button class="swiper-button-prev"></button>
            
                </div>

                <div class="swiper-wrapper-banner">

                    <div class="swiper-slide">
                        <div class="slide-txt">
                            <h1>제목</h1>
                            <p>아웃라인 텍스트</p>
                            <p>텍스트</p>
                        </div>
                        <img src="assets/main5.png" alt="banner">
                    </div>
                    <div class="swiper-slide">
                        <div class="slide-txt">
                            <h1>제목</h1>
                            <p>아웃라인 텍스트</p>
                            <p>텍스트</p>
                        </div>
                        <img src="assets/main1.png" alt="banner">
                    </div>

                    <div class="swiper-slide">
                        <div class="slide-txt">
                            <h1>제목</h1>
                            <p>아웃라인 텍스트</p>
                            <p>텍스트</p>
                        </div>
                        <img src="assets/main2.png" alt="banner">
                    </div>

                    <div class="swiper-slide">
                        <div class="slide-txt">
                            <h1>제목</h1>
                            <p>아웃라인 텍스트</p>
                            <p>텍스트</p>
                        </div>
                        <img src="assets/main3.png" alt="banner">
                    </div>

                    <div class="swiper-slide">
                        <div class="slide-txt">
                            <h1>제목</h1>
                            <p>아웃라인 텍스트</p>
                            <p>텍스트</p>
                        </div>
                        <img src="assets/main4.png" alt="banner">
                    </div>

                    <div class="swiper-slide">
                        <div class="slide-txt">
                            <h1>제목</h1>
                            <p>아웃라인 텍스트</p>
                            <p>텍스트</p>
                        </div>
                        <img src="assets/main5.png" alt="banner">
                    </div>

                    <div class="swiper-slide">
                        <div class="slide-txt">
                            <h1>제목</h1>
                            <p>아웃라인 텍스트</p>
                            <p>텍스트</p>
                        </div>
                        <img src="assets/main1.png" alt="banner">
                    </div>
                </div>
            </div>

 

아직 슬라이드 안 텍스트들은 데이터 값을 받아온 상태가 아니라서 임의로 만들어놓았다. 캐러셀은 항상 api를 가져와서 사용했었는데 막상 직접 만드려고하니 머리가 띵했다.. 근데 어떻게.. 해야지.. 상단 구조를 잡아놓고 시작

swiper-container / banner : 최상위 클래스로 캐러셀의 전체 구조
swiper-wrapper-banner : 캐러셀 슬라이드의 전체 구조
swiper-slide : 캐러셀 이미지를 설정
swipe-button-prev / swipe-button-next : 캐러셀 사이드 버튼 설정

 

 

css

/* 슬라이드 */
.banner { 
    width: 100%;
    overflow: hidden;
    margin: 0 auto 80px;
    position: relative;
    min-width: 1250px;
    max-width: 3840px;
    min-height: 555px;
  }
  
  .banner .main01-nav {
    display: table;
    position: absolute;
    bottom: 5%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    z-index: 2;
}
  
  .banner .main01-nav button[class^="btn"] {
    display: table-cell;
    width: 34px;
    height: 34px;
    vertical-align: middle;
  }
 

  .banner .swiper-pagination { /* pagination */
    display: table-cell;
    position: static;
    width: auto;
    font-size: 0;
    vertical-align: middle;
  }
  
  .swiper-pagination {
    position: absolute;
    text-align: center;
    transition: opacity 0.3s;
    z-index: 10;
  }
  

  .banner .swiper-button-prev {
    right: 500px;
    background-image: url(../assets/prev.png);
  }
  
  .banner .swiper-button-next,
  .banner .swiper-button-prev {
    position: absolute;
    top: -300px;
    z-index: 20;
    background-repeat: no-repeat;
    width: 100px;
    height: 100px;
    background-color: transparent;
    background-size: 100px auto;
    font-size: 0;
  }
  
  .swiper-button-next,
  .swiper-button-prev {
    position: absolute;
    top: 50%;
    z-index: 50;
    cursor: pointer;
    background-position: 50%;
    background-repeat: no-repeat;
  }
  
  .banner .swiper-button-next {
    left: 500px;
    background-image: url(../assets/next.png);
  }

 

우선 슬라이드에 pagination 슬라이드 이미지 가운데 배치 시키고 backgroun-image로 이전/다음 버튼을 넣어주었다. 

 

.swiper-slide > img {
    width: 100%;
  }
  
  .swiper-wrapper-banner {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 1;
    display: flex;
    box-sizing: content-box;
    transition: 0.3s ease-in-out;
  }
  
  .banner .swiper-slide {
    float: left;
    position: relative;
    overflow: hidden;
    width: 1250px;
    padding: 0 10px;
    border-radius: 12px;
  }
  
  .swiper-slide {
    flex-shrink: 0;
    width: 100%;
    height: 100%;
    position: relative;
  }


  .slide-txt{
    position: absolute;
    top:75%;
    left: 15%;
    transform: translate(-15%, -50%);
    color:#fff;
    font-size: 40px;
    line-height: 1.5em;
    font-weight: bolder;
  }

 

display : flex 로 슬라이드들을 가로로 정렬해주고 슬라이드의 가로 사이즈는 1250px로 맞춰주었다. 슬라이드마다 텍스트를 띄우기 위해 slide-txt가 들어가 있는 swiper-slide에 position:relative를 주고 왼쪽 아래 배치해 주었다.

 

Javascript

const sliderContainer = document.querySelector(".swiper-container");
const sliderWrapper = sliderContainer.querySelector(".swiper-wrapper-banner");
const slides = sliderWrapper.querySelectorAll(".swiper-slide");

const prevBtn = sliderContainer.querySelector(".swiper-button-prev");
const nextBtn = sliderContainer.querySelector(".swiper-button-next");
const pagination = sliderContainer.querySelector(".swiper-pagination");

 

필요한 요소들을 변수에 저장해준다. .swiper-slide는 배열로 가지고 올거기때문에 querySelectorAll 로 가지고 오자!

 

const slideCount = slides.length;
const size = slides[0].clientWidth; 
let currentIndex = 1;

 

slideCount에는 swiper-slide의 길이를 저장해주고, size는 슬라이드 0번째에 있는 컨텐츠의 크기를 확인할 수 있는 변수이다. slide의 사이즈는 css에서 1250px로 정했으니 size = 1250px이다.

currentIndex는 현재 위치를 저장하기 위한 변수이고 1번째 이미지를 메인으로 하기 위해 초기값을 1로 설정했다.

 

function updateSliderPosition() {
    sliderWrapper.style.transform = `translateX(${-size * currentIndex + 80}px)`; 
}

 

메인 배너가 배치되는 위치를 조정하는 함수로 updateSliderPosition()을 만들고 위치 값으로 슬라이드 사이즈와 현재 위치에 + 80px한 값을 넣어주었다. size = 1250px / currentIndex = 1 / + 80 으로 -1170 값이 나오는데 이 값은 처음 메인에 3개의 배너가 노출이 되어야 하기때문에 사이드에도 배너가 조금 보일 수 있게 밀어준 값이라고 생각하면 된다.

 

 

개발자 도구로 보면 이렇게 transform 으로 밀려있는걸 볼 수 있다!

 

function goToSlide(index) {
            sliderWrapper.style.transition = "0.3s ease";
            if (index < 0) {
                currentIndex = slideCount - 1;
            } else if (index >= slideCount) {
                currentIndex = 0;
            } else {
                currentIndex = index;
            }
            console.log(index);

            updateSliderPosition();
        }

 

다음으로 만들어야할 건 슬라이드를 움직이게 해주는 함수! 인덱스가 범위를 벗어나는지 확인하고 어떤 슬라이드가 노출되는지 조정한다. 이미지 슬라이드의 길이(이미지 장수)보다 커지면 안되므로 슬라이드에 포함된 이미지의 개수만큼만 작동할 수 있도록 인덱스가 슬라이드의 길이보다 크면 0으로 만들도록 했다.

 

//슬라이드 무한루프
        sliderWrapper.addEventListener("transitionend", () => {
            // currentIndex가 마지막일 인덱스일 경우
            if (currentIndex === slides.length - 1) {
                //첫번째 인덱스로 돌아감
                currentIndex = 1;
                sliderWrapper.style.transition = "0s";
                sliderWrapper.style.transform = `translateX(${-size * currentIndex + 80}px)`;
            }
            // 첫번째 인덱스일 경우
            if (currentIndex === 0) {
                // 마지막 슬라이드 이전 슬라이드
                currentIndex = slides.length - 2;
                sliderWrapper.style.transition = "0s";
                sliderWrapper.style.transform = `translateX(${-size * currentIndex + 80}px)`;
            }
        });

 

이제 슬라이드가 무한으로 돌아가는 루프를 만들어보자. 슬라이드의 이미지가 마지막에 도달했을 때 인덱스를 조정하는 무한 루프 함수를 만들었다. transitionend 이벤트를 사용해서 만들어보았다


✏️ transitionend

transitionend 이벤트는 CSS transition 이 완료되면 발생한다.
transition 속성이 제거되거나 display가 none으로 설정된 경우와 같이 완료 전에 
transition이 제거된 경우에는 이벤트가 생성되지 않는다.

 

currentIndex가 마지막일 인덱스일 경우 슬라이드의 길이에서 -1 한 값과 현재 위치가 같다면 처음 인덱스로 돌아가도록한다. 이때 transition을 0s로 해서 아무런 애니메이션 효과가 없도록한다. 

첫번째 인덱스일 경우 마지막 슬라이드가 첫번째의 이전 슬라이드가 되도록 슬라이드 길이에서 -2를 해준다. 

 

nextBtn.addEventListener("click", () => goToSlide(currentIndex + 1));
prevBtn.addEventListener("click", () => goToSlide(currentIndex - 1));

 

마지막으로 다음 버튼과 이전버튼에 이벤트 리스너를 달면 완성이다. 중간에 막히긴 했는데 첫번째 슬라이드 이미지 = 마지막 슬라이드 이미지를 넣고 마지막 슬라이드 이미지 = 첫번째 슬라이드 이미지를 넣으니까 해결 완료.. 마지막에 갔다가 다시 맨 처음으로 후리리릭 가는게 싫어서 참고사이트를 보고 한 꼼수다 후후.. 왜 이렇게 다들 잘할까.. 난..? 내일은 배너에 실제 api 데이터를 가지고 와야하는데 나 잘할 수 있게찌..

 

 

 

🔗 참고사이트

https://velog.io/@wjddnjswjd12/javascript%EB%A1%9C-carousel-slide-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EA%B8%B0

 

javascript로 carousel slide 구현해보기

우선 html 코드와 css는 이런 상태로 시작했습니다: image연습용이라 css를 대충 지정했습니다..😂일단 slide_box에 overflow:hidden을 주지 않고 진행이 어떻게되나 확인하면서 시작했습니다.overflow:hidden

velog.io

https://velog.io/@reasonz/2022.05.23-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%BA%90%EB%9F%AC%EC%85%80-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%93%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0

 

[2022.05.23] 자바스크립트 캐러셀 슬라이드 만들기

그동안 공부한 내용을 바탕으로 직접 이미지 슬라이드를 만들어보기로 했다. 다음/이전 버튼을 누르면 이미지가 슬라이드되는 방식이다.먼저 html 구조는 이렇게 짰다.전체 슬라이드를 감싸서 ov

velog.io

 

+ Recent posts