Bomb Kirby Running

JAVASCRIPT

슬라이드 이펙트 06

^. ̫ .^ 2023. 4. 13. 20:47

728x90

오늘은 닷메뉴가 있는 슬라이드 이펙트를 만들어 보았습니다. prev를 누르면 전 이미지로, next를 누르면 다음 이미지로, 닷 메뉴를 누르면 해당 순서의 사진으로 이동합니다.

 

HTML

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>06. 슬라이드 이펙트</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/slider.css">
    <style>
        /* slider__wrap */
        .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: 4800px;  /* 총 이미지 4800 */
            height: 2250px;
        }
        .slider {   /*개별적인 이미지*/
            position: relative;
            width: 800px;
            height: 450px;
        }
        .slider__btn a {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            width: 50px;
            height: 50px;
            line-height: 50px;
            text-align: center;
            background-color: #fff;
            transition: all 0.3s ease;
        }
        .slider__btn a:hover {
            border-radius: 50%;
            background-color: rgb(86, 166, 241);
        }
        .slider__btn a.prev {
            left: 0;
        }
        .slider__btn a.next {
            right: 0;
        }
        .slider__dot {
            position: absolute;
            left: 50%;
            bottom: 50px;
            transform: translateX(-50%);
        }
        .slider__dot .dot {
            width: 20px;
            height: 20px;
            background-color: rgba(255, 255, 255, 0.3);;
            display: inline-block;
            border-radius: 50%;
            text-indent: -9999px;
            transition: all 0.3s;
            margin: 3px;
        }
        .slider__dot .dot.active {
            background-color: rgba(255, 255, 255, 1);
        }
    </style>
</head>
<body class="img05 bg09 font07">
    <header id="header">
        <h1>JavaScript Slider Effect06</h1>
        <p>슬라이드 이펙트 : 이미지 슬라이드(버튼, 닷메뉴)</p>
        <ul>
            <li><a href="sliderEffect01.html">1</a></li>
            <li><a href="sliderEffect02.html">2</a></li>
            <li><a href="sliderEffect03.html">3</a></li>
            <li><a href="sliderEffect04.html">4</a></li>
            <li><a href="sliderEffect05.html">5</a></li>
            <li  class="active"><a href="sliderEffect06.html">6</a></li>
            <li><a href="sliderEffect07.html">7</a></li>
        </ul>
    </header>
    <!-- //header-->

    <main id="main">
        <div class="slider__wrap">
            <div class="slider__img">
                <div class="slider__inner">
                    <div class="slider s1"><img src="./img/sliderEffect02-min.jpg" alt=""></div>
                    <div class="slider s2"><img src="./img/sliderEffect03-min.jpg" alt=""></div>
                    <div class="slider s3"><img src="./img/sliderEffect04-min.jpg" alt=""></div>
                    <div class="slider s4"><img src="./img/sliderEffect05-min.jpg" alt=""></div>
                    <div class="slider s5"><img src="./img/sliderEffect06-min.jpg" alt=""></div>
                </div>
            </div>
            <div class="slider__btn">
                <a href="#" class="prev" title="이전이미지">prev</a>
                <a href="#" class="next" title="다음이미지">next</a>
            </div>
            <div class="slider__dot">
                <!-- <a href="#" class="active dot">이미지1</a>
                <a href="#" class="dot">이미지2</a>
                <a href="#" class="dot">이미지3</a>
                <a href="#" class="dot">이미지4</a>
                <a href="#" class="dot">이미지5</a> -->
            </div>
        </div> 
    </main>
    <!-- //main-->
</body>
</html>

이번엔 아래쪽에 닷 메뉴가 있으므로 footer는 없애주었습니다.

 

script

선택자

        //선택자
        const sliderWrap = document.querySelector(".slider__wrap");
        const sliderImg = sliderWrap.querySelector(".slider__img");     //보여지는 영역
        const sliderInner = sliderWrap.querySelector(".slider__inner"); //움직이는 영역
        const slider = sliderWrap.querySelectorAll(".slider");          //개별 이미지
        const sliderDot = sliderWrap.querySelector(".slider__dot");     //닷메뉴
        const sliderBtn = sliderWrap.querySelectorAll(".slider__btn a")    //버튼

        let currentIndex = 0;                       //현재 보이는 이미지
        let sliderCount = slider.length;            //전체 이미지 갯수
        let sliderInterval = 1000;                  //이미지 변경 간격 시간
        let sliderWidth = slider[0].offsetWidth;    //이미지 가로값
        let dotIndex = "";

