Lumpy Space Princess - Adventure Time

JAVASCRIPT

Slider Effect 07 - 썸네일 슬라이드의 버튼과 닷메뉴에 대해서 알아보자

jongyung 2023. 4. 14. 22:11

“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90

설명:

이미지 위에 썸네일을 띄웠습니다.

왼쪽과 오른쪽에는 preview 버튼과 next 버튼을 만들어서 각자 클릭했을 때 해당하는 이미지가 순서대로 나오도록 설정했습니다.

 

body 의 main 와 script 로 나눠서 설명하겠습니다.

body 의 main

<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>

body 의 구조는 간단합니다.

이미지 전체가 나오는 영역을 slider__img 로 정하고, 썸네일과 버튼의 영역도 각각 slider__thumb, slider__btn 로 정했습니다.

이미지의 왼쪽과 오른쪽에 위치한 preview 와 next 버튼도 각각의 class를 정했습니다.

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, imgaes){
    let currentIndex = 0; //현재 보이는 이미지, 첫 번째라서 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("");

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

    // 썸네일 출력
    slider.thumbnails.innerHTML = slider.images.innerHTML;

    // 썸네일 활성화 active
    let thumbnailNodes = slider.thumbnails.querySelectorAll("img");
    thumbnailNodes[currentIndex].classList.add("active");
    
    // forEach
    thumbnailNodes.forEach(function(thumbnailNodes, i){
        thumbnailNodes.addEventListener("click", function(){
            slider.thumbnails.querySelector("img.active").classList.remove("active");
            thumbnailNodes.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");

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

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

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

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

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

이미지를 배열로 만들었습니다.
이렇게 배열로 만들면 함수에서 불러올 때 배열의 형식으로 불러오면 되기 때문에 편리합니다.

 

선택자에서 parent는 변수로, 이전에 정의 된 부모 요소를 참조합니다.

변수 이름에서 유추할 수 있듯이, 이 변수는 슬라이더가 속한 부모 요소를 참조합니다.

 

예를 들어, HTML에서 슬라이더 요소가 다음과 같이 정의되어 있다고 가정해 봅시다.

<div class="slider-wrapper">
  <div class="slider">
    <!-- 슬라이더 이미지 및 썸네일 요소 등 -->
  </div>
</div>

위 코드에서 parent 변수는 slider 요소의 부모 요소인 slider-wrapper 를 참조합니다.

따라서 slider 객체는 slider-wrapper 내에서 찾을 수있는 슬라이더 이미지, 썸네일, 이전 및 다음 버튼과 같은 슬라이더의 다른 요소를 참조합니다.

즉, parent는 슬라이더가 속한 부모 요소를 나타내는 일종의 상위 요소를 가리키는 변수로 사용합니다.

 

이미지를 출력하는 코드는 images 변수가 참조하는 요소 내에 HTML 문자열을 동적으로 생성하여, 각 이미지에 대한 img 태그를 생성하고 이를 해당 요소에 삽입합니다.

이 코드에서는 images 변수가 참조하는 요소가 이미지 슬라이더에서 이미지가 표시되는 영역을 가리킨다고 가정합니다. 이 영역에는 이미지에 대한 img 태그가 있어야 하며, 각각의 img 태그는 이미지를 표시하는 데 사용됩니다.

따라서, images 변수가 참조하는 요소 내에 img 태그를 동적으로 생성하기 위해, 배열 images를 사용하여 이미지 경로를 포함하는 img 태그 문자열을 생성하는 것입니다.

 

map() 함수는 배열 images의 각 요소에 대해 콜백 함수를 호출하며, 이 콜백 함수는 img 태그 문자열을 생성합니다.

이때 join() 함수를 사용하여 각 img 태그 문자열을 연결하고, 최종적으로 생성된 HTML 문자열을 innerHTML 프로퍼티를 통해 images 변수가 참조하는 요소에 할당합니다.

예를 들어, images 배열이 다음과 같다면:

const images = ["image1.jpg", "image2.jpg", "image3.jpg"];

위 코드는 다음과 같은 HTML 문자열을 생성하고 "images" 변수가 참조하는 요소 내에 삽입합니다.

<img src="image1.jpg" alt="이미지0">
<img src="image2.jpg" alt="이미지1">
<img src="image3.jpg" alt="이미지2">

이렇게 생성된 img 태그들은 이미지 슬라이더에 표시되는 각 이미지를 나타냅니다.

 

이미지를 활성화하는 코드는 slider.images 변수가 참조하는 요소 내의 img 태그를 선택하고, 그 중 현재 슬라이드의 인덱스(currentIndex)에 해당하는 이미지에 active 클래스를 추가하는 것입니다.

slider.images 변수는 슬라이더의 이미지를 표시하는 요소를 가리킵니다. 이 요소 내의 모든 img 태그는 슬라이더에서 표시되는 각 이미지를 나타냅니다. 따라서, slider.images.querySelectorAll("img")는 slider.images 변수가 참조하는 요소 내의 모든 img 태그를 선택합니다.

그 다음, imageNodes[currentIndex]는 imageNodes 배열에서 현재 슬라이드의 인덱스에 해당하는 img 태그를 선택합니다. 이렇게 선택된 img 태그에 active 클래스를 추가하면, 해당 이미지가 슬라이더 내에서 활성화된 이미지로 표시됩니다.

예를 들어, 현재 슬라이드 인덱스가 1인 경우, imageNodes[1]은 두 번째 img 태그를 선택하고, classList.add("active")를 사용하여 해당 img 태그에 active 클래스를 추가합니다. 따라서, 슬라이더에서 두 번째 이미지가 활성화됩니다.

 

썸네일을 출력하는 코드는 이미지를 출력하는 코드와 같습니다.

 

썸네일을 활성화하는 코드는 이미지를 활성화하는 코드와 같은 방식으로 만들었습니다.

 

썸네일을 클릭하면 이미지가 바뀌는 코드는 thumbnailNodes 배열에 포함된 각 요소에 대해 클릭 이벤트를 추가하고, 클릭된 썸네일에 해당하는 이미지를 활성화시키는 것입니다.

thumbnailNodes는 슬라이더의 썸네일 이미지를 표시하는 요소를 선택하며, querySelectorAll() 메서드를 사용하여 선택된 모든 썸네일 이미지를 thumbnailNodes 배열에 저장합니다. 각각의 썸네일 이미지는 i 변수를 사용하여 인덱스를 가지며, 클릭 이벤트를 추가합니다.

클릭 이벤트가 발생하면, 현재 활성화된 썸네일 이미지의 active 클래스를 제거하고, 클릭된 썸네일 이미지에 active 클래스를 추가합니다. 이렇게 함으로써, 클릭된 썸네일 이미지가 활성화됩니다.

그리고, 현재 슬라이드 인덱스에 해당하는 이미지에서 active 클래스를 제거하고, 클릭된 썸네일 이미지의 인덱스를 사용하여 새로운 슬라이드 인덱스(currentIndex)를 설정합니다. 마지막으로, 새로운 슬라이드 인덱스에 해당하는 이미지에 active 클래스를 추가하여 해당 이미지가 활성화됩니다.

예를 들어, 썸네일 이미지 중 첫 번째 이미지가 클릭되었을 경우, thumbnailNodes[0]은 첫 번째 썸네일 이미지를 가리키고, 해당 요소에 클릭 이벤트가 추가됩니다. 클릭 이벤트가 발생하면, 첫 번째 썸네일 이미지에 active 클래스가 추가되고, 슬라이드 인덱스도 0으로 설정됩니다. 따라서, 슬라이더 내에서 첫 번째 이미지가 활성화됩니다.