본문 바로가기
Effect/Slider Effect

[자바스크립트 응용하기] 슬라이드 효과05_ 닷메뉴

by 코린이 박원장👶 2022. 10. 23.

슬라이드 효과 05

이번 시간에는 저번 버튼형식의 슬라이더에 추가로 하단에 도트를 추가해보겠습니다.
그리고 당연하게도 이 버튼을 눌렀을때도 이미지가 바뀌게 구성해야 합니다 ^^!


▶ 동그란 도트모양을 만들어주고 이 닷버튼에 JS를 부여해줍니다.
이 때 Index값을 잘 활용하면 아주 쉽게 닷형식의 슬라이더가 완성이 됩니다.

JS 소스

const sliderWrap = document.querySelector('.slider__wrap');
    const sliderImg = document.querySelector('.slider__img');
    const sliderInner = document.querySelector('.slider__inner');
    const slider = document.querySelectorAll('.slider');
    const sliderBtn = document.querySelector('.slider__btn');
    const sliderBtnPrev = sliderBtn.querySelector('.prev');
    const sliderBtnNext = sliderBtn.querySelector('.next');
    const sliderDot = document.querySelector('.slider__dot');

    let currentIndex = 0;
    let sliderCount = slider.length;
    let sliderWidth = sliderImg.offsetWidth; // 이미지 가로 값

    // 이미지 총 길이 넣기
    sliderInner.style.width = (sliderWidth * sliderCount) + "px";

    let dotIndex = "";
    function init() {
        slider.forEach((el, index) => dotIndex += `<a href="#" class="dot">이미지${index + 1}</a>`);
        sliderDot.innerHTML = dotIndex;

        // 첫 번째 닷 버튼한테 활성화 표시
        sliderDot.firstElementChild.classList.add('active');
    }
    init();

    // 이미지이동
    function gotoSlider(num) {
        sliderInner.style.transition = "all 400ms";
        sliderInner.style.transform = "translateX(" + -sliderWidth * num + "px)";
        currentIndex = num;
        console.log(-sliderWidth * num)


        // 두번째 이미지 --> 두번째 닷 클래스 추가
        // 1. 닷메뉴 클래스 모두 삭제
        // 2. 해당 이미지 해당 닷 메뉴 클래스 추가
        const sliderDotAs = sliderDot.querySelectorAll('a');    
        sliderDotAs.forEach((a) => a.classList.remove('active'));
        sliderDotAs[num].classList.add('active');


    }
    // 버튼 클릭시
    document.querySelectorAll(".slider__btn a").forEach((btn, index) => {
        btn.addEventListener("click", () => {
            let prevIndex = (currentIndex + (sliderCount - 1)) % sliderCount;
            let nextIndex = (currentIndex + 1) % sliderCount;

            if (btn.classList.contains("prev")) {
                gotoSlider(prevIndex);
            } else {
                gotoSlider(nextIndex);
            }
        });
    });


    // 닷 버튼 클릭했을 때
    document.querySelectorAll(".slider__dot .dot").forEach((dot, index) => {
        dot.addEventListener("click", () => {
            gotoSlider(index);
        });
    })
                

■ 핵심 찍먹하기🪓

✔ 움직이는 영역에 총이미지의 넓이값을 계산시키자!

-JS-
    sliderInner.style.width = (sliderWidth * sliderCount) + "px";
-CSS-
.slider__inner {
     /* 이미지를 감싸고 있는 부모 : 움직이는 부분 */
    display: flex;
    flex-wrap: wrap;
     height: 450px;
    position: relative;
    이곳에 '이미지 넓이 X 갯수'가 계산되어 들어가게 됩니다.
}

기존 유형들(4유형 제외)은 계속해서 'slider__inner'의 width값이 고정되어 있어서 5개까지만 제대로 출력할 수 있었는데요. 저번 유형부터 저는 이미지의 갯수가 추가되어도 따로 CSS를 수정하지 않아도 되게 하기 위해서 JS에 이미지의 전체 길이를 구하는 코드를 짜 주었습니다.

✔ dot의 html코드는 JS로 넣어주기

이미지의 갯수가 늘어날 때 번거롭게 dot의 html코드를 추가/제거해주기 귀찮을 수 있으므로 JS로 이미지의 인덱스를 구해주어 이미지 갯수만큼 알아서 코드가 변경되게 만들어 줍니다.
이 때, index는 0부터 시작이므로 +1을 해주는 것! 잊지마세요~

✔ dot 선택자 주의하기

const sliderDotAs = sliderDot.querySelectorAll('a');

a태그 전체를 선택해서 당황하셨나요? 잘 보시면 sliderDot라고 적혀있는데요. 이건 저희가 sliderDot이라고 변수를 지정해줬는데 이 변수의 범위안에서만 a 태그를 찾겠단 뜻입니다. 주의해주세요

✔ dot 버튼 클릭하기

닷 버튼을 클릭했을 때 이미 만들어놓은 gotoSlider()함수의 매개변수로 해당 닷의 index를 넣어줍니다. 이미 닷버튼의 갯수는 전체 이미지의 갯수와 같으므로 index는 동일합니다.
그러므로 '2번째 닷 = 2번째 이미지' 이런식으로 이미지를 이동할 수 있습니다.

