예제로 공부하기/슬라이드 효과

썸네일 슬라이드

Hyeon been 2023. 4. 14. 17:54

한번씩 읽고 가세요.

“ 훌륭한 코드는 훌륭한 문서보다 낫다. ”

- Steve McConnell
개발자
728x90

슬라이드 07

이번 슬라이드 유형은 썸네일 이미지와 썸네일 이미지를 누르면 이미지까지 바뀌는 효과를 내주려 합니다.

html 코드

<body class="img03 bg01 font04">
    <header id="header">
        <h1>Javasrcipt 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:esansi@naver.com">esansi@naver.com</a>
    </footer>

이번엔 이미지를 변수의 배열로 넣어 작업하였습니다.

let images = [
            "./img/slider06-min.jpg",
            "./img/slider04-min.jpg",
            "./img/slider09-min.jpg",
            "./img/slider07-min.jpg",
            "./img/slider04-min.jpg",
        ];

그리고 선택자 또한 다른 방법으로 사용했다.

function imageSlider(parent, images) {
            let currentIndex = 0;   //현재보이는 이미지

            // 선택자
            let slider = {
                parent: parent,
                images: parent.querySelector(".slider__img"),
                thumbnails: 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("");

함수 이미지 슬라이더를 생성해줍니다.

**function imageSlider(parent, images)**는 함수의 선언부입니다. 이 함수는 **parent**와 **images**라는 두 개의 매개변수를 받습니다. **parent**는 이미지 슬라이더가 부착될 부모 요소를 나타내는 매개변수이고, **images**는 이미지 슬라이더에 표시될 이미지들을 포함하는 배열(Array)을 나타내는 매개변수입니다.

이 함수는 이미지 슬라이더를 생성하고, parent 요소에 해당 슬라이더를 부착하는 기능을 제공합니다. 구체적인 사용법은 이 함수를 호출하여 이미지 슬라이더를 생성하고, parent 요소와 images 배열을 인자로 전달하는 것입니다. 예를 들면 다음과 같이 사용할 수 있습니다.

let slider = {
                parent: parent,
                images: parent.querySelector(".slider__img"),
                thumbnails: 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("");

slider(".slider__img")안에 images를 innerHTML로 불러와 줍니다. images를map을 사용하여 배열로 불러 와줍니다. 배열로 불러왔기 때문에 join을 사용해 ,를 없애줍니다.

slider.thumbnails.innerHTML = slider.images.innerHTML;

그 다음 썸네일 사진도 출력해줍니다. slider thumbnails(".slider__thumb") 안에 images를 출력해줍니다.

그 후

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

                if (currentIndex < 0) currentIndex = images.length - 1;
                imageNodes[currentIndex].classList.add("active")

                //썸네일

                slider.thumbnails.querySelector("img.active").classList.remove("active")
                thumnaliNodes[currentIndex].classList.add("active")

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

                currentIndex = (currentIndex + 1) % images.length;
                imageNodes[currentIndex].classList.add("active")

                //썸네일
                slider.thumbnails.querySelector("img.active").classList.remove("active")

                thumnaliNodes[currentIndex].classList.add("active")

            });

slider안 btn들에게 addEventListener 를 사용해 click 이벤트를 부여합니다.

왼쪽 버튼은

imageNodes[currentIndex].classList.remove("active") 전 이미지로 넘어가야하기 때문에

currentIndex—를 사용해 숫자를 줄여줄것입니다.

active를 다 지워줍니다. 마이너스로 넘어가면 이미지가 없기 때문에

            if (currentIndex < 0) currentIndex = images.length - 1;
            imageNodes[currentIndex].classList.add("active")

만약 현재이미지가 0 아래로 내려가면 현재이미지는 이미지 갯수 -1 에 액티브를 부여한다는 조건을 붙여 줍니다.

            slider.thumbnails.querySelector("img.active").classList.remove("active")
            thumnaliNodes[currentIndex].classList.add("active")

썸네일 사진은 똑같이 액티브를 지워준후 현재 보여지는 이미지에 액티브를 부여해줍니다.

오른쪽 버튼도

imageNodes 이미지안 이미지에 [현재보여지는 이미지]에 classList.remove를 사용해 active를 지웁니다. 그 뒤에 currentIndex 는 (currentIndex + 1) % images.length로 해주고 imageNodes[currentIndex].classList.add("active") active를 다시 부여해줍니다.

썸네일 사진은 똑같이 액티브를 지워준후 현재 보여지는 이미지에 액티브를 부여해줍니다.

마지막으로 썸네일을 클릭하면 활성화되는 스크립트를 주려한다.

let thumnaliNodes = slider.thumbnails.querySelectorAll("img");

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

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

변수 thumnaliNodes는 slider안에 thumbnails의 img들 이라는 변수를 만납니다.

그 안에 for문을 이용해 그 썸네일 안 이미지들에게 thumnaliNodes[i] 클릭하면 썸네일 이미지 중 현재 활성화 된 active를 지워 줍니다. 그리고 클릭한 thumnaliNodes[i] 에 액티브를 부여하여 썸네일 이미지를 선택하면 그 이미지가 활성화 되게 해줍니다.

이미지 안에 이미지도 active를 지우고 활성화 시켜주는데 동시에 진행 되서 반응이 없는 거 처럼 보이기 때문에 그 사이에 currentIndex = i 로 바꿔줍니다. 그럼 image[i]에 active를 부여해줍니다. 그럼 완성.

<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.8);
        }

        .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%, 180%);
            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: 45px;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #fff;
            font-size: 12px;
            background-color: rgba(0, 0, 0, 0.2);
            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>