모바일 기준으로 이미지 터치 슬라이더를 구현해봤습니다.

터치 슬라이더는 이미 다양한 블로그에서 정리를 해놔서 구현하기 쉬었습니다.

 

그런데 여기서 사람이 직접 슬라이드를 넘기는 것이 아닌 자동으로 시간이 지나면 슬라이드 되는 기능을 추가해봤습니다.

 

자동으로 슬라이드가 되는 기능은 setInterval을 사용하면 쉽게 구현 할 수 있지만,

터치를 한 순간에는 setInterval이 멈춰야 하기 때문에 그 부분에서 고민을 많이 했습니다.

 

 

오토 슬라이드 시연 gif

 

터치 슬라이드 시연 gif

 

 

HTML 구현 코드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" type="text/css" href="style.css">
    <title>slider</title>
</head>
<body>
    <div class="slideshow-container">
        <div class="images">
            <img src="image/1.jpg">
            <img src="image/2.jpg">
            <img src="image/3.jpg">
            <img src="image/4.jpg">
        </div>
    </div>
<script src="slide.js"></script>
</body>
</html>

HTML은 위의 코드를 참고하셔도 괜찮고 직접 작성하셔도 됩니다.

여기서 class 값으로 JS에서 querySelector를 사용하기 때문에 그 부분만 유의하시면 될 것 같습니다.

 

 

CSS 구현코드

body {
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.slideshow-container {
    overflow: hidden;
    width: 100vw;
    position: relative;
    overflow: hidden;
    display: flex;
}

.images {
    position: relative;
    display: flex;
    transition: transform 0.5s;
}

.images img {
    vertical-align: middle;
    width: 100vw;
}

CSS는 반응형으로 디자인 하기 위해서 flex 컨테이너를 사용했습니다.

이미지 혹은 div의 widh 값도 반응형으로 만들기 위해 'vw' 단위를 사용했습니다.

 

 

 

 

자바스크립트 구현코드

const IMAGE_VW = 100;
const IMAGES = document.querySelector(".images");
const INTERVAL_TIME = 5000;
const IMG_COUNT = IMAGES.childElementCount;
const LAST_INDEX = IMG_COUNT - 1;

let curIndex = 0;
let curImgVw = 0;
let startX, endX;
let interval;

function prevImg() {
    if(curIndex > 0) {
        curImgVw += IMAGE_VW;
        IMAGES.style.transform = `translateX(${curImgVw}vw)`;
        curIndex--;
    }
}

function nextImg() {
    if(curIndex < LAST_INDEX) {
        curImgVw -= IMAGE_VW;
        IMAGES.style.transform = `translateX(${curImgVw}vw)`;
        curIndex++;
    }
}

function touchStart(event) {
    stopInterval();

    startX = event.touches[0].pageX;
}

function touchEnd(event) {
    startInterval();

    endX = event.changedTouches[0].pageX;
    if(startX > endX) {
        nextImg();
    } else {
        prevImg();
    }
}

function autoSlide() {
    if(curIndex === LAST_INDEX) {
        stopInterval();
        curImgVw = 0;
        IMAGES.style.transform = `translateX(${curImgVw}vw)`;
        curIndex = 0;
        startInterval();
    } else if(curIndex < LAST_INDEX) {
        curImgVw -= IMAGE_VW;
        IMAGES.style.transform = `translateX(${curImgVw}vw)`;
        curIndex++;
    }
}

function startInterval() {
    if(interval === null) {
        interval = setInterval(autoSlide, INTERVAL_TIME);
    }
}

function stopInterval() {
    clearInterval(interval);
    interval = null;
}

function init() {
    IMAGES.addEventListener("touchstart", touchStart);
    IMAGES.addEventListener("touchend", touchEnd);
    startInterval();
}

init();
  • 고정적인 값을 나타내는 변수는 const(상수)와  전역변수로 선언 했습니다.
    ex) 인터벌 시간, 이미지의 가로 길이
  • 자동으로 슬라이드가 되는 함수(autoSlide)는 브라우저가 렌더링 되면 바로 실행이 되도록 init 함수에 넣어놨습니다.
  • 이미지를 클릭하면 touchstart 함수가 실행되고 autoSlide를 일정 간격으로 실행시키는 인터벌을 정지하도록 했습니다.
  • startInterval() 함수를 만들어서 하나의 인터벌만 실행되도록 코드를 작성했습니다.
    => 동일하게 stopInterval() 실행중인 하나의 인터벌을 clearInterval() 함수를 사용해서 종료하도록 했습니다.
    => 실행 할 하나의 interval은 미리 전역변수로 설정을 해놨습니다.
  • 터치 슬라이드에서 각 이미지에 인덱스 값이 있다는 가정하에 curIndex, LAST_INDEX 변수 선언
    => curIndex는 유저가 현재 보고있는 이미지의 인덱스입니다.
    => LAST_INDEX는 말그대로 마지막 이미지의 인덱스입니다.

 

 

 

 


참고자료

  • 블로그 [탐구소년] 자바스크립트 모바일 터치 슬라이더 구현하기 => 링크

 

 

 

 

반응형

+ Recent posts