VanilaJS 로 Carousel만들기

클로이·2020년 10월 25일
1

VanilaJS로 Carousel을 만들어 보았다. 앞으로 이것저것 기능을 추가한 글을 올릴 것이다. (내가 나중에 다시 쓰기 위해서 ㅎㅎ)

  • Carousel
    위의 링크에 올려두었다.
  • 노마드 코더님의 동영상 강의의 코드를 참고하여 쓴 글입니다.

유튜브 노마드 코더님의 동영상 강의를 보면서 내가 구현하고 싶은 기능을 이것저것 추가했다.

기본적인 html 코드 작성

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>

<body>
    <div class="container">
        </div>
    </div>
</body>

</html>

이제 container 클래스 안에 carousel 클래스와 슬라이드를 만들 것이다.

<div class="container">
        <div class="carousel">
            <div class="slide_item">
                <h1>Slide1</h1>
            </div>
            <div class="slide_item">
                <h1>Slide2</h1>
            </div>
            <div class="slide_item">
                <h1>Slide3</h1>
            </div>
            <div class="slide_item">
                <h1>Slide4</h1>
            </div>
            <div class="slide_item">
                <h1>Slide5</h1>
            </div>    
        </div>
    </div>

클래스 이름은 그냥 carousel이랑 slide_item으로 지정해 두었다.
이제 이 슬라이드들이 하나씩 보여야 하고 같은 위치에 있어야 한다 !

css 적용하기

웹 폰트로 Noto Sans KR 폰트도 적용해 주었다.

@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap');

body {
    font-family: 'Noto Sans KR', sans-serif;
    margin: 0;
}
        
.container {
    display: flex;
    justify-content: center;
    align-items: center;
}

.carousel {
    width: 80%;
    position: relative;
}
 
.slide_item {
    width: 100%;
    height: 500px;
    border-radius: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    top: 0 px;
    z-index: 0;
}

.slide_item:nth-child(odd) {
     background-color: yellow;
 }

 .slide_item:nth-child(even) {
     background-color: yellowgreen;
 }

position: relative;이면 z-index로 화면 요소를 겹쳐 놓을 수 있다. z-index가 높은게 제일 위에 쌓인다. 위와 같은 상황이면 아래와 같이 제일 마지막에 있는 Slide 5가 맨 위에 오게 된다. (css아래에 .slide_item:nth-child()이걸 추가하기전 사진이다. 위의 코드 처럼하면 연두색이 나오는게 맞음)

이제 제일 위에 띄울 슬라이드를 정하는 showing 클래스가 있다고 가정하고 코드를 작성한다.

.showing {
    z-index: 1;
 }

showing클래스가 있으면 z-index가 높으므로 무조건 위로 보인다.
예를들어

<div class="slide_item showing">
    <h1>Slide1</h1>
</div>

이런식으로 코드를 수정하면 Slide1이 화면에 보이게 된다. 이 방법을 이용하여 Carousel을 만들것이다.

먼저 이전 슬라이드로 이동하는 버튼(leftBtn)이랑 다음 슬라이드로 이동하는 버튼(rightBtn)을 만들었다. 아이콘은 폰트 어썸을 사용했다. cdn으로 사용했다 !

  • html
<i class="fa fa-chevron-left movebtn" id="left"></i>
	<div class="slide_item showing">
		<h1>Slide1</h1>
	</div>
	<div class="slide_item">
		<h1>Slide2</h1>
	</div>
	<div class="slide_item">
		<h1>Slide3</h1>
	</div>
	<div class="slide_item">
		<h1>Slide4</h1>
	</div>
	<div class="slide_item">
		<h1>Slide5</h1>
	</div>    
<i class="fa fa-chevron-right movebtn" id="right"></i>
  • css
 .movebtn {
     font-size: 30px;
     position: absolute;
     color: rgba(0,0,0,0.5);
     top: 225px;
     z-index: 2;
     cursor: pointer;
 }
        
 #left {
     left: 20px;
 }

 #left:hover {
     transition: 0.3s;
     transform: translateX(-5px);
     color: rgba(0,0,0,0.8);
  }

 #right {
     right: 20px;
 }

 #right:hover {
     transition: 0.3s;
     transform: translateX(5px);
     color: rgba(0,0,0,0.8);
 }

마우스를 올리면 투명도가 바뀌면서 움직이는 모션도 추가했다.
그럼 아래와 같이 버튼이 생긴다 ! 이제 여기에 이벤트를 추가하면 된다.

이벤트 추가하기

  • JS

html <body>태그 안에 <script>에 이 코드를 넣어주었다.
document.querySelectorAll()함수를 사용해 .slide_item클래스를 가진 요소들을 Array로 불러오고 아이콘을 누를때마다 moveRSlide(), moveLSlide()함수가 실행되고 슬라이드가 넘어가게 한다.

