CSS&JS/👀Study and Copy

웹/모바일 터치슬라이더 만들기 (vanilla Java Script/vanilla JS)

arancia_ 2021. 5. 17. 14:57

소스 참고 : https://penguingoon.tistory.com/257

 

자바스크립트 모바일 터치 슬라이더 구현하기 (feat. 터치 이벤트)

안녕하세요! 오늘은 모바일 전용 이미지 슬라이더를 간단하게 구현해보았습니다. 모바일에서는 손가락을 이용해 영역을 터치하면 터치이벤트가 발생하게 되는데, 이 터치의 시점과 위치를 잘

penguingoon.tistory.com

탐구소년님이 올려주신 소스를 바탕으로

1) 웹에서는 mousedown / mouseup 으로 작동되게
2) 모바일에서는 touchstart / touchend
3) 자동재생 / 일시정지 / 다시 재생
4) 좌우 화살표 페이저 있음
5) 하단에 슬라이드 갯수만큼 자동으로 생성되는 페이저 있음
6) mousedown / touchstart / 좌우화살표페이저 / 하단 페이저 이벤트 발생시 자동재생은 멈추도록

으로 구현해보았습니다.

 

 

HTML

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
<!DOCTYPE html>
<html>
<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"/>
    <title>GRAB SLIDER</title>
<link href="style_3.css" rel="stylesheet"type="text/css"/>
<script src="./grabSlider_final.js" defer></script>
</head>
<body>
 
<h6>https://swiperjs.com/ 같은 터치 가능한 슬라이드 만들어 보자</h6>
 
<button id="btn_stop">멈춰!!!</button>
<button id="btn_play">다시 재생해</button>
 
<div id="arrows">
    <button data-flow="prev">&lt;</button>
    <button data-flow="next">&gt;</button>
</div>
 
<div id="cont">
    <ul id="slider">
        <li><div>001</div></li>
        <li><div>002</div></li>
        <li><div>003</div></li>
        <li><div>004</div></li>
        <li><div>005</div></li>
        <li><div>006</div></li>
    </ul>
</div>
 
<div id="pager"></div>
 
 
</body>
</html>
cs



CSS

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
@charset "utf-8";
*{margin:0;padding:0;box-sizing:border-box;}
li{list-style-type:none;}
html,body{
    display:flex;flex-wrap:wrap;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    overflow:hidden;
    width:100%;height:100vh;
    background:#000;}
/*  */
#stop, #btn_stop, #btn_play{
    font-size:2rem;
    margin-bottom:1rem;
}
 
/*  */
#arrows{
    display:flex;
    justify-content:space-between;
    position:fixed;
    width:800px;
    top:50%;left:calc(50% - 400px);}
 
#arrows button{
    width:50px; height:50px;
    font-size:2rem;
}
    
/*  */
#cont{ outline:2px solid red;
    position:relative; overflow:hidden;
    width:600px; height:600px;
    margin:0 auto;}
 
#slider{
    display:flex;
    position:relative;
    height:100%;
    background:yellow;
    transition:transform .5s;}
 
#slider li{
    display:flex;
    justify-content:center;
    align-items:center;
    background:#fff;
    width:600px;height:100%;
    font-size:4vw;
    border:1px solid black;
    cursor:grab;}
#slider li:active{cursor:grabbing;}
#slider li > *{pointer-events:none;user-select:none;}
 
/*  */
#pager{
    display:flex;
    justify-content:center;
    position:relative;
    width:100%;
    margin-top:2rem; padding:1rem;
    background:rgba(255,255,255,.5);}
 
#pager button{
    width:20px;height:20px;
    margin:0 5px;
    border-radius:50%;
    border:none;
    cursor:pointer;}
#pager button.on{background-color:red;}
cs



JS

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
const btn_stop = document.getElementById('btn_stop');
const btn_play = document.getElementById('btn_play');
const arrows = document.getElementById('arrows');
const slider = document.getElementById('slider');
const li = slider.children;
const li_LEN = li.length;
const li_WID = 600;
const pager = document.getElementById('pager');
 
let pos = {
    prev : 0,
    now  : 0
}
 
