TIL - 좌우 슬라이더 만들기(JS)

rain98·2021년 4월 20일
3

TIL

목록 보기
5/32
post-thumbnail
post-custom-banner

스터디 과정중 자기소개 페이지의 좌우 슬라이더를 구현할 일이 생겼다. 요 슬라이더를 매우
간단하게 슬라이더 라이브러리인 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()함수를 이용해 가운데 위치로 보내줘야한다.
slideMarginslidesWidth값을 계산해서 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를 이동한 횟수로 변수로 두자.
slideCountcurrentIdx가 "서로 같다면" 이라는 조건하에 움직이면 되겠다.

반대로 오른쪽이 아닌 왼쪽으로 슬라이더 할 경우도 있으니 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);를 넣는다.
슬라이더가 다 돌고 currentIdxslideCount가 같아졌을때 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);
});

출처 : https://www.youtube.com/watch?v=7rTW0mndIy0&list=PL-qMANrofLyvzqz2yYzNectJnYo5ZifE7&index=53&ab_channel=Rock%27sEasyweb

  • 가독성 좋고 설명을 잘하는 것이란 되게 어려운거 같다.. 연습을 많이 해야할거같다😅
  • 글을 정리하면서도 코드의 문제점을 찾아냈다.
    완성된 코드라도 하나하나 꼼꼼히 봐야겠단 생각이 들었다.
profile
헷갈리거나 기억에 남기고 싶은것을 기록합니다.
post-custom-banner

0개의 댓글