자바스크립트 터치 슬라이드 - jabaseukeulibteu teochi seullaideu

이 팁은 터치슬라이드이긴 한데, 터치 이벤트 쪽에 팁이 많음..

#터치슬라이드 #터치이벤트

1) jQuery 터치 슬라이드 간편용

#jquery.touchslider #jquery.event.drag
//blog.naver.com/bigdead/220178246744

//jsfiddle.net/eond/jp1t0r5c/1/ 

2) jquery 터치 슬라이드

//stackoverflow.com/questions/4755505/how-to-recognize-touch-events-using-jquery-in-safari-for-ipad-is-it-possible

3) dohoons

//beone.tistory.com/536

4) 자바스크립트 터치&마우스 슬라이드(1차 완성) & (2차완성)

[출처] 자바스크립트 터치&마우스 슬라이드(1차 완성)|작성자 Roka

//blog.naver.com/the602/220064835615

//blog.naver.com/the602/220065840782

5) [JQuery] 소스정리 : 터치 슬라이드 (모바일 겸용) 

[출처] [JQuery] 소스정리 : 터치 슬라이드 (모바일 겸용)|작성자 규

//blog.naver.com/mobilism/70150817964

6) [tip] jQuery 터치 이벤트 사용시 event.touches가 undefined 일때
//august5pm.tistory.com/30

7) 기타 - 검색 아이콘 변경(이건 왜..) 

//codepen.io/mattbraun/pen/eNwmJG

8) [jQuery] 제이쿼리를 사용한 드래그, 터치 이미지 슬라이드 샘플

//ryuseunghyun.tistory.com/4185

9) [HTML5+CSS3]제이쿼리(jQuery)와 Swipe JS 파일을 활용한 터치슬라이드 갤러리 소스
//ryuseunghyun.tistory.com/category/Information/html+css
touchSlide.zip 

//ryuseunghyun.tistory.com/2751
swipeGallery.zip

10) [HTML5+CSS3]모바일에서 터치, 슬라이드 모션 구현에 유용한 자바스크립트 라이브러리
//ryuseunghyun.tistory.com/2750
Swipe-master.zip

//swipejs.com

11) 터치해서 쓸어 넘기기를 해주는 jQuery 라이브러리
//opencode.co.kr/bbs/board.php?bo_table=jquery_tips&wr_id=103
부트스트랩 3.0에 터치 기능을 추가하는 것에 대한 게시글
//lazcreative.com/blog/adding-swipe-support-to-bootstrap-carousel-3-0/

1. jQuery mobile의 touch 기능 (touch lib만 빼서 쓰라는...)
2. hammer.js
고작 3k. jQuery가 없어도 동작한다는...ㄷㄷㄷ
//eightmedia.github.io/hammer.js/
3. touch swipe plugin
//labs.rampinteractive.co.uk/touchSwipe/demos/

설명자료
//labs.rampinteractive.co.uk/touchSwipe/docs/symbols/%24.fn.swipe.html

Features

  • Detects swipes in 4 directions, "up", "down", "left" and "right"
  • Detects pinches "in" and "out"
  • Supports single finger or double finger touch events
  • Supports click events both on the touchSwipe object and its child objects
  • Definable threshold / maxTimeThreshold to determin when a gesture is actually a swipe
  • Events triggered for swipe "start","move","end" and "cancel"
  • End event can be triggered either on touch release, or as soon as threshold is met
  • Allows swiping and page scrolling
  • Disables user input elements (Button, form, text etc) from triggering swipes

12) jQuery.event.swipe
//stephband.info/jquery.event.swipe/

//sir.co.kr/bbs/board.php?bo_table=pg_talk&wr_id=7493

ps. 남들은 쉽게 하나만 찾으면 그걸 사용하면 되는데 저는 뭐든 다 찾아봐야 직성이 풀리나봅니다.
그래도 조금이라도 뭐가 더 낫겠지 하는 걸 찾아보는 희한한 성격이 있어서 제 스스로가 다 피곤하네요.

(정리라도 좀 잘하지! ㅠ)

미리보기  다운로드

