ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CSS와 javascript는 눈보다 빠르다 슬라이드와 무한슬라이드
    Knowledge/javascript 2019. 8. 13. 18:30
    반응형

    일정 시간이 지나면 가로로 넘어가는 슬라이드를 만들어보자.

    준비물은 다음과 같다.

     

    div 하나, 가로로 쭉 이어붙인 li 다섯개, 그 li 다섯개의 총 너비와 같은 너비를 가진 ul 하나!

    여기에 필자는 알아보기 좋게 배경색과 border를 좀 추가해서 준비했다

    코드로 보면 아래와 같다

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>슬라이드 무한 슬라이드</title>
        <style src=></style>
        <style>
           body * {
             height: 50px;
            }
            .slide_box{
                width: 200px;
               position: relative;
               left: 50%;
               margin-left: -100px;
               top: 400px;
               border: 5px blue solid;
               z-index: 100;
            }
            .slide_wrap{
                background: red;
                width: 1000px;
                margin: 0;
                padding: 0;
            }
            .slide_item{
                background: green;
                width: 200px;
                list-style: none;
                float: left;
                text-align: center;
                line-height: 50px;
            }
            .slide_item a{
                text-decoration: none;
                color : black;
            }
        </style>
    </head>
    <body>
        <div class="slide_box"> 
            <ul class="slide_wrap">
                <li class="slide_item"><a href="#">1</a></li>
                <li class="slide_item"><a href="#">2</a></li>
                <li class="slide_item"><a href="#">3</a></li>
                <li class="slide_item"><a href="#">4</a></li>
                <li class="slide_item"><a href="#">5</a></li>
            </ul>
        </div>
        <script>
            document.addEventListener("DOMContentLoaded",function(){
                // 
            });
        </script>
    </body>
    </html>
    화면은 이렇게 나온다

     

    슬라이드와 무한 슬라이드로 검색하면 굉장히 많은 샘플이 나오고

    상세한 설명이 함께 있지만 필자의 경우 그걸 읽다보니 되려 더 헷갈리는 느낌을 받았다.

    그래서 최대한 간단히 설명하려한다.

     

    슬라이는 이 상태에서 원하는 시간마다 ul을 옆으로 밀면 된다. 끝!

     

    정말 이게 다다. 코드를 한번 쳐보자

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
        <script>
            var ul = document.querySelector('.slide_wrap');
     
            function move(){
     
                var curIndex = 0;
     
                setInterval(function(){
                    ul.style.transition = '0.2s';
                    ul.style.transform = "translate3d(-"+200*(curIndex+1)+"px, 0px, 0px)";
     
                    curIndex++;
     
                    if(curIndex === 4){
                        curIndex = -1;
                    }
     
                },1000);
            }
            
            document.addEventListener("DOMContentLoaded",function(){
                move();
            });
        </script>

     

    위 html에서 아래와 같은 스크립트 코드만 넣어주면 된다.

    그러면 1초마다 ul이 옆으로 움직이고 li가 div의 border안에 딱 맞게 배치되는 모습을 볼 수 있다. 

     

    슬라이드가 끝까지 이동한 모습

    원리를 설명하기 위해 아직 처리하지 않았지만

    이제 div의 css에 overflow : hidden만 줘서 범위를 넘어서는 부분을 감추면

    우리가 보는 슬라이드 구현이 끝난다.

     

    캡처 도구로 막 캡쳐했는데 이번에 4가 잡혔다

     

    그러나 따라해보신 분들은 아시겠지만 5에서 1로 가는 움직임이 그닥 자연스럽지 않다.

    그러나 걱정하지 말고 제목을 다시 한번 읽자. CSS와 javascript는 눈보다 빠르다. 다 방법이 있다.

     

    - 무한 슬라이드

     

    이 역시도 위와 같은 눈속임을 활용해 구현한다

    이를 위해선 재료의 추가와 변형이 좀 필요하다.

     

    일단 첫 1이 적힌 첫 li를 복사한 엘리먼트 하나를 추가해야 하고

    1000px을 줬던 ul의 width를 복사본 하나를 덧붙일 만큼의 200px을 추가해 1200px로 만든다.

    그리고 ul의 가장 뒤에 복사본을 붙인다. 

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        <style>
            .slide_wrap{
                width: 1200px;
            }
        </style>
         <script>
            var ul = document.querySelector('.slide_wrap');
            var firstItemClone = ul.firstElementChild.cloneNode(true);
            ul.appendChild(firstItemClone);
        </script>

     

    이 정도 변경에 전체 코드를 붙이기는 좀 부담스럽고 부분만 잘라와 올린다.

    위 코드를 맞는 위치에 붙여서 아래와 같은 결과가 눈에 보이면 준비 완료!

    (아 div의 overflow : hidden도 지워줘야 합니다! 원리를 정확히 이해하는 게 이 포스팅의 목적이니 보고 하는게 좋겠죠?)

     

    이렇게 하면 준비 끝!

    그리고 move 함수의 내용을 아래와 같이 바꾸면 구현이 된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
            function move(){
     
                var curIndex = 0;
     
                setInterval(function(){
                    ul.style.transition = '0.2s';
                    ul.style.transform = "translate3d(-"+200*(curIndex+1)+"px, 0px, 0px)";
     
                    curIndex++;
     
                    if(curIndex === 5){
                        setTimeout(function(){
                            ul.style.transition = '0s';
                            ul.style.transform = "translate3d(0px, 0px, 0px)";
                        },201)
                        curIndex = 0;
                    }
     
                },1000);
            }

    무슨 짓을 한건지 코드만 읽고 감이 오는가?

    그렇다면 부럽다. 필자는 이것과 비슷하게 구현된 코드를 읽고 

    '뭔짓을 해놓은거야..'란 생각밖에 안들었다..ㅋㅋ

     

    그렇기에 간단히 설명을 적는다.

     

    일단 첫 엘리먼트를 복사해 ul의 마지막에 붙인 이유부터 시작하자.

     

    처음 구현한 슬라이드에서 문제가 되었던 건 무엇인가?

    1이 나오지 않았나? 아니다 1은 잘 나왔다.

    문제는 그 과정에서 5->4->3->2를 거친다는 게 문제였다.

    의도대로면 1->2->3->4->5의 흐름에서 처럼 스르륵 왼쪽으로 넘어가서 1이 나와야 하는데 말이지..

     

    그러니까 일단 우리에겐 '왼쪽으로 스르륵하고 나오는 1이 필요했고'

    처음 엘리먼트를 복사해 마지막에 붙인 이유는 그 때문이다. 그러면 5 다음에 왼쪽으로 스르륵 넘어가 1이 나오니까.

     

    근데 분명 복사본을 마지막에 붙이지 않았나?

    그러니까 무언가 조치를 취하지 않으면 처음 구현한 슬라이드에서 겪은 문제를 다시 겪게 되는게 당연하다.

    5에서 4,3,2를 거쳐 1이 나오던게 복사본 1에서 5,4,3,2를 거쳐 1이 나오는 것으로 바뀔 뿐..

     

    0.201초 뒤에 트랜지션을 없애고 ul의 위치를 처음으로 바꾸는  if(curIndex === 5)안에 코드는 그래서 존재한다.

     

    무슨 의미인지 알겠는가? 0.201초 뒤라는 것이 단서다.

    추가로 하나 더 힌트를 주자면 ul에 원래 줬던 trasition이 0.2초라는 것.

     

    그러니까 5에서 스르륵 효과를 지나쳐 나오는 1의 복사본이 완전히 자리 잡은 다음 

    트랜지션을 끄고 UL을 처음 위치, 처음 1이 .slide_box의 위치에 있던 때로 되돌리는 것이다.

     

    그럼 복사본 1을 1로 대체하는 것과 다름 없으니 브라우져를 보는 유저 입장에선 뭐가 바뀐건지 체감할 수 없다.

    우리는 UL을 처음으로 넘겨 슬라이드가 다시 작동할 수 있게 만들었음에도 말이지.

     

    원리를 알았으니 이제 이 상태에서 ul의 overflow : hidden을 다시 주면 잘 작동하는 무한 슬라이드를 볼 수 있다.

    물론 이게 완전한 코드는 아니다.

    비슷한 기능을 css의 animaition만을 활용해 구현할 수도 있고

    setInterval 안에서 setTimeout을 또 사용하는 건 의도하지 않은 결과를 불러올 수도 있다.

     

    아래의 문제 같은 경우엔 promise 등을 활용해 개선할 수 있는데

    이는 후에 javascript 카테고리에서 동기 프로그래밍에 관해 포스팅 한 후 추가로 올리도록 하겠다

     

    참고:

     

     

    [JS/Slider] 바닐라 자바스크립트로 무한 루프 슬라이드(Carousel) 구현하기

    무한 루프 슬라이드 오늘은 자바스크립트로 구현해 본 무한루프 슬라이드를 정리해보려고 한다. 예전에 제이쿼리를 사용해서 슬라이드를 구현해본 적은 있지만 마지막 슬라이드에서 첫번째 슬라이드로 자연스럽게..

    im-developer.tistory.com

    반응형

    댓글

Designed by Tistory.