JAVASCRIPT

슬라이드 이펙트 사용해보기 ( 7 ) 버튼, 썸네일 만들기

김도현2 2023. 4. 14. 15:54
반응형

슬라이드 이펙트 사용해보기 ( 7 ) 버튼, 썸네일 만들기

슬라이드 이펙트를 버튼이나 썸네일을 누르면 이동하는 사이트를 만들어 보겠습니다.

 

 

 

 

 

 

 

 

 

VSCode

<!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>슬라이드 이펙트7</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/slider.css">
    <style>
        /* slider__wrap */
        .slider__wrap {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 800px;
            height: 450px;
            box-shadow: 0 50px 100px rgba(0,0,0,0.4);
        }
        .slider__img {
            position: relative;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        .slider__img img {
            position: absolute;
            width: 100%;
            height: 100%;
            object-fit: cover;
            opacity: 0;
            transform: scale(1.1);
            transition: all 500ms ease-in-out;
        }
        .slider__img img.active {
            opacity: 1;
            transform: scale(1);
        }
        .slider__thumb {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, 140px);
            width: 100px;
            display: flex;
            justify-content: center;
            gap: 10px;
        }
        .slider__thumb img {
            cursor: pointer;
            border: 2px solid transparent;
        }
        
        .slider__thumb img.active {
            border: 2px solid #fff;
        }
        .slider__btn a {
            position: absolute;
            top: 0;
            width: 40px;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 12px;
            color: #fff;
            background-color: rgba(0,0,0,0.1);
            transition: all 300ms ease-in-out;
        }
        .slider__btn a.next {
            right: 0;
        }
        .slider__btn a:hover {
            background-color: rgba(0,0,0,0.5);
        }
        
    </style>
</head>
<body class="img02 bg02 font07">
    <header id="header">
        <h1>Javascript Slider Effect07</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><a href="sliderEffect06.html">6</a></li>
            <li class="active"><a href="sliderEffect07.html">7</a></li>
        </ul>
    </header>
    <!-- //header-->

    <main id="main">
        <div class="slider__wrap">
            <div class="slider__img"></div>
            <div class="slider__thumb"></div>        
            <div class="slider__btn">
                <a href="#" class="prev" title="이전이미지">prev</a>
                <a href="#" class="next" title="다음이미지">next</a>
            </div>
        </div>
    </main>
    <!-- //main-->

    <footer id="footer">
        <a href="mailto:ehcjswo1@gmail.com">ehcjswo1@gmail.com</a>
    </footer>
    <!-- //footer-->
    
    <script>
        let images = [
            "./img/SliderEffect06-min.jpg",
            "./img/SliderEffect07-min.jpg",
            "./img/SliderEffect08-min.jpg",
            "./img/SliderEffect09-min.jpg",
            "./img/SliderEffect10-min.jpg",
        ];

        function imageSlider(parent){
            let currentIndex = 0; 

            //선택자
            let slider = {
                parent: parent,
                images: parent.querySelector(".slider__img"),
                thumnails: parent.querySelector(".slider__thumb"),
                prevBtn: parent.querySelector(".slider__btn .prev"),
                nextBtn: parent.querySelector(".slider__btn .next")
            }
            //이미지 출력하기
            slider.images.innerHTML = images.map((image, index) => {
                return `<img src="${image}" alt="이미지${index}">`;
            }).join("");    //join: 소스에 ,(쉼표) 없애기

            //이미지 활성화(active)하기
            let imageNodes = slider.images.querySelectorAll("img");
            imageNodes[currentIndex].classList.add("active");

            //썸네일 이미지 출력하기
            slider.thumnails.innerHTML = slider.images.innerHTML;

            

            // 썸네일 활성화(active)하기
            let thumnailNodes = slider.thumnails.querySelectorAll("img");
            thumnailNodes[currentIndex].classList.add("active");

            //썸네일 이미지 클릭하기
            // for(let i=0; i<thumnailNodes.length; i++){
            //     thumnailNodes[i].addEventListener("click", function(){
            //         slider.thumnails.querySelector("img.active").classList.remove("active");
            //         thumnailNodes[i].classList.add("active");

            //         imageNodes[currentIndex].classList.remove("active");
            //         currentIndex = i;
            //         imageNodes[currentIndex].classList.add("active");

            //     });
            // }

            thumnailNodes.forEach((el, i) => {
                el.addEventListener("click", () => {
                    slider.thumnails.querySelector("img.active").classList.remove("active");
                    el.classList.add("active");

                    imageNodes[currentIndex].classList.remove("active");
                    currentIndex = i;
                    imageNodes[currentIndex].classList.add("active");
                })
            })

            //왼쪽 버튼 클릭
            slider.prevBtn.addEventListener("click", function(){
                imageNodes[currentIndex].classList.remove("active");
                currentIndex--

                //0 4 3 2 1 0 4 3 ...
                if(currentIndex < 0) currentIndex = images.length - 1;
                imageNodes[currentIndex].classList.add("active");
                // thumnailNodes[currentIndex].classList.add("active");
                //썸네일
                slider.thumnails.querySelector("img.active").classList.remove("active");
                thumnailNodes[currentIndex].classList.add("active");
            });

            //오른쪽 버튼 클릭
            slider.nextBtn.addEventListener("click", function(){
                imageNodes[currentIndex].classList.remove("active");
                // thumnailNodes[currentIndex].classList.remove("active");
                // currentIndex++

                //1 2 3 4 1 2 3 4 ...
                currentIndex = (currentIndex + 1 ) % images.length;
                
                imageNodes[currentIndex].classList.add("active");
                // thumnailNodes[currentIndex].classList.add("active");

                //썸네일
                slider.thumnails.querySelector("img.active").classList.remove("active");
                thumnailNodes[currentIndex].classList.add("active");
            });
            
        } 

        imageSlider(document.querySelector(".slider__wrap"), images);

        
    </script>


        