심플한 가로 슬라이더입니다.
엄청난 슬라이드 효과는 없습니다.  그냥 모바일에서 터치 슬라이딩하면 스와이핑 되고, 마지막 슬라이드에서 터치 드래그 하면 다시 처음으로 이어지는 슬라이드입니다.
자동으로 시간에 맞춰 슬라이딩 되고, 슬라이드 반복을 제어 할 수 있습니다.
데스크탑에서 클릭 스와이핑 기능을 제어할 수 있습니다.

슬라이딩 되는 모션을 'easeOutQuart'과 같이 꾸미고 싶으시다면 jquery.easing.js 를 같이 사용하시어 설정하시면 됩니다.

먼저 <head> 안에 플러그인을 넣습니다.

<script type="text/javascript" src="./js/vinyli.viSimpleSlider.js"></script>

그리고 슬라이드를 감쌀 div를 만들고 id를 부여합니다.
그 안에 ul을 만들어 li 안에 슬라이드 할 것들을 넣습니다.

<div id="testDiv"> <ul> <li data-link="링크 주소 1"> <img src="이미지 경로 1"> </li> <li data-link="링크 주소 2"> <img src="이미지 경로 2"> </li> </ul> </div>  

그리고 마지막으로 </body> 바로 위에 실행 코드를 넣습니다.
위에 div에 부여한 id를 찾아 실행하게 됩니다.

<script> $('#testDiv').viSimpleSlider({ ease : 'easeOutQuart', autoPlay : true, autoTime : 6000, speed : 400, mobileSwipe: true, desktopSwipe : true }); </script>

추가 옵션은 ease, indicate, arrow, autoPlay, autoTime, speed, loop, mobileSwipe, desktopSwipe 이 있으며 미리보기를 클릭하면 자세한 사용법이 나옵니다.

미리 보기  : //bongsunga.com/blog/labfile/plugin.viSimpleSlider/

1. swipe란?

swipe란 손가락을 댄 후, 일직선으로 드래그하는 것을 말한다.

2. 그래서 무엇을 만들 것이냐?

상단 gif와 같다.

3. swiper.js 있는데 왜 만드냐?

(1) 공부용
(2) 경량화
(3) 문서 읽기 싫음 (이미 읽음)
(4) 리액트에서 쉽게 사용하기 위해서 react-id-swiper를 다운받아야 함

그렇다고 이 문서가 react로 포팅된 swiper는 아님.

4. 시작합니다.

HTML

먼저 DOM 틀부터 필요하다.
잇몸이 있어야 이를 끼워넣든 하지 않겠는가

<div id="container"> <div id="inner"> ... 다량의 이미지 태그 </div> </div>

왜 두번 div로 감쌀까?

container는 넘치는 컨텐츠를 보여주지 않기 위해
overflow: hidden 을 사용한다.

inner는 실제 컨텐츠를 담는 공간이다.
container가 보여주지 않는 공간(넘치는 공간)을 다 담는 것이다.

개발자 도구를 켜서 inner부분을 잡아보면 container와 크기가 같은 것을 볼 수 있다.
div는 display: block 속성을 기본으로 가지고 있고,
이는 상위 객체의 width를 따라간다.

그래서 overflow: hidden인 container와, inner 모두 같은 px이다.

CSS

body { margin: 0; } #container { height: 300px; overflow: hidden; } #inner { display: flex; height: 300px; transition-property: transform; } img { width: 100%; }

body에 보기 싫은 margin이 8px이나 껴있으니 빼주자.

inner에 display: flex 를 준 이유는 이미지를 일렬로 나열하기 위함이다.

display: flex 의 기본 flex-direction 은 row 이기 때문이다.

transition-property: transform 트랜지션은 transform이 일어날 때만 사용하겠다는 뜻이다.

이렇게 하면 한 화면에 하나의 이미지가 보일 것이다. (모바일 기준)

Javascript

먼저 eventlistener의 세 종류를 알아야 한다.

window.addEventListener('touchstart', callback); window.addEventListener('touchmove', callback); window.addEventListener('touchend', callback);

