이펙트 효과/슬라이드 이펙트

JS 슬라이드 이펙트 적용해보기! - 7 썸네일

우당당쿵당콩탕 2023. 4. 14. 23:20
728x90
반응형

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: 1px 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.3);
    transition: all 300ms ease-in;
   }
   .slider__btn a.next {
    right: 0;
   }
   .slider__btn a:hover {
    background-color: rgba(0,0,0,0.5);
   }
</style>

추가된 부분은 썸네일의 slider tuhmb과 active입니다. 썸네일 이미지를 의미하며 클릭했을 시 활성화 및 동작을 위한 active부분입니다.

 

script

이번 스크립트에서는 선택자를 일일히 만들어주는 것이 아니라, 함수안에 객체 형식으로 넣어보겠습니다.

먼저 images라는 변수안에 각각의 이미지를 넣어줍니다. 

let images = [
    "img/sliderEffect03.jpg",
    "img/sliderEffect04.jpg",
    "img/sliderEffect02.jpg",
    "img/sliderEffect01.jpg",
    "img/sliderEffect06.jpg"
];

// 선택자 만들기, 함수안에 객체 형식, 선택자를 변수화
function imageSlider(parent, images){
    let currentIndex = 0; 

    //선택자
    //parent = slider__wrap
    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")
    }

선택자를 만든다는 점에서는 동일하나, 함수안에 객체 형식이며 선택자를 변수화 시킨 부분입니다.

imagesSlider는 parent와 images라는 두가지를 받고, parent는 슬라이더가 생성 될 부모를 가리키는 선택자고, imagessms 이미지를 담은 배열입니다. (상단에서 만든부분입니다.)

 

currentIndex라는 변수도 정의되어 있는데 이 변수는 슬라이더에 표시된 이미지, 즉 보이는 이미지를 말합니다.

 

thumnails는 섬네일을 의미하며 Btn은 각각의 버튼을 의미합니다.

 

이렇게 정의해 두었기 때문에 slider.images, slider.prevBtn 이런식으로 코드를 작성할 수 있게됩니다!

 

이미지 출력, 활성화(active)하기

// 이미지 출력하기
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.thumnails.innerHTML = slider.images.innerHTML;

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

slider.images.innerHTML는  images라는 배열에 담긴 이미지들을 map함수로 뽑아내는 것을 말합니다. 

그 뒤, img라는 태그를 감싸주고 join을 사용해 문자열로 만들어줍니다. 그리고 그 문자열들은 slider.images.innerHTML에 할당되어지기 때문에 이미지들이 보여지게 됩니다.

 

상단에서 선택자를 만들어 주었기 때문에 slider.images.querySelectorAll 형식으로 사용해줍니다.

let imageNodes = slider.images.querySelectorAll("img");
imageNodes[currentIndex].classList.add("active");

querySelectorAll을 사용해서 slider.images 내부의 img를 선택해서 imageNodes라는 변수에 저장합니다.

그 다음 imageNodes 배열에서 currentindex에 해당하는 이미지(보여지는 이미지)에 active 클래스를 추가합니다.

이ㄷ 때 classList 속성을 사용해 해당 요소의 클래스를 조작 할 수 있습니다.

 

classList

classList는 DOM 요소의 클래스 이름을 다루기 위한 프로퍼티입니다. 클래스 이름을 추가, 삭제, 토글 등의 작업을 할 수 있습니다.

주로 사용되는 것들은 active, remove, toggle 입니다.

 

예를 들어, classList.add('active')를 사용하면 해당 DOM 요소의 클래스 이름에 'active'가 추가됩니다. 

classList.remove('active')를 사용하면 'active' 클래스 이름이 삭제됩니다. 

classList.toggle('active')를 사용하면 해당 클래스가 없다면 추가하고, 있다면 삭제합니다.

map()

이 함수는 배열 객체의 메서드 중 하나로, 배열 내 모든 요소에 대해 인자로 전달된 콜백 함수를 호출하고 그 결과를 모아 새로운 배열을 반환해줍니다.

예를 들어 1,2,3,4,5라는 배열이 있을 때 이 배열의 모든 요소에 2를 곱한 새로운 배열을 만들려면 map()을 사용할 수 있습니다.

const originalArray = [1, 2, 3, 4, 5]; const multipliedArray = originalArray.map((number) => number * 2);

console.log(multipliedArray); // [2, 4, 6, 8, 10]

join()

join() 메서드는 배열의 모든 요소를 문자열로 변환하고, 이들 사이에 구분자를 삽입하여 하나의 문자열로 만들어 반환합니다.

const result = fruits.join(", ");

console.log(result); // "apple, banana, kiwi"

 

thumnailNodes.forEach((el, i) => {
    el.addEventListener("click", function() {
    slider.thumnails.querySelector("img.active").classList.remove("active");
    el.classList.add("active");
    imageNodes[currentIndex].classList.remove("active");
    currentIndex = i;
    imageNodes[currentIndex].classList.add("active");
    });
});

이 코드는 각각 썸네일 이미지를 클릭 했을 때 해당 이미지를 활성화 하고, 그 이미지와 연관된 원본 이미지도 활성화하여 매칭해주는 역할을 합니다.

 

forEach를 사용하여 thumnailNodes라는 배열에 대해 반복 작업을 수행하게 됩니다. 

여기서 el과 i는 매개변수인데, el은 현재 요소이고 i는 현재 요소의 인덱스값을 의미합니다. 즉 el 과 i는 각각 클릭 된 이미지(img)와 그 인덱스 값입니다.

 

click을 했을 때 실행시키기 위에 addeventlistener를 추가해 줍니다. click 시 함수가 실행됩니다.

썸네일 이미지를 클릭 했을 때 이미지의 클래스 목록에서는 액티브 클래스가 삭제되고, 목록에 다시 액티브 클래스를 추가합니다. 활성화 된 원본에서의 액티브는 삭제 되고, currentindex값이 업데이트 되어서 클릭한 이미지가 보임과 동시에 썸네일과 원본이미지가 서로 연관되어 동시에 활성화 됩니다.