Javascript Mobile Events의 이해

Posted by in Research

W3C의 터치 이벤트

지금까지 HTML 및 Javascript 등의 웹 표준 기술은 마우스와 키보드만 고려한 사용자 인터페이스 이벤트만 지원했습니다. 그러나 스마트폰이나 태블릿 등의 보급으로 화면을 손가락이나 펜으로 조작하는 일이 많아지면서 멀티 터치 조작과 같은 마우스 및 키보드와는 다른 형식의 조작을 감지 할 수 있도록 하는 새로운 이벤트 사양을 책정 할 필요가 있었습니다. 이윽고 2013년 10월에 W3C의 WebEvents Wroking Group은 손가락이나 펜을 이용한 조작에 관한 TouchEvents의 사양을 채택 완료하고 권고(Recommendation)를 발표하게됩니다.

TouchEvents에서 추가 된 이벤트 유형은 네 가지 입니다.

  • touchstart
  • touchend
  • touchmove
  • touchcancel

이들을 이용해서 요소에 터치 이벤트를 리스닝할 수 있을 뿐만 아니라 여러 손가락의 위치에 대한 터치 정보 등도 얻을 수 있게 되었습니다. 이 정보를 이용해 줌이나 회전 등의 일반적인 멀티 터치 제스처 뿐만 아니라 거의 모든 종류의 터치 조작에 대응할 수 있습니다.

이미 시장에 출시된 많은 디바이스가 TouchEvents를 구현하고 있고 신뢰할 수 있는 제스처 라이브러리도 나와있기 때문에 특별한 변화는 없을 수도 있지만 Recommendation은 모든 합의를 끝낸 후 W3C 멤버들과 감독에게 승인을 받은 문서로써 채택한 사양이 쓰이기를 권장한다는 뜻이며 사양의 책정이 끝났으니 기술이 안정되었다고 보면되겠습니다. Touch Events의 지원 현황은 CAN I USE를 참고하세요.

아래의 이벤트들을 이용해 제스처 효과(double tap, long tap등)를 개발하신다면 touchstart와 gesturestart에 event.preventDefault()를 지정해 기본 이벤트를 꺼주는게 좋습니다. 그래야 브라우저가 가지고 있는 기본 이벤트(double tap 한다면 브라우저가 그 부분을 클로즈업 한다던지)가 동직하지 않아 자연스러운 제스처 효과가 가능합니다.

touchstart

디바이스 화면에 손가락이 닿는 순간 발생하는 이벤트입니다. 하지만 WindowPhone에서는 touchstart가 발생하지 않고 pointerdown이 발생합니다.

touchend

디바이스 화면에 손가락이 닿은 상태에서 손가락을 떼어내면 발생하는 이벤트입니다. 주의해야할 점은 Android 4.x에서 touchstart, touchmove시 e.preventDefault()를 수행하여 브라우저의 스크롤을 정지해주지 않으면 touchend 이벤트가 발생하지 않는다는 것입니다. 또한 touchend는 mouseup과 대칭되지 않으며 간헐적으로 touchend 대신 touchcancel 이벤트가 발생하는 경우가 있습니다. 그러므로 문제가 되지 않는다면 touchend 이벤트 리스너를 touchcancel에도 등록해주는 편이 좋습니다.

touchmove

디바이스 화면에 손가락이 닿은 상태에서 손가락을 움직이면 발생하는 이벤트 입니다. 주의해야할 점은 일부 Android 디바이스에서 touchstart시 e.preventDefault()를 수행하여 브라우저의 스크롤을 중지하지 않으면 touchmove가 처음 몇 번 발생하지 않는다는 것입니다. 또한 처음 몇 번의 touchmove가 발생할때 e.preventDefault()를 수행해야 touchmove가 지속적으로 발생할 수 있는 Android 디바이스도 존재한다고 합니다.

touchcancel

터치 이벤트가 시스템으로 인해 취소 될 때 발생하는 이벤트입니다. 전화나 메일의 착신 등 시스템 측의 어떤 동작으로 인해 터치 이벤트가 취소되는 경우에 발생합니다. 하지만 WindowsPhone에는 구현되어 있지 않습니다. WindowsPhone에서는 pointercancel이 발생합니다.

Apple의 추가 터치 이벤트

Apple은 조금 더 발전된 형태의 터치 이벤트 세 가지를 추가로 제공하고 있습니다. 하지만 이는 W3C의 사양이 아닌 비표준이며 아쉽게도 iPhone과 iPad등의 iOS 단말에만 탑재되어있고 Android와 WindowsPhone에는 구현되어있지 않으므로 서비스 개발시엔 사용을 지양하는 편이 좋습니다.

  • gesturestart
  • gesturechange
  • gestureend

gesturestart

두 번째 손가락이 디바이스의 화면에 닿을때 발생하는 이벤트 입니다. 첫 번째 손가락이 닿을때는 touchstart 가 발생하고 두 번째 손가락은 gesturestart와 touchstart가 같이 발생합니다. 세 번째 부터는 다시 touchstart만 발생합니다.

gesturechange

