자바스크립트 슬라이드 효과
슬라이드 효과 7
슬라이드 이펙트 중 썸네일과 버튼이 있는 효과입니다.
구조
<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 -->
스크립트_변수 설정
let images = [
"img/sliderEffect04-min.jpg",
"img/sliderEffect05-min.jpg",
"img/sliderEffect03-min.jpg",
"img/sliderEffect09-min.jpg",
"img/sliderEffect10-min.jpg"
];
images라는 변수 안에 배열 형태로 이미지를 저장해줍니다.
스크립트_함수 만들기
function imageSlider(parent, images){
};
imageSlider(document.querySelector(".slider__wrap"), images);
해당 코드는 imageSlider라는 함수를 선언하고, 슬라이더를 감싸고 있는 부모 요소와 이미지들이 들어있는 배열(images)을 매개변수로 받습니다. 하지만 함수 내부의 구현 코드가 비어있으므로, 슬라이더를 만드는 코드를 작성해주어야 합니다.
마지막 줄에서는 작성한 imageSlider 함수를 호출하고, 슬라이더를 감싸고 있는 부모 요소와 이미지들이 들어있는 배열(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")
};
parent: 슬라이더를 감싸고 있는 부모 요소를 가리킵니다.
images: 이미지가 출력될 영역을 가리키는 클래스명이 .slider__img인 요소를 찾아 지정합니다.
thumbnails: 썸네일 이미지가 출력될 영역을 가리키는 클래스명이 .slider__thumb인 요소를 찾아 지정합니다.
prevBtn: 왼쪽 버튼 요소를 가리키는 클래스명이 .prev인 요소를 찾아 지정합니다.
nextBtn: 오른쪽 버튼 요소를 가리키는 클래스명이 .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.images는 이미지가 출력될 영역을 가리키는 요소입니다. images 매개변수로 전달된 배열을 map 메소드로 순회하면서, 각 이미지를 HTML의 img 태그로 변환하여 문자열 배열로 만듭니다. join 메소드로 이를 하나의 문자열로 합친 후, 이를 innerHTML 프로퍼티에 할당하여 슬라이더에 이미지를 출력합니다.
그리고나서 slider.images에서 img 태그들을 querySelectorAll 메소드로 모두 선택한 후, 이들 중에서 현재 활성화되어야 할 이미지를 찾아 classList.add 메소드를 사용하여 active 클래스를 추가합니다. 이를 통해 슬라이더 초기화 시 첫 번째 이미지가 활성화되도록 설정합니다.
스크립트_썸네일 이미지 출력하기, 활성화하기
// 썸네일 이미지 출력하기
slider.thumbnails.innerHTML = slider.images.innerHTML;
// 썸네일 활성화(active)하기
let thumnailNodes = slider.thumbnails.querySelectorAll("img");
thumnailNodes[currentIndex].classList.add("active");
위 코드는 이미지 슬라이더에서 썸네일(thumbnail)을 구성하는 부분입니다. 이미지 슬라이더에 이미지와 썸네일을 함께 보여주기 위해서, 이미지와 같은 HTML 태그(<img>)를 사용하여 썸네일을 구성하고 있습니다.
이미지 출력하기에서와 같이, innerHTML 속성을 이용하여 썸네일을 구성하고 있습니다. 이때, 이미지 출력하기에서 이미지를 구성한 것과 같은 방법으로 map() 메소드를 이용하여 썸네일의 HTML 태그를 생성하고, join() 메소드로 각각의 HTML 태그를 하나의 문자열로 연결하여 썸네일을 구성하고 있습니다.
그리고, 현재 활성화된 이미지와 썸네일을 나타내기 위해서 currentIndex에 대응되는 이미지와 썸네일에 active 클래스를 추가하고 있습니다. 이를 위해서, querySelectorAll() 메소드를 사용하여 이미지와 썸네일의 HTML 태그를 가져오고, classList 속성을 이용하여 클래스를 추가하고 삭제하고 있습니다.
스크립트_썸네일 이미지 클릭하기(for문)
for(let i=0; i<thumnailNodes.length; i++){
thumnailNodes[i].addEventListener("click", function(){ //this값을 가져올 수 있음
slider.thumbnails.querySelector("img.active").classList.remove("active");
thumnailNodes[i].classList.add("active");
imageNodes[currentIndex].classList.remove("active");
currentIndex = i;
imageNodes[currentIndex].classList.add("active");
});
}
이 코드는 썸네일 이미지가 클릭될 때 마다 실행되는 이벤트 리스너를 설정합니다. for문을 통해 썸네일 이미지 노드(thumbnailNodes)를 순회하며 각 썸네일 이미지 노드에 클릭 이벤트 리스너를 등록합니다.
각 썸네일 이미지 노드를 클릭하면 실행되는 함수에서는 현재 active 클래스를 가지고 있는 이미지 노드와 썸네일 이미지 노드의 active 클래스를 모두 제거하고, 클릭된 썸네일 이미지 노드와 해당하는 이미지 노드를 활성화합니다. currentIndex 값도 클릭된 썸네일 이미지 노드의 인덱스 값으로 업데이트 됩니다.
이렇게 하면 썸네일 이미지가 클릭될 때 마다 currentIndex 값과 active 클래스가 변경되어, 슬라이더에서 현재 보여지는 이미지와 썸네일이 변경됩니다.
스크립트_왼쪽, 오른쪽 버튼 클릭하기
// 왼쪽 버튼 클릭하기
slider.prevBtn.addEventListener("click", () => {
imageNodes[currentIndex].classList.remove("active");
currentIndex--;
// 0 4 3 2 1 0 4 3 2 1...
if(currentIndex < 0) currentIndex = images.length - 1;
imageNodes[currentIndex].classList.add("active");
// 썸네일 버튼 클릭하기
thumnailNodes[currentIndex].classList.remove("active");
thumnailNodes[currentIndex].classList.add("active");
});
// 오른쪽 버튼 클릭하기
slider.nextBtn.addEventListener("click", () => {
imageNodes[currentIndex].classList.remove("active");
thumnailNodes[currentIndex].classList.remove("active");
// 1 2 3 4 0 1 2 3 4...
currentIndex = (currentIndex + 1) % images.length;
imageNodes[currentIndex].classList.add("active");
thumnailNodes[currentIndex].classList.add("active");
});
왼쪽 버튼 클릭 시, 현재 활성화된 이미지와 썸네일의 active 클래스를 제거합니다. 그리고 현재 이미지 인덱스(currentIndex)를 감소시킵니다. 만약 currentIndex가 0보다 작아지면 images.length - 1로 설정하여 무한 루프로 이미지를 슬라이드할 수 있습니다. 그리고 새로운 이미지와 썸네일에 active 클래스를 추가합니다.
오른쪽 버튼 클릭 시, 현재 활성화된 이미지와 썸네일의 active 클래스를 제거합니다. 그리고 현재 이미지 인덱스(currentIndex)를 1 증가시킨 후 images.length로 나눈 나머지를 새로운 currentIndex로 설정합니다. 이렇게 하면 currentIndex가 images.length를 초과할 경우 다시 처음으로 돌아가는 무한 루프 슬라이드를 구현할 수 있습니다. 마지막으로, 새로운 이미지와 썸네일에 active 클래스를 추가합니다.