본문 바로가기
JAVASCRIPT

슬라이드 이펙트 : 이미지 슬라이드(썸네일)

by dongjin6539 2023. 4. 14.
728x90
반응형

슬라이드 이펙트 : 이미지 슬라이드(썸네일)

 

수업 시간에 배운 내용을 복습하면서 해보겠습니다.

코드 보기(HTML, JAVASCRIPT / CSS1 / CSS2) / 완성화면

 

 

코드 블럭

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>07. 슬라이드 이펙트</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/slider.css">

    <!-- 파비콘 -->
    <link rel="shortcut icon" type="image/x-icon" href="ico/favicon.png"/> 
    <link rel="apple-touch-icon" sizes="114x114" href="ico/favicon.png"/>
    <link rel="apple-touch-icon" href="ico/favicon.png"/>

    <style>
        #header ul a:hover {
            background-color: #000;
            color: #fff;
            transform: scale(1.2);
            transition: all 0.5s;
        }
        #header li {
            margin: 0 2px;
        }

        /* 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.5);
        }
        .slider__img {
            position: relative;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        .slider__img img {
            position: absolute;
            width: 100%;
            height: 100%;
            /* background-size: cover; */
            object-fit: cover;   /* img 태그로 불러왔을 때 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%, 150px);
            width: 100px;
            display: flex;
            justify-content: center;
            gap: 10px;
        }
        .slider__thumb img {
            cursor: pointer;
            border: 2px solid transparent; /* 보더도 위치값을 가지기 때문에 transparent(색상 투명하게) 씀 */
        }
        .slider__thumb img.active {
            border: 2px solid #fff;
        }
        .slider__btn a {
            display: flex;
            position: absolute;
            top: 0;
            width: 40px;
            height: 100%;
            justify-content: center;
            align-items: center;
            font-size: 12px;
            color: #fff;
            background-color: rgba(0,0,0,0.2);
            transition: all 300ms ease-in-out;
        }
        .slider__btn a:hover {
            background-color: rgba(0,0,0,0.5);
        }
        .slider__btn a.next {
            right: 0;
        }
        .slider__btn a.prev {
            left: 0;
        }
    </style>
</head>
<body class="img07 bg07 font07">
    <header id="header">
        <h1>Javascript slider Effect06</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>    <!--title은 웹 접근성을 위함임-->
                <a href="#" class="next" title="다음 이미지">next</a>
            </div>
        </div>
    </main>
    <!-- //main -->

    <footer id="footer">
        <a href="mailto:dongjin6539@naver.com">dongjin6539@naver.com</a>
    </footer>
    <!-- //footer -->
</body>
</html>

구성

  • 코드는 간단하게 header 구역 부분에 제목 태그, 목록 태그를 사용해서 텍스트를 입력해줍니다.
  • main 구역에는 이미지가 들어갈 구역, 썸네일 이미지가 들어갈 구역, 화살표 버튼을 class 명을 사용해서 만들어줍니다.
  • css는 유형별로 공통으로 사용될 스타일은 파일로 따로 만들어서 링크 태그를 사용해 가지고 와서 입력해주고 유형별로 다르게 사용될 스타일은 각각의 코드 구성하는데 입력해줍니다.

 

CSS

 

JAVASCRIPT

<script>
    let images =[
        "./img/sliderEffect01-min.jpg",
        "./img/sliderEffect02-min.jpg",
        "./img/sliderEffect03-min.jpg",
        "./img/sliderEffect04-min.jpg",
        "./img/sliderEffect05-min.jpg"
    ];

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

        //선택자 - 변수 객체 안에 선택자를 담은 형태
        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"),
        }

        //이미지 출력하기
        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 추가하기
        // slider.thumnails.firstChild.classList.add("active")

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

        //썸네일 이미지 클릭하기(for문)
        // for(let i = 0; i < thumnailNodes.length; i++){
        //     thumnailNodes[i].addEventListener("click", function(){  //화살표 함수는 this 못 씀 ㄷㄷ
        //         slider.thumnails.querySelector("img.active").classList.remove("active");
        //         thumnailNodes[i].classList.add("active");

        //         imageNodes[currentIndex].classList.remove("active");
        //         currentIndex = i;
        //         imageNodes[currentIndex].classList.add("active");
        //     });
        // }
		
        //썸네일 이미지 클릭하기(forEach())
        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");
            });
        });

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

            //0에서 빼도 음수가 안 나오도록
            if(currentIndex < 0) currentIndex = images.length-1;

            imageNodes[currentIndex].classList.add("active");
            // thumnailNodes[currentIndex].classList.add("active");

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

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

            //index가 최대 개수 안 넘게 하기(여기서 currentIndex에 +1을 하기 때문에 ++ 안 함)
            currentIndex = (currentIndex+1) % images.length;

            imageNodes[currentIndex].classList.add("active");

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

    imageSlider(document.querySelector(".slider__wrap"), images);
