본문 바로가기
EFFECT

슬라이드 이펙트 - 버튼 및 닷메뉴, 무한으로 움직이기

by 코빈_ 2022. 10. 23.

슬라이드 이펙트 : 버튼 및 닷메뉴, 무한으로 움직이기

이번 슬라이드 이펙트는 버튼 클릭시 하단에 닷메뉴 작용과 무한으로 움직이게 코딩해봤습니다.

HTML

각 슬라이드 형태에 맞는 이미지를 넣기 위해 각각 이미지를 넣어줬습니다.
또한 스크립트를 짤 때, 그에 맞는 class 이름을 지정해주고 dot도 마찬가지로 형태로 진행하기 위해 html을 구성하였습니다.
주석 표시한 것들은 스크립트에서 적용한 것들 입니다.

HTML CODE
<main id="main">
    <section id="sliderType03">
        <div class="slider__wrap">
            <div class="slider__img">
                <div class="slider__inner">
                    <div class="slider s1"><span>이미지1</span><img src="../assets/img/slide01.jpg" alt="이미지1"></div>
                    <div class="slider s2"><span>이미지2</span><img src="../assets/img/slide02.jpg" alt="이미지2"></div>
                    <div class="slider s3"><span>이미지3</span><img src="../assets/img/slide03.jpg" alt="이미지3"></div>
                    <div class="slider s4"><span>이미지4</span><img src="../assets/img/slide04.jpg" alt="이미지4"></div>
                    <div class="slider s5"><span>이미지5</span><img src="../assets/img/slide05.jpg" alt="이미지5"></div>
                </div>
            </div>
            <div class="slider__btn">
                <button href="#" class="prev">prev</button>
                <button href="#" class="next">next</button>
            </div>
            <div class="slider__dot">
                <!-- <a href="#" class="dot active">image01</a>
                <a href="#" class="dot">image02</a>
                <a href="#" class="dot">image03</a>
                <a href="#" class="dot">image04</a>
                <a href="#" class="dot">image05</a> -->
            </div>
        </div>
    </section>
</main>

CSS

css는 기존에 앞 슬라이드 css와는 비슷하지만. 새로 dot을 작동시킬 때 적용되는 css를 구성하였습니다.
dot에 스타일은 자기가 원하는 형태로 코드를 적용해주시면 됩니다.

CSS CODE
/* slider */
.slider__wrap {
    width: 100%;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}
.slider__img {      /* 이미지를 보이는 영역 */
    position: relative;
    width: 800px;
    height: 450px;
    overflow: hidden;
}
.slider__inner {    /* 이미지를 감싸고 있는 부모 : 움직이는 부분 */
    display: flex;
    flex-wrap: wrap;
    width: 10000px;      /* 총 이미지 6개 */
    height: 450px;
    position: relative;
    left: -800px;
}
.slider__inner.transition {
    transition: all 0.5s;
}
.slider {   /* 개별적인 이미지 */
    position: relative;
    width: 800px;
    height: 450px;
}
.slider span {
    position: absolute;
    left: 5px;
    top: 5px;
    background: rgba(0, 0, 0, 0.4);
    color: #fff;
    padding: 5px 10px;
}

@media(max-width: 800px) {
    .slider__img {
    position: relative;
    width: 400px;
    height: 225px;
    }
}

.slider__btn button {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 50px;
    height: 50px;
    background: rgba(0,0,0,0.4);
    text-align: center;
    line-height: 48px;
    transition: all 0.2s;
    display: block;
    color: #fff;
    pointer-events: auto;
    border: 0;
    cursor: pointer;
}
.slider__btn button:hover {
    border-radius: 50%;
    background: #3b3d6350;
}
.slider__btn.disable button {
    pointer-events: none;
}
.slider__btn button.prev{
    left: 0;
}
.slider__btn button.next{
    right: 0;
}

.slider__dot {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: 20px;
}
.slider__dot .dot {
    width: 20px;
    height: 20px;
    background: rgba(0, 0, 0, 0.4);
    display: inline-block;
    border-radius: 50%;
    text-indent: -9999px;
    transition: all 0.3s;
    margin: 3px;
}
.slider__dot .dot.active {
    background: rgba(255, 255, 255, 0.4);
}

SCRIPT

스크립트는 기존에 있던 슬라이드 이펙트04와 살짝 비슷한 형태이지만, dot에 스크립트를 적용하기 위해 새로운 구성으로 추가 해줬습니다.
또한, 이번에는 무한으로 작동하는 형태의 슬라이드를 스크립트로 코딩했습니다.

SCRIPT CODE
const sliderWrap = document.querySelector(".slider__wrap");            // 전체 이미지 슬라이드
    const sliderImg = document.querySelector(".slider__img");              // 보여지는 영역
    const sliderInner = document.querySelector(".slider__inner");          // 움직이는 영역
    const slider = document.querySelectorAll(".slider");                   // 이미지
    const sliderDot = document.querySelector(".slider__dot");              // 닷 메뉴
    const sliderBtn = document.querySelector(".slider__btn");              // 버튼
    const sliderBtnPrev = document.querySelector(".slider__btn .prev");    // 왼쪽 버튼
    const sliderBtnNext = document.querySelector(".slider__btn .next");    // 오른쪽 버튼

    let currentIndex = 0,
        sliderLength = slider.length,
        sliderWidth = slider[0].offsetWidth,
        sliderFirst = slider[0],                    // 첫번째 이미지
        sliderLast = slider[sliderLength -1],       // 마지막 이미지
        cloneFirst = sliderFirst.cloneNode(true),   // 첫번째 이미지 복사
        cloneLast = sliderLast.cloneNode(true),     // 마지막 이미지 복사
        dotIndex = "";

    sliderInner.appendChild(cloneFirst);
    sliderInner.insertBefore(cloneLast, sliderFirst);

    function init(){
        // 이미지 갯수만큼 닷 메뉴 생기게
        for(let i=0; i<sliderLength; i++){
            dotIndex += "<a href='#' class='dot'>";
        }

        sliderDot.innerHTML = dotIndex;
        sliderDot.firstElementChild.classList.add("active");
    }
    init();

    function gotoSlider(direction){
        sliderInner.classList.add("transition");

        posInitial = sliderInner.offsetLeft;
        console.log(posInitial)

        if(direction == -1){
            sliderInner.style.left = (posInitial + sliderWidth) + "px";
            currentIndex--;
        } else if(direction == 1){
            sliderInner.style.left = (posInitial - sliderWidth) + "px";
            currentIndex++;
        }
    }

    // 순간이동 메서드
    function checkIndex() {
        sliderInner.classList.remove("transition");
        // sliderBtn.classList.add("disable");

        console.log(currentIndex);

        // 마지막 이미지
        if(currentIndex == sliderLength) {
            sliderInner.style.left = -(1 * sliderWidth) + "px";
            currentIndex = 0;
        }

        // 처음 이미지
        if(currentIndex == -1) {
            sliderInner.style.left = -(sliderLength * sliderWidth) + "px";
            currentIndex = sliderLength - 1;
        }
    }

    sliderBtnPrev.addEventListener("click", () => {
        gotoSlider(-1);
        setTimeout(() => {
            sliderBtn.classList.remove("disable");
        },300);
    });
    sliderBtnNext.addEventListener("click", () => {
        gotoSlider(1);
        setTimeout(() => {
            sliderBtn.classList.remove("disable");
        },300);
    });
    
    sliderInner.addEventListener("transitionend", checkIndex);


RESULT

댓글


INFORMATION

javascript

css

html