✔ 혹시 모를 next, prev버튼에 대한 설명

이미 04유형에서 사용했던 방식이며, 코드또한 달라진 점이 없으므로 아무런 수정없이 04유형의 내용을 복붙했습니다. 참고하실분은 아래 버튼을 통해 확인해주세요.
↓↓↓↓↓

next, prev버튼 JS 설명(04유형 내용 재탕)

제 4유형은 이미지가 총 9개입니다. 그럼 각 div의 index은 0부터 8이 됩니다. 그리고 변수 sliderCount는 9입니다.
그럼 오른쪽버튼만 누른다고 생각해볼까요? 이미지의 순서가 어떻게 반복되나요? 0~8이 계속해서 반복하게 짜주면 되겠죠?
여태까지 한 유형들이 다 이런 방식이었어요. '현재이미지+1'을 '전체이미지'로 나눈 값의 '나머지'를 구해서 이 나머지를 익명함수의 변수로 선언해 주면 되겠죠?

첫번째이미지 -> 두번째이미지
     첫번째 이미지(0) -> 두번째이미지(1)로 만들면 되겠죠.

☞ nextIndex = (0 + 1) % 9 즉, 1이 대입되게 됩니다. 그럼 함수의 변수로 1이 들어가므로 -800px만큼 이동하겠네요.(=두번째이미지)


마지막이미지 -> 첫번째이미지
     마지막 이미지(8) -> 첫번째이미지(0)로 만들면 되겠죠.

☞ nextIndex = (8 + 1) % 9 즉, 0이 대입되게 됩니다. 그럼 함수의 변수로 0이 들어가므로 0만큼 이동하겠네요(=최초이미지)

좋아요 여기까지는 쉬워요. 우리가 여태까지 계속 했던방식이니까요. 그럼 이제 왼쪽버튼을 어떻게 구현해야 할까요? 힌트는 드렸습니다. 제 사이트 기준 876543210, 876543210 순으로 되게끔 해주시면 됩니다. 해보면서 느낀게 나머지값을 하나씩 감소시키는건 어렵지 않습니다. 다만 0 다음에 8 이 올 수 있게 만드는게 조금 헷갈리긴 하는데 조금만 바꿔서 생각해보면 되긴 됩니다!
아래는 왼쪽버튼에 대한 설명 들어갑니다.

두번째이미지 -> 첫번째이미지
     두번째 이미지(1) -> 첫번째이미지(0)로 만들면 되겠죠.

☞ nextIndex = (1 + 9-1) % 9 즉, 0이 대입되게 됩니다. 그럼 함수의 변수로 0이 들어가므로 0px만큼 이동하겠네요.(=첫번째이미지)


첫번째이미지 -> 마지막이미지
     첫번째 이미지(0) -> 마지막이미지(8)로 만들면 되겠죠.

잠시 생각해볼까요. 9를 9로 나누면 나머지는 0이 나옵니다. 우리가 원하는건 8이라는 나머지 값인데... 9를 뭘로 나눠야 나머지가 8이 나올까요?
뭘 어떻게 나눠요. 어렵게 생각하지 맙시다 우리!! 그냥 8을 9로 나누면 될 것 같은데요? 그럼 9로는 못 나누니깐 그대로 8이 나머지로 반환되겠죠. 그럼 'nextindex = (0 + x) % 9 ' 0 + x = 8, ∴ currentIndex + 8 이라는 조건이 나옵니다.

이제 이 '(currentIndex + 8)'의 조건으로 다른 값들도 나눠보면 감소가 잘되는지 확인해야 겠죠.
세번째(2) -> 두번째(1)이라고 가정해봅시다. 그럼 이 조건을 활용하면?
nextIndex = (2 + 8) % 9 ∴ nextIndex에 1이 대입됩니다. 원하는 알고리즘을 얻었군요...👍
기세를 몰아 하나만 더 확인해봅시다. 5->4 라면?
nextIndex = (5 + 8) % 9 ∴ nextIndex에 4가 대입! 굿이네요.👍👍👍
이제 왜 8이 아니라 'sliderCount-1'일까요?
왜긴요! sliderCount = 전체갯수잖아요. 그럼 이미지 갯수가 늘어나도 우리가 도출해낸 알고리즘은 계속 유지시킬 수 있어요. 그럼 제가 초반에 말씀드렸던 이미지갯수가 가변되도 js코드를 따로 손대지 않아도 되는 그런 방식이 완성되는 겁니다.

☞ 문제로 돌아가서 얻어낸 정보를 대입해볼까요.
nextIndex = (0 + 9-1) % 9 즉, 8이 대입되게 됩니다. 그럼 함수의 변수로 8이 들어가므로 -6400px만큼 이동하겠네요.(=마지막 이미지)

혹시 여기까지 다 보셨나요? 너무 고생하셨습니다 :)👏


🙇‍♀️ 틀린 점에 대한 지적은 언제나 환영합니다 🙇‍♂️

728x90

댓글


HTML이미지
HTML이미지

JAVASCRIPT

자세히 보기
HTML이미지