선택자로 각 요소들을 선택해주고 변수들은 값을 설정해줍니다.

 

닷메뉴 생성 및 활성화

      function init(){
            //이미지 갯수만큼 닷 메뉴 생성
            slider.forEach(() => dotIndex += "<a href='#' class='dot'>이미지2</a>");
            sliderDot.innerHTML = dotIndex;
            //첫번째 닷 메뉴한테 활성화 표시하기
            sliderDot.firstChild.classList.add("active");
        }
        init();

dotIndex에 += 를 통해 이미지 링크를 반복해줍니다.

sliderDot의 내부HTML을 반복된 이미지 링크가 있는 dotIndex값으로 설정합니다.

이러면 요소 내부에 이미지 링크가 반복된 모양새를 가진 닷 메뉴들이 생성됩니다.

그리고 첫번째 닷 메뉴를 active 클래스를 추가해주어 활성화 해주었습니다.

 

이미지 이동 및 전체 닷메뉴 활성화

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

            //닷메뉴 활성화 하기
            let dotActive = document.querySelectorAll(".slider__dot .dot");
            dotActive.forEach((active) => active.classList.remove("active"));
            dotActive[num].classList.add("active");
        }

sliderInner에 style을 transition을 주어 모두 0.4초로 설정해서 이미지 이동 시 애니메이션 효과가 적용되도록 합니다.

transform 속성에는 현재 화면에서 보이는 이미지 슬라이더를 x축으로 원하는 위치를 이동시킬 수 있도록 설정해줍니다.

currnetIndex에 num값을 할당하여 현재 보이는 이미지 슬라이더의 인덱스 값을 바꿔줍니다.

dotActive 변수를 사용해 닷 메뉴에서 현재 활성화된 요소를 찾고 active 클래스를 추가해 활성화 해줍니다.

 

버튼/닷메뉴 클릭

        //버튼을 클릭했을 때
        sliderBtn.forEach((btn, index)=>{
            btn.addEventListener("click",() => {
                let prevIndex = (currentIndex + (sliderCount-1)) % sliderCount;
                let nextIndex = (currentIndex + 1) % sliderCount;//1 2 3 4 0 1 2 3 4
                if(btn.classList.contains("prev")){
                gotoSlider(prevIndex);
                } else {
                gotoSlider(nextIndex);
                }
            })
        });

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

버튼을 클릭했을때 콜백함수는 이미지 슬라이더를 이동시키는 gotoSlider를 호출합니다.

prev버튼을 클릭하면 prevIndex 변수에 (currentIndex + (sliderCount-1)) % sliderCount 값을 할당합니다.

(currentIndex + (sliderCount-1))은 현재 인덱스에서 1을 빼고, sliderCount로 나눈 나머지를 계산하는 것을 의미합니다.

next 버튼을 클릭하면, nextIndex 변수에 (currentIndex + 1) % sliderCount 값을 할당합니다.

(currentIndex + 1)은 현재 인덱스에서 1을 더하고, sliderCount로 나눈 나머지를 계산하는 것을 의미합니다.

btn.classList.contains("prev")를 사용하여 현재 클릭한 버튼이 "이전" 버튼인지 "다음" 버튼인지를 구분하고, gotoSlider() 함수를 호출하여 계산된 인덱스 값을 전달합니다.

 

dot 메뉴를 클릭했을때는 queryselector로 slider__dot 안의 dot을 모두 선택해줍니다. 그리고 콜백함수로 이미지 슬라이더를 이동시키는 gotoSlider를 호출하고 index 매개변수는 각각의 닷 메뉴 요소에 대한 인덱스 값을 나타내며, gotoSlider() 함수를 호출할 때 이 값을 전달합니다.

gotoSlider() 함수에서는 index 값을 인자로 받아 해당 인덱스에 해당하는 이미지 슬라이더로 이동하도록합니다.

 

이렇게 하면 위의 예시처럼 닷메뉴가 있는 이미지 슬라이더를 만들 수 있습니다!