-
hammer.js 또는 js의 터치이벤트JAVASCRIPT 2022. 2. 21. 13:20
터치&드래그에 관련된 라이브러린 hammer.js를 이용한다. 호환성도 좋아서 사용하기 좋다고한다.
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js" integrity="sha256-eVNjHw5UeU0jUqPPpZHAkU1z4U+QFBBY488WvueTm88=" crossorigin="anonymous"></script>
hammer.js의 CDN이다.
hammer를 이용해서 저번에 만든 캐러셀을 드래그해서 넘기는 기능을 구현해보자.
<div style="overflow: hidden; position: relative;"> <div class="slide-container"> <div class="slide-box img1"> <!-- <img src="/img/product1-1.jpg" alt=""> --> </div> <div class="slide-box img2"> <!-- <img src="/img/product2.jpg" alt=""> --> </div> <div class="slide-box img3"> <!-- <img src="/img/product3.jpg" alt=""> --> </div> </div> <button id="prev" class="prev btn-primary">⟨</button> <button id="next" class="next btn-primary">⟩</button> <div style="clear: both;"></div> </div>
이 html을 이용한다. 그리고 먼저 js셀렉터로 기능개발할 요소를 찾아준다.
var 이미지1 = document.querySelectorAll('.slide-box')[0]; //이미지1은 드래그 할 대상을 담은 변수 var 매니저 = new Hammer.Manager(이미지1); 매니저.add(new Hammer.Pan({ threshold: 0 })); //어떤 이미지를 hammer로 작동할건지 매니저를 만들어(new Hammer.Manager 이용) //add를 이용해 등록한다. Pan은 슬라이드를 뜻하며, threshold 이벤트 작동 한계점?이다. //threshold가 100이면 100px 드래그 했을 때 작동됨
그러고 나서,
매니저.on('pan', function(e) { //Pan이라는 이벤트 함수임 console.log(e.deltaX); //e.deltaX는 이동한 거리임(왼쪽은 - 오른쪽은 +) if (e.deltaX < -1) { $('.slide-container').css('transform', 'translateX('+e.deltaX+'px)'); if (e.isFinal) { //isFinal은 터치끝났는지 알려줌 $('.slide-container').addClass('transforming'); $('.slide-container').css('transform', 'translateX(-100vw)'); setTimeout(function() { $('.slide-container').removeClass('transforming'); },500); } } });
위처럼 e.deltaX를 쓰면 편리하게 드래그의 이동거리를 계산할 수 있다. 하지만, hammer라이브러리를 안쓰면
touchstart, touchmove, touchend로 (시작좌표-최종좌표)로 움직인 거리를 직접 계산해야 한다.
세번째줄에, e.deltaX < -1은 이미지를 왼쪽으로 움직이면 즉, 음수 값이 된다면을 나타낸다. 움직이면 container가 드래그된 만큼 e.deltaX px만큼 움직이게 된다. 그러고 마우스를 떼면 다음 이미지가 나와야하므로 e.isFinal로 터치가 끝났을 때 -100vw움직이게 설정한다.
.transforming { transition: transform 0.5s; }
그리곤 transforming이란 클래스를 새로만들어 transition을 주고 내가 원할 때 클래스를 붙였다가 땠다가 하면 된다. 터치중엔 transition을 안쓰고 터치가 끝나면 transition을 쓰고 싶으므로 transition의 시간인 0.5초가 지난 후에 transforming클래스를 때주면 된다. 그러므로 setTimeOut 함수를 사용해서 0.5초 후에 지워주세요 라는 코드를 설정했다.
만약, 사진이 여러개가 되면
지금보이는사진 == 1 //현재사진을 변수로 담고 if (e.isFinal && 지금보이는사진 == 1) { //isFinal은 터치끝났는지 알려줌 $('.slide-container').addClass('transforming'); $('.slide-container').css('transform', 'translateX(-100vw)'); setTimeout(function() { $('.slide-container').removeClass('transforming'); },500); 지금보이는사진 += 1; } else if (e.isFinal && 지금보이는사진 == 2) { //isFinal은 터치끝났는지 알려줌 $('.slide-container').addClass('transforming'); $('.slide-container').css('transform', 'translateX(-200vw)'); setTimeout(function() { $('.slide-container').removeClass('transforming'); },500); }
이런식으로 변수를 이용해 담고 현재 사진에 맞게끔 이동하게 해주면된다. 그리고 사진이 많아지면 반복문을 사용하며 지금보이는사진 값에 변수를 놓고 사용하면 될 것 같다.
js로도 터치이벤트 구현이 가능하다.
//캐러셀 마우스로 움직이기 //e.clientX 하면 마우스의 x좌표 출력 //우선 내가 얼만큼 드래그했는지 알아야 함 var 시작좌표 = 0; var 누름 = false $('.slide-box').eq(0).on('mousedown', function(e) { 시작좌표 = e.clientX; 누름 = true }); $('.slide-box').eq(0).on('mousemove', function(e) { if (누름 == true) { $('.slide-container').css('transform', `translateX(${e.clientX-시작좌표}px)`) } }); $('.slide-box').eq(0).on('mouseup', function(e) { 누름 = false; if((e.clientX-시작좌표) < -100) { $('.slide-container').css('transform', 'translateX(-100vw') $('.slide-container').addClass('transition-class'); } else { $('.slide-container').css('transform', 'translateX(0vw') } setTimeout(()=>{ $('.slide-container').removeClass('transition-class'); },1000) })
e.clientX를 하면 현재 좌표를 출력하는데, 시작좌표를 0으로 함수 밖에서 선언하고, slide-box를 눌렀을 때,
mousedown (클릭을 함)했을 때, 시작좌표를 e.clientX로 담아주고, 누름이란 변수를 false에서 true로 바꿔준다.
그리고, 마우스가 움직일 때, mousemove(마우스가 움직이는 중)이면, 누름이 true일때,
즉 클릭 후 움직일때만, slide-container를 움직인만큼 움직여준다.
그리고, 클릭을 떼면 그 자리에서 누름이 false가 되면서, slide-container이 멈추게 된다.
그리고 부드럽게 움직이게 하기 위해서, transition 1초를 붙이구 사진이 다움직이면 1초후 클래스를 제거해주면 된다.
만약, 모바일 환경에서 하려면, touchstart, touchmove, touchend로 각각 바꿔주면 된다.
대신, e.clientX가 아니라 e.touches[0].clientX 이렇게 써줘야 잘 작동하며,
touchend에는 e.changedTouches[0].clientX로 써줘야 한다.
'JAVASCRIPT' 카테고리의 다른 글
setTimeout (0) 2022.02.28 Typewriting (2) 2022.02.21 Scroll UI (2) 2022.02.18 ajax (2) 2022.02.17 DOM의 개념과 이벤트리스너 ready, load (2) 2022.02.16