디바이스 화면에 2개 이상의 손가락이 닿은 상태에서 손가락을 움직이면 발생하는 이벤트 입니다. gesturechange는 touchmove 발생 후 발생합니다.

gestureend

디바이스 화면에 2개 이상의 손가락이 닿은 상태에서 손가락을 떼어내면 발생하는 이벤트 입니다. gestureend는 touchend 이벤트 발생 후 발생합니다. 이 이벤트는 2개 이상의 손가락중 하나만 떨어져도 발생합니다.

MS의 터치 이벤트

WindowsPhone에서는 W3C의 권고와는 다른 이벤트명을 사용합니다. 아래의 이벤트는 IE10과 WindowsPhone8 등에 탑재되어 있습니다. 하나 주의해야할 점은 IE10은 MSPointerDown처럼 벤더 접두사를 붙여 이벤트명을 지정해야 한다는 것입니다.

  • pointerdown
  • pointerup
  • pointerhover
  • pointerover
  • pointerout
  • pointermove
  • pointercancel

터치 이벤트 인터페이스

Touch Interface

이 인터페이스는 터치 이벤트에 대한 각각의 터치 포인트를 설명합니다. Touch객체가 만들어지면 속성은 변하지 않습니다.

clientX

스크롤을 제외한 뷰포트의 상대적인 픽셀의 수평 좌표

clientY

스크롤을 제외한 뷰포트의 상대적인 픽셀의 수직 좌표

identifier

손가락을 고유하게 식별하는 번호, 터치 포인트가 활성화 될 때 활성화된 다른 터치 포인트와 구별되는 식별자

pageX

스크롤을 포함한 뷰표트의 상대적인 픽셀의 수평 좌표

pageY

스크롤을 포함한 뷰표트의 상대적인 픽셀의 수직 좌표

screenX

픽셀 화면상의 상대적 수평 좌표

screenY

픽셀 화면상의 상대적 수직 좌표

target

화면에 손가락이 처음 닿은 접촉점이 EventTarget이며 타겟 엘리먼트를 벗어나더라도 EventTarget은 변하지 않습니다.

TouchEvent Interface

이 인터페이스는 touchstart, touchend, touchmove, touchcancel 이벤트 타입을 정의합니다. TouchEvent객체가 만들어지면 속성은 변하지 않습니다.

changedTouches

이벤트에 할당된 모든 접촉점에 대한 터치 리스트 입니다. touchstart 이벤트의 changedTouches는 현재 이벤트와 함께 바로 활성화된 터치점(touch point)의 리스트입니다. touchmove 이벤트의 changedTouches는 마지막 이벤트에서 이동한 터치점의 리스트입니다. touchend와 touchcancel 이벤트의 changedTouches는 화면에서 막 떼어진 터치점의 리스트입니다.

targetTouches

현재 이벤트의 타겟인 엘리먼트에서 시작되어 화면을 터치하고 있는 모든 접촉점에 대한 터치 리스트입니다

touches

현재 화면을 터치하고 있는 모든 접촉점의 터치 리스트이며 터치된 구역의 정보를 담은 배열입니다. event.touches.length를 이용해 멀티터치 여부를 계산할 수 있습니다. 특정 터치의 좌표는 event.touches[i].pageX(pageY) 형식으로 가져올 수 있습니다.  안드로이드 2.x에서는 어떠한 경우에도 두 번째 터치 값을 알 수 없습니다. 즉 배열에는 항상 하나의 값만 존재합니다. 따라서 멀티 터치 제스처(pinch 등)를 구현할 수 없습니다.  1개의 터치를 활용한 제스처(swipe 등)는 구현 가능합니다.

제스처 라이브러리

터치 이벤트를 기반으로한 이미 많은 제스처 라이브러리가 있습니다. 제가 둘러 봤을때 당장 사용해도 될 만한 수준(이해비용이 낮고, 가볍고, 정확한)의 라이브러리는 2개입니다. 깃 허브 스타는 이 라이브러리가 대중화 되었는지에 대한 지표로 사용될 수 있습니다. 예를 들어 HighCharts가 1,200개 이며 jQuery가 27,142개입니다.

아래에 소개하는 라이브러리 외에도 TouchSwipe(1,450), jQueryTouchGestures, jQueryMobile(8,767), jqTouch(2,746), tap.js 등 많은 라이브러리가 있습니다. 여기를 참고하길 바랍니다.

Hammer.js

구현된 이벤트가 풍부하고 정확합니다. 디바이스 이슈 대응 등 관리가 잘되고 있습니다. 클라이언트가 제스처 플러그인을 추가로 등록해 사용할 수 있습니다. QuoJS와 더불어 단독 라이브러리로 특정 라이브러리를 의존하지 않습니다.

    • GithubStars : 6,338
    • fork : 995

QuoJS

필요한 이벤트만 모자라지 않게 구현하고 있는 경량 라이브러리입니다. 매우 우수한 수준의 이벤트 감지를 해줍니다.

    • GithubStar : 1,174
    • fork : 168

Google Trend

touch_librarys

도움되는 자료