</script>

자바스크립트 구성

  • 이미지를 배열로 데이터를 저장해줍니다.
  • 함수 imageSlider로 실행시켜주고 parent, images의 값을 입력해줍니다.
  • 현재 보이는 이미지를 변수 currentIndex를 0으로 데이터를 저장해줍니다.
  • 선택자를 객체로 데이터를 저장해줍니다.
  • // 이미지 출력하기에서 이미지를 입력할 부분의 선택자를 가져와서 .innerHTML로 데이터를 입력해주는데 이미지가 다중이이므로 map 메서드를 사용해줍니다. return 함수를 사용해서 이미지 소스를 입력시켜줍니다.
  • // 이미지 활성화하기에서 이미지를 입력한 부분의 이미지를 선택자로 만들고 미리 만들어둔 스타일을 가져오기 위해서 classList.add("active");를 입력해서 스타일을 입력해줍니다.
  • // 썸네일 이미지 출력하기에서 썸네일 이미지를 입력한 부분의 선택자를 가져와서 .innerHTML로 데이터를 입력해주는데 // 이미지 출력하기의 .innerHTML 부분을 그대로 가져와서 입력해줍니다.
  • // 썸네일 이미지 활성화하기에서 썸네일 이미지를 입력한 부분의 이미지를 선택자로 만들고 미리 만들어둔 스타일을 가져오기 위해서 classList.add("active");를 입력해서 스타일을 입력해줍니다.
  • // 왼쪽 버튼 클릭하기에서 클릭하기 속성을 입력하기 위해 addEventListener("click") 메서드를 사용해줍니다. 먼저 이미지가 활성화된 부분을 classList.remove("active");를 입력해서 스타일을 제거해줍니다. 현재 보이는 이미지를 --연산자를 이용해서 값을 저장해줍니다. 하지만 음수가 나오면 이미지가 안나오므로 if문을 사용해서 if(currentIndex<0)currentInex=images.length-1;을 입력해서 음수가 나오면 적용된 currentInex값이 이미지의 갯수에서 -1을 해서 나오는 값(4,3,2,1,0 순으로 나오는 값)을 저장해줍니다. 그러고 나오는 currentInex의 이미지에 다시 classList.add("active");를 입력해서 스타일을 적용시켜줍니다. 썸네일 이미지에도 classList.remove("active");를 입력해서 스타일을 제거해주고 새로운 currentInex의 이미지에 다시 classList.add("active");를 입력해서 스타일을 적용시켜줍니다.
  • // 오른쪽 버튼 클릭하기에서 클릭하기 속성을 입력하기 위해 addEventListener("click") 메서드를 사용해줍니다. 먼저 이미지가 활성화된 부분을 classList.remove("active");를 입력해서 스타일을 제거해줍니다. 계속 클릭했을 때 인덱스 값이 1,2,3,4,0,1 순으로 나오게 값을 입력해줍니다. 그러고 나오는 currentInex의 이미지에 다시 classList.add("active");를 입력해서 스타일을 적용시켜줍니다. 썸네일 이미지에도 classList.remove("active");를 입력해서 스타일을 제거해주고 새로운 currentInex의 이미지에 다시 classList.add("active");를 입력해서 스타일을 적용시켜줍니다.
  • // 썸네일 이미지를 클릭하기에서 썸네일 이미지를 클릭하면 해당하는 이미지로 이동하게끔 활성화시켜줍니다. 썸네일 이미지가 다중이이므로 forEach( )를 사용해줍니다. 값을 el, 인덱스 값을 i로 변수를 저장해줍니다. 값을 클릭하기 속성을 입력하기 위해 addEventListener("click") 메서드를 사용해줍니다. 그리고 기존에 active가 적용되었던 부분을 classList.remove("active");입력해서 스타일을 제거해주고 클릭된 값에 classList.add("active");를 입력해서 스타일을 적용시켜줍니다. 배경 이미지도 기존에 active가 적용되었던 부분을 classList.remove("active"); 입력해서 스타일을 제거해주고 현재 보이는 이미지의 값을 클릭된 인덱스 값을 가져와서 classList.add("active");를 입력해서 스타일을 적용시켜줍니다.

 

참고

parent
parent는 선택된 부분의 부모 태그를 선택해주는 역할을 합니다.
728x90
반응형