세 가지 이벤트 모두 터치 위치를(스크린에 올려둔 마우스의 포인터 기준) 알 수 있고,
각각의 이름과 같이 touchstart 는 터치를 시작한 시점 touchmove 는 움직이고 있을 당시
touchend 는 터치가 끝난 시점을 잡아낸다.

나는 container 라는 이름을 가진 div가 스와이프 됨에 따라
inner가 보여주는 슬라이드가 변하는 것을 원하기 때문에
container에 eventListener 를 부여하기로 했다.

const container = document.getElementById('container'); const inner = document.getElementById('inner'); let startPos = 0; let offset = 0; let curPos = 0; const screenWidth = container.clientWidth;

전역 변수로 다음과 같이 지정하였다.

startPos는 touchstart 지점에서 찍히는 screenX를 뜻한다.
offset은 touch를 시작하고 나서의 변위를 뜻한다.
curPos는 현재 슬라이드의 위치, inner가 마지막에 움직이는 위치를 위해 정의했다.

window.onload = function() { 여기에 밑의 세가지 체크포인트가 들어간다. }

checkpoint 1

먼저 우리는 터치를 드래그 함으로써 이미지를 넘길 것이기 때문에 터치를 시작한 위치를 알아야 한다.

container.addEventListener('touchstart', (e) => { startPos = e.touches[0].pageX; });

checkpoint 2

스와이프를 끝마친 다음에야 슬라이드가 넘어가는 비(非)유동적인 swiper를 만들지 않기 위해서는
이미지가 내가 스와이프 하고 있는 동안 을 따라와야 한다.

따라서 경위(offset)를 구해주는데 여기에 curPos를 더한 이유는
현재 몇번째 슬라이드에서 스와이프를 하고 있는지를 적용하기 위해서다.

긴 말 할 것 없다. transform으로 x값을 translate해주자.
이 때 transitionDuration은 바로바로 드래그에 이미지가 딸려오게 하기 위함이다.

container.addEventListener('touchmove', (e) => { offset = curPos + (e.targetTouches[0].pageX - startPos); inner.style.transform = `translate3d(${offset}px, 0px, 0px)`; inner.style.transitionDuration = '0ms'; });

checkpoint 3

앞과 마찬가지로 변위(offset)를 구해주자.

destination을 따로 구한 이유는

앞이나 뒤의 일정 공간을 더 끌어도 결국에는 마지막 혹은 첫번째 슬라이드로 돌아오게 하기 위함이다.

Math.round를 해준 이유는 반 이상 이미지를 드래그 했냐고 물어보는 것이다.

container.addEventListener('touchend', (e) => { const sum = curPos + (e.changedTouches[0].pageX - startPos); let destination = Math.round(sum / screenWidth) * screenWidth; if (destination > 0) { destination = 0; } else if (destination < -(screenWidth * (이미지의 총 갯수 - 1))) { destination = -(screenWidth * (이미지의 총 갯수 - 1)); } inner.style.transform = `translate3d(${destination}px, 0px, 0px)`; inner.style.transitionDuration = '300ms'; curPos = destination; setTimeout(() => { inner.style.transitionDuration = '0ms'; }, 300); });

근데, 돌아올 때 0ms만에 돌아오면 뒤의 여백을 땡긴 의미가 없지 않는가?

transitionDuration 을 300ms로 바꾸어주고,

300ms 후에 다시 0ms으로 바꾸어준다.

막 자신있게 이야기해서 마치 라이브러리 하나를 위의 코드로 단축한 것 같지만,
굉장히 중요한 기능들은 구현하지 못했다.

예를 들면 드래그 한 범위가 좁더라도 그 스피드가 빠르면 스크롤 스피드를 적용하여
가중치를 곱해주어야 꼭 반이 넘지 않아도 슬라이드가 넘어가는데,

touch의 callback parameter를 유심히 찾아보았으나, 그런 속성은 찾지 못하였다.

혹시 알고 있다면 댓글에 써주길 간곡히 요청한다. ㅠㅠ

Toplist

최신 우편물

태그