</body>
</html>

 

 

이 코드는 자바스크립트를 사용하여 이미지 슬라이더를 만드는 코드입니다. 슬라이더는 주어진 영역 안에서 이미지를 보여주고, 다음/이전 버튼을 클릭하거나 썸네일을 클릭하여 이미지를 전환할 수 있습니다.

 

.slider__wrap: 슬라이더 영역을 감싸는 가장 바깥 div입니다. position: absolute와 transform 속성을 사용하여 중앙 정렬을 합니다.

.slider__img: 실제 이미지가 들어갈 div입니다. overflow: hidden 속성을 사용하여 이미지를 가립니다.

.slider__img img: 이미지 요소입니다. opacity와 transform 속성을 사용하여 이미지가 전환되는 애니메이션 효과를 줍니다.

.slider__thumb: 썸네일 이미지를 보여주는 div입니다.

.slider__thumb img: 썸네일 이미지 요소입니다. 클릭하면 해당 이미지로 전환됩니다.

.slider__btn: 이전/다음 버튼을 보여주는 div입니다.

 

 

 

 

script

let images = [
    "./img/SliderEffect06-min.jpg",
    "./img/SliderEffect07-min.jpg",
    "./img/SliderEffect08-min.jpg",
    "./img/SliderEffect09-min.jpg",
    "./img/SliderEffect10-min.jpg",
];

