❓ 내가 말하는 무한 슬라이드란 ?
결과물:
이 영상의 슬라이드는 mounted에서 setInterval을 설정하여 자동으로 오른쪽 슬라이딩이 되게 해놨다.
Vue로 코딩을 하였기때문에 v-for로 각 슬라이드 아이템을 생성
// template
<template>
//..나머지 코드 중략
<div class="slide-container">
<button @click="moveSlideToLeft">
<img src="왼쪽버튼이미지입니다." />
</button>
<div class="slide-window">
<div class="slide"
:class="{ slide-active': transitionOn }"
:style="{transform: 'translate3d(' + slideCoord + 'px, 0, 0)',}">
<SlideCard v-for="card in cardArray" :key="card.name" /></div>
</div>
</div>
<button @click="moveSlideToRight">
<img src="오른쪽버튼이미지입니다."/>
</button>
</div>
</template>
// script
<script>
//..코드 중략
export default {
data(){
transitionOn: true; //슬라이드가 움직일때 트렌지션을 줄 것인지
cardArray : [], // 슬라이드 카드가 담길 배열 mounted에서 담아준다.
slideCoord: -300, // 옆으로 움직일 값, (슬라이드의 마진,패딩값 포함된 width)
// 이 값으로 슬라이드 카드를 담고있는 .slide의 css에 transform: translate3d(여기, 0 , 0) 에 넣어줘야 한다.
}
}
</script>
//..style 생략
😈 문제 발생
처음엔 슬라이드 카드 배열안의 카드 순서만 바꾸는 방법을 적용했다가 문제를 겪었다.
배열의 맨 앞을 잘라내서 뒤에 갖다 붙이는 방법으로 배열 내 순서를 바꿨다. 하지만......
이 방법으로는 .slide는 계속 오른쪽으로 이동하는데 배열안의 카드의 순서만 바뀔 뿐 배열의 길이는 그대로였기때문에 카드들을 담고 있는 슬라이드에 빈 칸이 표시되는 문제 발생.
비유하자면 기차에서 1,2,3,4,5 사람이 순서대로 자리만 바꿨을뿐 기차는 계속해서 앞으로 이동했기때문에
기차가 1,2,3,4,5의 사람들을 볼 수 없게된다.
🤓 문제 해결하기
배열의 앞을 잘라내지않고 뒤에 계속 붙여나가는 방법을 사용, 하지만 이 방법은 배열의 길이가 무한으로 늘어나는 문제가 있다.
배열이 늘어남에따라 v-for로 생성대는 컴포넌트 역시 무한으로 늘어나게 된다.
때문에 배열이 한 번 순환하면 늘어난 배열을 다시 초기 배열의 값으로 바꿔주었다.
(예. [1,2,3,4,5] → [1,2,3,4,5,1] → [1,2,3,4,5,1,2...5] → [1,2,3,4,5])
다만 이 방법도 그닥 좋다고 생각들지 않았다.
배열 뒤로 카드를 붙여나가는 방법으로 data
에 currentIdx라는 값을 만들어 놓고, 오른쪽버튼 클릭이벤트를 발생시킬때마다 currentIdx라는 값에 +1을 더한다.
슬라이드카드배열.splice(슬라이드카드배열의 마지막 인덱스, 0, 카드 초기배열[currentIdx])
으로 배열의 길이를 늘려나갔다보니 data
에 currentIdx값과 카드 초기배열 값을 저장해두었다.
배열의 한 사이클을 돌면 슬라이드 카드 배열을 초기 배열 값과 동일하게 바꿔주고 currentIdx는 다시 0으로 만들어 주는 방법..
난 배열의 길이를 조작하지 않고 순서만 바꾸면서 슬라이드되는 효과를 만들고 싶었다.
그래서 생각해낸 방법이 슬라이드 트렌지션이 발생한 후 다음 슬라이드를 넘기기 전에 보여지고 있는 순서로 배열 순서를 만들어주는 방법이다.
methods: {
resetCardArrayToRight() {
// 슬라이드 카드 배열 끝에 맨 앞에 있던 카드를 추가
this.cardArray.splice(this.cardArray.length, 0, this.cardArray[0]);
// 맨 끝에 추가한 후 맨 앞에 있던 카드는 삭제
this.cardArray.splice(0, 1);
// 잠시 transition 을 off 하기
this.transitionOn = false;
// slideCoord를 초기값으로 설정
this.slideCoord = -300;
},
// 슬라이드 오른쪽 버튼 클릭이벤트 @click=" moveSlideToRight"
moveSlideToRight() {
// -300 씩 이동
this.slideCoord = this.slideCoord - 300
// transitionOn은 true로
this.transitionOn = true
// 0.5초 뒤에 배열의 순서를 바꾸고 slideCoord값을 다시 초기 값으로 설정
// 이때만 transition을 off하여 움직이지 않는 것 처럼 눈속임한다.
// 여기 setTimeout의 delay 시간은 css의 transition의 duration과 같게 설정해야한다.
setTimeout(this.resetCardArrayToRight, 500)
},
}
왼쪽으로 이동하는 방법도 오른쪽과 같다. 다만 처음 슬라이드가 시작할 때 인덱스 0이 아닌 1부터 보여줘야했다. 이 때문에 slideCoord의 초기 값을 0이 아닌 슬라이드 하나 넘어간 -300으로 설정했다.
0부터 시작한다면 처음에 왼쪽으로 넘길때 왼쪽에 왼쪽에 카드가 없어서 빈칸이 넘어오게 되기 때문..
위 방법으로 currentIdx나 초기 배열의 값을 쓸데없이 data
에 저장하지 않아도 된다.
tip 참고로 처음엔 .slide-container에
relative
, .slide에absolute
로left
값을 더하거나 빼는 방법으로 슬라이드를 좌우 이동하였으나,transform: translate3d
를 사용하는 방법을 추천한다고 한다.
작동이 되지 않습니다ㅠㅠ 혹시 완성된 코드를 참고할 수 있을까요?