const SHOWING_CLASS = "showing";
       
const Slides = document.querySelectorAll(".slide_item");
const leftBtn = document.querySelector("#left");
const rightBtn = document.querySelector("#right");

let curIndex = 0;

const moveRslide = () => {
    Slides[curIndex].classList.remove(SHOWING_CLASS);	// 현재 슬라이드의 SHOWING_CLASS를 없애고
     
    if (curIndex < Slides.length - 1) {
         curIndex++;
     } else {
         curIndex = 0;
     }
    Slides[curIndex].classList.add(SHOWING_CLASS);	// 다음 슬라이드에 SHOWING_CLASS를 추가한다.
}

const moveLslide = () => {
     Slides[curIndex].classList.remove(SHOWING_CLASS);	// 현재 슬라이드의 SHOWING_CLASS를 없애고
          
      if (curIndex > 0) {
          curIndex--;
      } else {
          curIndex = Slides.length - 1;
      }
               
      Slides[curIndex].classList.add(SHOWING_CLASS);	// 다음 슬라이드에 SHOWING_CLASS를 추가한다.
  
 leftBtn.addEventListener("click",moveLslide);
 rightBtn.addEventListener("click",moveRslide);
  
}

주의할 점은 curIndex가 슬라이드의 개수를 넘어가면 다시 slide1로 초기화 되거나 0보다 작아지면 slide5로 넘어가야하는데 이 부분은 if문으로 해결해 주었다.

그럼 각 슬라이드마다 showing클래스가 없어지고 추가되고가 반복되면서 슬라이드가 넘어가게 된다.

전체 코드

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <title>Document</title>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap');

        body {
            font-family: 'Noto Sans KR', sans-serif;
            margin: 0;
        }
        
        .container {
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .carousel {
            width: 80%;
            position: relative;
        }

        .slide_item {
            width: 100%;
            height: 500px;
            border-radius: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
            top: 0 px;
            z-index: 0;
        }

        .slide_item:nth-child(odd) {
            background-color: yellow;
        }

        .slide_item:nth-child(even) {
            background-color: yellowgreen;
        }

        .showing {
            opacity: 1;
            z-index: 1;
        }
        .movebtn {
            font-size: 30px;
            position: absolute;
            color: rgba(0,0,0,0.5);
            top: 225px;
            z-index: 2;
            cursor: pointer;
        }
        
        #left {
            left: 20px;
        }

        #left:hover {
            transition: 0.3s;
            transform: translateX(-5px);
            color: rgba(0,0,0,0.8);
        }

        #right {
            right: 20px;
        }

        #right:hover {
            transition: 0.3s;
            transform: translateX(5px);
            color: rgba(0,0,0,0.8);
        }
       

    </style>
</head>

<body>
    <div class="container">
        <div class="carousel">
            <i class="fa fa-chevron-left movebtn" id="left"></i>
            <div class="slide_item">
                <h1>Slide1</h1>
            </div>
            <div class="slide_item">
                <h1>Slide2</h1>
            </div>
            <div class="slide_item">
                <h1>Slide3</h1>
            </div>
            <div class="slide_item">
                <h1>Slide4</h1>
            </div>
            <div class="slide_item">
                <h1>Slide5</h1>
            </div>    
            <i class="fa fa-chevron-right movebtn" id="right"></i>
        </div>
    </div>
    <script>
        const SHOWING_CLASS = "showing";
       
        const Slides = document.querySelectorAll(".slide_item");
       
       
        const leftBtn = document.querySelector("#left");
        const rightBtn = document.querySelector("#right");
        let curIndex = 0;

        const moveRslide = () => {
            Slides[curIndex].classList.remove(SHOWING_CLASS);
            if (curIndex < Slides.length - 1) {
                curIndex++;
            } else {
                curIndex = 0;
            }
            console.log(curIndex);
            
            Slides[curIndex].classList.add(SHOWING_CLASS);
        }

        const moveLslide = () => {
            Slides[curIndex].classList.remove(SHOWING_CLASS);
            if (curIndex > 0) {
                curIndex--;
            } else {
                curIndex = Slides.length - 1;
            }
            Slides[curIndex].classList.add(SHOWING_CLASS);
        }

        leftBtn.addEventListener("click",moveLslide);
        rightBtn.addEventListener("click",moveRslide);
        
    </script>
</body>

</html>

다음 글에는 페이지를 추가한걸 올릴 예정이다. 사실 css가 많이 부족해서 아이콘도 약간 하드 코딩해서 넣었다. 다음에는 꼭 해결해야지 ㅠㅠ!!

profile
개발자가 되고싶어요

0개의 댓글