<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');
/* 주요 변수 초기화 */
let currentIdx = 0;
let translate = 0;
const speedTime = 500;
/* CSSOM 셋업 */
const liWidth = slideLis[0].clientWidth;
const sliderWidth = liWidth * slideLis.length;
slider.style.width = `${sliderWidth}px` ;
/* 리스너 설치하기 */
moveButton.addEventListener('click', moveSlide);
/* 슬라이드 실행 */
function move(D) {
currentIdx += (-1 * D);
translate += liWidth * D;
slider.style.transform = `translateX(${translate}px)`;
slider.style.transition = `all ${speedTime}ms ease`
}
/* 버튼 클릭 */
function moveSlide(event) {
event.preventDefault();
if (event.target.className === 'next') {
if (currentIdx === slideLis.length -1) return;
move(-1);
} else {
if (currentIdx === 0) return;
move(1);
}
}
}
</script>
이전 글 슬라이드 코드에서 슬라이드를 실행하는 부분을 따로 함수로 빼내어 작성했고, transition
기능을 CSS에서 빼내어 move()
함수에 추가했다.
무한루프를 만들기 위해서는 li
태그의 첫 번째 부분과 마지막 번째 부분을 복사하여 슬라이드 양 끝에 배치해야한다. 그리고 복사된 슬라이드로 넘어왔을때, 애니메이션을 중단하고 그 자리를 복사된 슬라이드와 같은 슬라이드가 자리를 메꾸도록 코드를 작성해야한다.
예를 들어,
A, B, C,
총 3개의 슬라이드가 있다고 가정하자. 무한루프를 만들고 싶다면, 여기서 처음과 끝 슬라이드를 복사하여 가장자리에 배치해야한다.
C, A, B, C, A
위와 같은 구조가 됐을때, 슬라이드 차례가 맨 끝부분인 복사된 A에 도착했다고 가정해보자. 그럴경우 복사된 A는 애니메이션 적용을 받아 자연스럽게 앞의 C에서 이동해왔을 것이다. 여기서 애니메이션 적용을 제거한 뒤 곧바로 두번째 자리에 있는 A로 이동하게 한다면, 우리 눈에는 A가 움직이지 않고 그대로 있는 모습을 연출할 수 있다. 실제로는 복사된 A에서 원래 A로 위치가 변경됐음에도 불구하고 말이다. 아래의 그림을 보면 더 이해하기 쉬울 것이다.
A-B-C-copyA 구조로 슬라이드가 적용되도록 코드를 작성했다고 하자. 위 그림은 해당 구조에서 C에서 copyA로 넘어가는 순간, 애니메이션 적용을 제거하고 A위치로 옮겨가게 코드를 작성해 출력한 모습이다. 여기서 copyA가 A와 콘텐츠가 똑같다면 우리 눈에는 copyA에서 A로 곧바로 넘어갔다는 사실을 인지하지 못하고 무한히 슬라이드가 동작한다고 느낄 것이다.
이제 앞에서 배운 지식을 바탕을 가지고 코드를 작성해보자.
<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');
/* 클론 */
const clone1 = slideLis[0].cloneNode(true);
const cloneLast = slideLis[slideLis.length - 1].cloneNode(true);
slider.insertBefore(cloneLast, slideLis[0]);
slider.appendChild(clone1);
/* 주요 변수 초기화 */
let currentIdx = 0;
let translate = 0;
const speedTime = 500;
/* CSSOM 셋업 */
const sliderCloneLis = slider.querySelectorAll('li');
const liWidth = slideLis[0].clientWidth;
const sliderWidth = liWidth * sliderCloneLis.length;
slider.style.width = `${sliderWidth}px`;
currentIdx = 1;
translate = -liWidth;
slider.style.transform = `translateX(${translate}px)`
/* 리스너 설치하기 */
moveButton.addEventListener('click', moveSlide);
/* 슬라이드 실행 */
function move(D) {
currentIdx += (-1 * D);
translate += liWidth * D;
slider.style.transform = `translateX(${translate}px)`;
slider.style.transition = `all ${speedTime}ms ease`
}
/* 클릭 버튼 */
function moveSlide(event) {
event.preventDefault();
if (event.target.className === 'next') {
move(-1);
if (currentIdx === sliderCloneLis.length -1)
setTimeout(() => {
slider.style.transition = 'none';
currentIdx = 1;
translate = -liWidth;
slider.style.transform = `translateX(${translate}px)`;
}, speedTime);
} else {
move(1);
if (currentIdx === 0) {
setTimeout(() => {
slider.style.transition = 'none';
currentIdx = sliderCloneLis.length -2;
translate = -(liWidth * currentIdx);
slider.style.transform = `translateX(${translate}px)`;
}, speedTime);
}
}
}
}
</script>
위의 코드를 보면, .cloneNode()
기능을 사용해 첫번째와 마지막 li
태그를 복사한 것을 볼 수 있다. 이후 insertBefore
와 appendChild
를 사용해 기존의 li
태그 앞과 뒤에 배치시켰다.
참고로 insertBefore
는 배치할 대상과 배치할 위치를 지정해야하나, appendChild
는 배치할 대상만 지정해주면 된다.
이렇게 되면 복사된 li
태그 2개가 새로 생겨났지만. 기존 li
태그 값을 받아오는 slideLis
변수는 그것을 반영하지 못한다. 따라서 복사된 태그와 기존의 태그를 묶어 줄 수 있는 slideCloneLis
변수를 새로 만들었다.
그리고 slideLis
변수를 사용한 부분을 전부 slideCloneLis
변수로 바꿔준다.
이후 if문을 이용해 특정 조건(currentIdx
가 0 또는 slideCloneLis
배열 길이와 같을 때)일 경우 setTimeout
을 사용해 시간차로 애니메이션을 정지하고, 복사된 슬라이드와 같은 슬라이드로 변경해준다. 이렇게 하면 아래와 같은 무한루프 슬라이드를 만들 수 있다.
setTimeout
이 한 번 시간을 지연시키는 함수라면 setInterval
은 시간 지연을 여러번 반복시킬 수 있다.
자동변환 슬라이드는 setInterval
를 활용해서 만들 수 있다.
<script>
function sliding() {
move(-1);
if (currentIdx === sliderCloneLis.length -1)
setTimeout(() => {
slider.style.transition = 'none';
currentIdx = 1;
translate = -liWidth;
slider.style.transform = `translateX(${translate}px)`;
}, speedTime);
}
function showSliding() {
setInterval(sliding, 1500);
}
showSliding();
</script>
기존의 'next' 버튼을 담당했던 코드들을 가져와 sliding()
함수에 그대로 입히고, 이것을 그대로 setInterval
함수로 가져다주면 아래와 같은 자동변환 슬라이드를 만들 수 있다.
끝.
개구리가 너무 매력있네요. 슬라이드 계속 보게 되요🙄