let order = 0;
let sliderMove = 0;
let arrowTarget;
 
/* 01-1. 초기세팅 - UL넓이 정렬 */
slider.style.width = `${li_WID * li_LEN}px`;
 
/* 01-2. 초기세팅 - 페이저 추가 */
let pg;
for(let i=0; i<li_LEN; i++){
    pg = document.createElement('BUTTON');
    pg.setAttribute('data-order',i);
    pager.appendChild(pg);
}
pager.children[0].classList.add('on');
 
 
 
 
/* ✨✨✨  ======== GRAB SLIDE  ========*/
slider.addEventListener('mousedown',moveStart);
slider.addEventListener('mouseup',moveEnd);
slider.addEventListener('touchstart',moveStart_touch);
slider.addEventListener('touchend',moveEnd_touch);
 
function moveStart(e){
    stopSlide();
 
    e = e || window.event;
    pos.prev = e.clientX;
}//moveStart
 
function moveEnd(e){
    e = e || window.event;
    pos.now = e.clientX;
    finalEnd();
}//moveEnd
 
function moveStart_touch(e){
    stopSlide();
    pos.prev = e.touches[0].pageX;
}//moveStart_touch
 
function moveEnd_touch(e){
    e = e || window.event;
    pos.now = e.changedTouches[0].pageX;
    finalEnd();
}//moveEnd_touch
 
function finalEnd(){
    if(pos.prev > pos.now){
        onOrder(1);
    }else{
        onOrder(-1);
    }
    justPager(order);
    caculMove(order);
    moveSlide();
}//finalEnd
 
 
/*  ======== ✨ 순서 ======== */
function onOrder(num){
    order += num;
    if(order < 0){order = li_LEN - 1;}
    if(order > li_LEN - 1){order = 0;}
    console.log(order);
    return order;
}//onOrder
 
/*  ======== ✨ 움직임 계산  ======== ✨  */
function caculMove(num){
    sliderMove =  -(num * li_WID);
}//caculMove
 
/*  ======== ✨ 움직이기 */
function moveSlide(){
    slider.style.transform = `translateX(${sliderMove}px)`;
}//moveSlide
 
 
 
 
/* 📍  ======== 페이저 표시 관련 ======== */
pager.addEventListener('click',(e)=>{onPager(e)});
 
function onPager(e){
    stopSlide();
 
    e = e || window.event;
    order = e.target.dataset.order;
    if(order == undefined || order == null){return;}
    order = Number(order);
 
    justPager(order);
    caculMove(order);
    moveSlide();
}//onPager
 
function offPager(){
    for(let btns of pager.children){ btns.classList.remove('on');}
}//offPager
 
function justPager(num){
    offPager();
    pager.children[num].classList.add('on');
}//justPager
 
 
/* ⚡ ======== 좌우 화살표 관련 ========*/
arrows.addEventListener('click',(e)=>{onArrow(e)});
 
function onArrow(e){
    stopSlide();
 
    e = e || window.event;
    arrowTarget = e.target.dataset.flow;
    if(arrowTarget == undefined || arrowTarget == null){return;}
 
    switch(arrowTarget){
        case "prev" :
            onOrder(-1);
            break;
        case "next" :
            onOrder(1);
            break;
        default:
            break;
    }
    justPager(order);
    caculMove(order);
    moveSlide();
}//onArrow
 
 
/* ⏰ ========== 자동 재생 관련 ========== */
let myTime;
 
function autoSlide(){
    onOrder(1);
    justPager(order);
    caculMove(order);
    moveSlide();
    myTime = setTimeout(autoSlide,1500);
}//autoSlide
 
function stopSlide(){
    clearTimeout(myTime);
}//stopSlide
 
 
/* ========== 멈춤 / 다시 재생 ========== */
btn_stop.addEventListener('click',()=>{
    stopSlide();
});
 
btn_play.addEventListener('click',()=>{
    stopSlide();
    setTimeout(autoSlide,1000);
});
 
 
/* ----- ⏰ 최종 실행 ----- */
autoSlide();
cs

 

소스코드 다운로드

grabSlider_final.html
0.00MB
grabSlider_final.js
0.00MB
style_3.css
0.00MB