[Tistory] [자바스크립트] 바닐라JS로 캐러셀기능 구현하기

원글 페이지 : 바로가기

🔗 레퍼런스 https://www.wavve.com/ Wavve(웨이브) 세상 얕은 콘텐츠부터 세상 딥한 콘텐츠까지 JUST DIVE! Wavve www.wavve.com ✅ 구현 사항 1. 한 눈에 데이터 3개 노출하기 (swiper-slide) 2. 버튼으로 슬라이드 동작 구현하기 (swipe-button-next / swipe-button-prev) html

아직 슬라이드 안 텍스트들은 데이터 값을 받아온 상태가 아니라서 임의로 만들어놓았다. 캐러셀은 항상 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

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다