완성 화면
코드 보기 / CSS
.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.5);
}
.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.2);
transition: all 600ms ease-in-out;
}
.slider__img img.active {
opacity: 1;
transform: scale(1);
}
.slider__thumnail{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, 240px);
width: 100px;
display: flex;
justify-content: center;
gap: 10px;
}
.slider__thumnail img{
cursor: pointer;
border: 3px solid transparent;
}
.slider__thumnail img.active {
border: 3px solid #fff
}
.slider__btn a {
position: absolute;
top: 0;
width: 100px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 13px;
background-color: rgba(0, 0, 0, 0.3);
color: #fff;
transition: all 400ms ease-in-out;
}
.slider__btn a:hover{
background-color: rgba(255, 255, 255, 0.2);
}
.slider__btn a.next {
right: 0;
}
.slider__btn a.previous {
left: 0;
}
코드 보기 / HTML
<main id="main">
<div class="slider__wrap">
<div class="slider__img"></div>
<div class="slider__thumnail"></div>
<div class="slider__btn">
<a href="#" class="previous">previous (이전)</a>
<a href="#" class="next">next (다음)</a>
</div>
</div>
</main>
코드 보기 / JAVASCRIPT
let images = [
"img/sliderEffect01-min.jpg",
"img/sliderEffect02-min.jpg",
"img/sliderEffect03-min.jpg",
"img/sliderEffect04-min.jpg",
"img/sliderEffect05-min.jpg",
"img/sliderEffect07-min.jpg",
"img/sliderEffect08-min.jpg",
"img/sliderEffect09-min.jpg",
"img/sliderEffect10-min.jpg"
];
function ImageSlider (parent, images) {
let currentIndex = 0;
//선택자
let Slider = {
parent : parent,
images : parent.querySelector(".slider__img"),
thumnail : parent.querySelector(".slider__thumnail"),
PreviousBtn : parent.querySelector(".slider__btn .previous"),
NextBtn : parent.querySelector(".slider__btn .next")
}
//이미지를 화면에 출력
Slider.images.innerHTML = images.map((image, index)=>{
return `<img src="${image}" alt="이미지${index}">`
}).join("");
//큰 활성화 시 효과
let imageNode = Slider.images.querySelectorAll("img");
imageNode[currentIndex].classList.add("active");
//썸네일에 이미지 출력
Slider.thumnail.innerHTML = Slider.images.innerHTML;
//썸네일에 active 활성화
let thumnailNode = Slider.thumnail.querySelectorAll("img");
thumnailNode[currentIndex].classList.add("active");
//썸네일 클릭 시 이동
// for(let i=0; i<thumnailNode.length; i++){
// thumnailNode[i].addEventListener("click", function(){
// Slider.thumnail.querySelector("img.active").classList.remove("active");
// thumnailNode[i].classList.add("active");
// imageNode[currentIndex].classList.remove("active");
// currentIndex = i;
// imageNode[currentIndex].classList.add("active")
// });
// }
thumnailNode.forEach((el, i) => {
el.addEventListener("click", function(){
Slider.thumnail.querySelector("img.active").classList.remove("active");
el.classList.add("active");
imageNode[currentIndex].classList.remove("active");
currentIndex = i;
imageNode[currentIndex].classList.add("active")
});
});
//왼쪽 버튼 클릭
Slider.PreviousBtn.addEventListener("click", function(){
imageNode[currentIndex].classList.remove("active");
currentIndex--;
if(currentIndex < 0) currentIndex = images.length - 1;
imageNode[currentIndex].classList.add("active");
//활성화 되는 이미지와 같은 썸네일에 active 활성화
Slider.thumnail.querySelector("img.active").classList.remove("active");
thumnailNode[currentIndex].classList.add("active");
});
//오른쪽 버튼 클릭
Slider.NextBtn.addEventListener("click", function(){
imageNode[currentIndex].classList.remove("active");
currentIndex = (currentIndex + 1) % images.length;
imageNode[currentIndex].classList.add("active");
//활성화 되는 이미지와 같은 썸네일에 active 활성화
Slider.thumnail.querySelector("img.active").classList.remove("active");
thumnailNode[currentIndex].classList.add("active");
});
}
ImageSlider(document.querySelector(".slider__wrap"),images);
parent : 슬라이더를 감싸는 부모 요소이다.
images : 슬라이더에 들어갈 이미지의 배열이다.
ImageSlider 함수
: Slider 객체를 생성하고, 이 객체 안에 슬라이더에 필요한 요소들을 할당한다.
parent : 슬라이더를 감싸는 부모 요소입니다. Slider 객체의 parent 프로퍼티에 할당된다.
images : 슬라이더에 들어갈 이미지 배열입니다. 현재 코드에서는 images를 사용하지 않는다.
images 프로퍼티는 parent.querySelector(".slider__img")로 할당된다. 이는 슬라이더 안에 있는 이미지 요소를 선택하는선택자이다.
thumnail 프로퍼티는 parent.querySelector(".slider__thumnail")로 할당된다. 이는 슬라이더의 썸네일을 나타내는 요소를 선택하는 선택자이다.
PreviousBtn 프로퍼티는 parent.querySelector(".slider__btn .previous")로 할당된다. 이는 이전 이미지로 이동하는 버튼을 나타내는 요소를 선택하는 선택자이다.
NextBtn 프로퍼티는 parent.querySelector(".slider__btn .next")로 할당된다. 이는 다음 이미지로 이동하는 버튼을 나타내는 요소를 선택하는 선택자이다.
이렇게 생성된 Slider 객체를 통해 슬라이더에 필요한 요소들에 접근할 수 있다.
Slider.images.innerHTML에 map() 함수를 사용하여 images 배열에서 이미지를 가져와 HTML 코드로 변환한다.
join() 함수는 배열의 각 요소를 문자열로 변환하고, 배열 요소 사이에 구분자를 삽입하여 하나의 문자열로 결합한다.
따라서 Slider.images.innerHTML에는 이미지 요소를 포함한 HTML 코드가 삽입된다.
다음으로, Slider.images.querySelectorAll("img")로 이미지 요소를 선택하여 imageNode에 할당한다.
currentIndex 변수로 현재 활성화된 이미지를 지정하고, 이를 imageNode에서 선택한 이미지 요소에 classList.add("active")를 사용하여 추가한다.
이로써 현재 활성화된 이미지에 대한 효과를 적용한다.
Slider.thumnail.innerHTML에도 Slider.images.innerHTML과 같은 방식으로 HTML 코드를 삽입합니다. 따라서 썸네일 이미지 요소도 이미지 슬라이더 이미지와 동일하게 표시된다.
마지막으로, Slider.thumnail.querySelectorAll("img")로 썸네일 이미지 요소를 선택하여 thumnailNode에 할당한다.
이전과 마찬가지로 currentIndex 변수로 현재 활성화된 이미지를 지정하고, 이를 thumnailNode에서 선택한 이미지 요소에 classList.add("active")를 사용하여 추가한다. 이로써 현재 활성화된 썸네일에 대한 효과를 적용한다.
Slider.PreviousBtn.addEventListener() 함수: 왼쪽 버튼에 클릭 이벤트를 등록한다.
이벤트 핸들러 함수에서는 현재 활성화된 이미지에서 active 클래스를 제거하고, currentIndex 변수를 1 감소시킨다.
이후, currentIndex 값이 0보다 작으면, currentIndex 값을 images.length - 1로 설정하여, 마지막 이미지를 가리키도록 한다.
다음으로, imageNode[currentIndex]로 현재 활성화된 이미지 요소를 선택하고, classList.add("active")를 사용하여 해당 이미지에 active 클래스를 추가한다.
마지막으로, 활성화된 이미지와 동일한 썸네일 이미지에 active 클래스를 추가하여, 썸네일 이미지도 함께 활성화시킨다.
이렇게 함으로써 왼쪽 버튼을 클릭했을 때, 이미지 슬라이더의 활성화된 이미지가 왼쪽으로 이동하고, 이에 따라 썸네일 이미지도 변경된다.
Slider.NextBtn.addEventListener() 함수 : 오른쪽 버튼에 클릭 이벤트를 등록합니다.
이벤트 핸들러 함수에서는 현재 활성화된 이미지에서 active 클래스를 제거하고, currentIndex 값을 (currentIndex + 1) % images.length으로 설정한다.
이렇게 함으로써, currentIndex 값이 images.length와 같아지면, 0으로 돌아가게 된다.
이후, imageNode[currentIndex]로 현재 활성화된 이미지 요소를 선택하고, classList.add("active")를 사용하여 해당 이미지에 active 클래스를 추가한다.
마지막으로, 활성화된 이미지와 동일한 썸네일 이미지에 active 클래스를 추가하여, 썸네일 이미지도 함께 활성화 시킨다. 이렇게 함으로써 오른쪽 버튼을 클릭했을 때, 이미지 슬라이더의 활성화된 이미지가 오른쪽으로 이동하고, 이에 따라 썸네일 이미지도 변경된다.
마지막으로, ImageSlider() 함수를 호출하여, 이미지 슬라이더를 초기화합니다.
함수에는 document.querySelector(".slider__wrap")로 슬라이더를 감싸는 부모 요소와 images 배열을 인자로 전달한다.
thumnailNode.forEach() 함수를 사용하여 thumnailNode에 있는 모든 썸네일 이미지 요소에 대해 반복합니다.
각 썸네일 이미지 요소에 addEventListener() 함수를 사용하여 클릭 이벤트를 등록한다.
이벤트 핸들러 함수에서는 먼저 Slider.thumnail.querySelector("img.active")를 사용하여 현재 활성화된 썸네일 이미지를 선택하고, classList.remove("active")를 사용하여 해당 이미지에서 active 클래스를 제거한다.
다음으로, 클릭된 썸네일 이미지 요소에 classList.add("active")를 사용하여 active 클래스를 추가한다.
그리고 currentIndex 변수를 클릭된 썸네일 이미지 요소의 인덱스 값으로 업데이트한다.
이후, imageNode[currentIndex]로 현재 활성화된 이미지 요소를 선택하고, classList.remove("active")를 사용하여 해당 이미지에서 active 클래스를 제거한다.
마지막으로, imageNode[currentIndex]에 classList.add("active")를 사용하여 클릭된 썸네일 이미지와 해당하는 이미지를 활성화한다.
이렇게 함으로써 썸네일 이미지를 클릭했을 때, 해당 이미지가 활성화되고 이에 따라 이미지 슬라이더가 변경된다.