function imageSlider(parent){
    let currentIndex = 0; 

    //선택자
    let slider = {
        parent: parent,
        images: parent.querySelector(".slider__img"),
        thumnails: parent.querySelector(".slider__thumb"),
        prevBtn: parent.querySelector(".slider__btn .prev"),
        nextBtn: parent.querySelector(".slider__btn .next")
    }
    //이미지 출력하기
    slider.images.innerHTML = images.map((image, index) => {
        return `<img src="${image}" alt="이미지${index}">`;
    }).join("");    //join: 소스에 ,(쉼표) 없애기

    //이미지 활성화(active)하기
    let imageNodes = slider.images.querySelectorAll("img");
    imageNodes[currentIndex].classList.add("active");

    //썸네일 이미지 출력하기
    slider.thumnails.innerHTML = slider.images.innerHTML;

이미지들의 경로를 저장한 images 배열이 정의됩니다.

그리고 imageSlider 함수가 정의됩니다. 이 함수는 슬라이더를 생성하기 위한 부모 요소를 인자로 받습니다.

함수 내부에서는 currentIndex 변수가 초기화됩니다. 이 변수는 현재 보여지는 이미지의 인덱스를 저장합니다.

그리고 slider 객체가 정의됩니다. 이 객체는 슬라이더를 구성하는 다양한 요소들을 선택하기 위한 선택자들을 포함하고 있습니다.

 

slider.images는 이미지를 보여주는 요소, slider.thumbnails는 썸네일 이미지를 보여주는 요소입니다.

slider.prevBtn과 slider.nextBtn은 각각 슬라이더를 이전 이미지 또는 다음 이미지로 이동시키는 버튼 요소입니다.

slider.images의 내부 HTML을 구성하는 부분에서 map 함수를 사용해 images 배열의 각각의 이미지를 img 요소로 만듭니다. 이때 alt 속성은 "이미지"와 그 인덱스를 조합해서 설정됩니다.

 

이미지들이 HTML에 출력된 이후에는, imageNodes 변수를 사용해 slider.images 내부의 img 요소들을 선택합니다.

imageNodes의 첫 번째 요소에 active 클래스를 추가하여 초기 상태에서 첫 번째 이미지가 활성화됩니다.

마지막으로, slider.thumbnails의 내부 HTML을 slider.images의 내부 HTML과 동일하게 설정합니다. 이렇게 하면 이미지와 썸네일 이미지가 동일한 내용으로 출력됩니다.

 

 

 

 

// 썸네일 활성화(active)하기
    let thumnailNodes = slider.thumnails.querySelectorAll("img");
    thumnailNodes[currentIndex].classList.add("active");

    //썸네일 이미지 클릭하기
    // for(let i=0; i<thumnailNodes.length; i++){
    //     thumnailNodes[i].addEventListener("click", function(){
    //         slider.thumnails.querySelector("img.active").classList.remove("active");
    //         thumnailNodes[i].classList.add("active");

    //         imageNodes[currentIndex].classList.remove("active");
    //         currentIndex = i;
    //         imageNodes[currentIndex].classList.add("active");

    //     });
    // }

    thumnailNodes.forEach((el, i) => {
        el.addEventListener("click", () => {
            slider.thumnails.querySelector("img.active").classList.remove("active");
            el.classList.add("active");

            imageNodes[currentIndex].classList.remove("active");
            currentIndex = i;
            imageNodes[currentIndex].classList.add("active");
        })
    })

    //왼쪽 버튼 클릭
    slider.prevBtn.addEventListener("click", function(){
        imageNodes[currentIndex].classList.remove("active");
        currentIndex--

        //0 4 3 2 1 0 4 3 ...
        if(currentIndex < 0) currentIndex = images.length - 1;
        imageNodes[currentIndex].classList.add("active");
        // thumnailNodes[currentIndex].classList.add("active");
        //썸네일
        slider.thumnails.querySelector("img.active").classList.remove("active");
        thumnailNodes[currentIndex].classList.add("active");
    });

    //오른쪽 버튼 클릭
    slider.nextBtn.addEventListener("click", function(){
        imageNodes[currentIndex].classList.remove("active");
        // thumnailNodes[currentIndex].classList.remove("active");
        // currentIndex++

        //1 2 3 4 1 2 3 4 ...
        currentIndex = (currentIndex + 1 ) % images.length;

        imageNodes[currentIndex].classList.add("active");
        // thumnailNodes[currentIndex].classList.add("active");

        //썸네일
        slider.thumnails.querySelector("img.active").classList.remove("active");
        thumnailNodes[currentIndex].classList.add("active");
    });

} 

imageSlider(document.querySelector(".slider__wrap"), images);

imageSlider() 함수는 parent 인자를 받아 해당 요소 내부에 이미지 슬라이더를 생성합니다. 이 함수는 다음과 같이 작동합니다.

 

초기화

  • currentIndex 변수를 0으로 설정합니다.
  • slider 객체를 생성합니다. 이 객체는 이미지 슬라이더 요소들의 선택자를 포함합니다.
  • slider.images와 slider.thumnails의 내부에 이미지를 추가합니다.
  • currentIndex에 해당하는 이미지와 썸네일에 active 클래스를 추가합니다.

 

썸네일 이미지 클릭 이벤트 등록

  • 썸네일 이미지들에 대해 forEach 메서드를 사용하여 클릭 이벤트를 등록합니다. 클릭 시 현재 이미지와 썸네일에서 active 클래스를 제거하고, 클릭된 이미지와 썸네일에 active 클래스를 추가합니다.

 

왼쪽/오른쪽 버튼 클릭 이벤트 등록

  • 왼쪽 버튼이 클릭된 경우, 현재 이미지와 썸네일에서 active 클래스를 제거하고 currentIndex를 1 감소시킵니다. currentIndex가 0보다 작아지면 images.length - 1로 설정합니다.
  • 오른쪽 버튼이 클릭된 경우, 현재 이미지와 썸네일에서 active 클래스를 제거하고 currentIndex를 1 증가시킵니다. currentIndex가 images.length와 같아지면 0으로 설정합니다.

 

이후, imageSlider() 함수를 호출하여 슬라이더를 생성합니다. document.querySelector(".slider__wrap")은 슬라이더를 감싸는 요소를 선택하며, images 배열은 슬라이더에 표시할 이미지 경로들을 포함합니다.