스터디 과정중 자기소개 페이지의 좌우 슬라이더를 구현할 일이 생겼다. 요 슬라이더를 매우
간단하게 슬라이더 라이브러리인 swiper.js로 간단하게 슬라이드를 구현할 수 있지만
아직은 배우는 단계이므로 순수 자바스크립트로만 구현을 해보자
전체적인 코드를 간략하게 나타낸 알고리즘이다. - 파란색은 함수를 나타낸다.
로직을보면서 조금더 자세히 알고리즘을 설명하려고 한다.

화면상 보이는 크기를 Slides라고 잡고 이것이 움직이면서 좌우 슬라이드를 구현할것이다.
하지만 이상태에서는 슬라이더를 구현하기가 힘드니 Slide 개수만큼 앞뒤 복사하여 붙여준다.
function makeClone() {
currentIdx = 0;
for (let i = 0; i < slideCount; i++) {
let cloneSlide = slide[i].cloneNode(true);
slides.appendChild(cloneSlide);
}
for (let i = slideCount - 1; i >= 0; i--) {
let cloneSlide = slide[i].cloneNode(true);
slides.prepend(cloneSlide);
}
setInitialPos();
setTimeout(function () {
slides.classList.add('animated');
}, 10)
}
makeClone함수를 붙여 Slide 개수만큼 앞뒤 복사하여 붙여 놓는다.

slide복사본을 앞뒤에 붙여 놓았으나 지금 현재 slides의 위치가 복사본 첫번째 위치에 있기때문에 이경우 왼쪽 버튼을 클릭했을때, 빈 공간이 나오기 때문에 setInitialPos()함수를 이용해 가운데 위치로 보내줘야한다.
slideMargin과slidesWidth값을 계산해서 initialTranslateValue라는 변수에 넣어주고 트랜스폼을 이용하여 그 위치만금 이동을 하게되면 가운데 위치를 선정할 수 있다.
slides.style.transform = 'translateX(' + initialTranslateValue + 'px)';
그러고 나서 오른쪽 버튼과 왼쪽 버튼을 눌러 slides를 움직여 좌우 슬라이드를 만들수 있다.
이제 slides를 움직여줄 moveSlide() 함수를 생성해서 left값을 조정한다.
function moveSlide(num) {
slides.style.left = -num * (slideWidth + slideMargin) + 'px';
currentIdx = num;
}
left값 만큼 움직였지만 마지막 복사본 끝이나 처음으로 갔을 경우 복사본을 또 다시 넣을경우 코드가 매우 난잡해지기 때문에 기존에 있던 위치로 이동 할것이다.
slideCount를 슬라이드 개수 currentIdx를 이동한 횟수로 변수로 두자.
slideCount와 currentIdx가 "서로 같다면" 이라는 조건하에 움직이면 되겠다.

반대로 오른쪽이 아닌 왼쪽으로 슬라이더 할 경우도 있으니 currentIdx == -slideCount 를 추가해준다.
기존에 있던 곳으로 이동하면서 currentIdx를 0으로 초기화 해주고 animated 라는 클래스를 지우고 1초뒤 다시 생성해준다.
그래서 moveSlide()함수가 완성되었다.
function moveSlide(num) {
slides.style.left = -num * (slideWidth + slideMargin) + 'px';
currentIdx = num;
if (currentIdx == slideCount || currentIdx == -slideCount) {
setTimeout(function () {
slides.classList.remove('animated');
slides.style.left = '0px';
currentIdx = 0;
}, 500);
setTimeout(function () {
slides.classList.add('animated');
}, 600);
}
}
이제moveSlide()함수를 사용할 버튼 이벤트 리스너를 추가해준다
다음 버튼을 누르면currentIdx을 증가 시켜줘서 다음 슬라이드로 넘어간다.
반대로 이전 버튼을 누르면 currentIdx을 감소 시켜줘서 이전 슬라이드로 넘어간다.
nextBtn.addEventListener('click', () => {
moveSlide(currentIdx + 1);
});
prevBtn.addEventListener('click', () => {
moveSlide(currentIdx - 1);
});

그다음 첫번째 보고있는 화면을 큰 이미지로 출력 시켜보려면 어떻게 해야할까
우선 addImage()함수를 생성 시켜 num숫자 파라미터 값을 받는다.
num의 숫자를 받아와서 배열안에 알맞는 인덱스에 맞춰서 사진을 꺼낸다.
function addImage(num) {
bigImage.style.background = `center url(${contentArr[num]}) no-repeat`;
}
하지만 배열은 0번 인덱스부터 가지고 있어 currentIdx와 SlideCount가 서로 같아지는 시점이 되면 사진은 다른 인덱스를 호출하여 엉뚱한 이미지를 가져온다.
그래서 nextBtn 이벤트 리스너 안에 if (currentIdx == slideCount) addImage(0);를 넣는다.
슬라이더가 다 돌고 currentIdx와 slideCount가 같아졌을때 0번 인덱스의 사진을 호출 시킨다.
nextBtn.addEventListener('click', () => {
moveSlide(currentIdx + 1);
if (currentIdx == slideCount) {
addImage(0);
} else addImage(currentIdx);
});
이랬을 경우 prevBtn역시 배열을 통해 호출을 하다 보니 currentIdx가 음수가 되어버리면 배열은 음수 인덱스가 존재하지 않으니 아무것도 출력하지 않는다. 그래서 음수가 됐을때 slideCount를 추가해주면 해결이 가능하다.
prevBtn.addEventListener('click', () => {
moveSlide(currentIdx - 1);
if (currentIdx < 0) {
addImage(currentIdx + slideCount);
} else addImage(currentIdx);
});
- 가독성 좋고 설명을 잘하는 것이란 되게 어려운거 같다.. 연습을 많이 해야할거같다😅
- 글을 정리하면서도 코드의 문제점을 찾아냈다.
완성된 코드라도 하나하나 꼼꼼히 봐야겠단 생각이 들었다.