jQueryを使ってスマートフォン用のイベントを扱ってみた

スマートフォン用のサイトを作る場合は、jQuery Mobileやら、jQTouchやら、Sencha Touchやら色々ありますが、ちょっとそこまで必要ないときに、スマートフォン特有のイベントをjQueryを使って扱えないか触ってみました。

スマホ特有のイベント

スマホ特有のイベントは幾つかありますが、今回は特に使われるであろうタッチ、スライド、ピンチイン、ピンチアウトに重点を置いて調べてみました。

上記操作に必要なイベントは以下の通りです。

  • touchstart
  • touchmove
  • touchend
  • touchcancel
  • gesturestart
  • gesturechange
  • gestureend

「touch***」というイベントが画面に指でタッチした、している時のイベント、「gesture***」というイベントが「二本指以上」の操作(ピンチイン、ピンチアウト、回転等)を行っている時のイベント、と考えていただければ良いかと思います。

また、「touch***」は一本指だけでなく、二本指以上の操作でも実行されるため、今何本の指が画面上にタッチされているかを確認しながら動作する必要があります。

イベントの実行される流れ

一本指での操作の場合

一本指だけのイベント進行は単純で以下のように進行していきます。

1.touchstart
指が画面をタッチした時に実行
2.touchmove
タッチした指を画面上で動かした時に実行
3.touchend
画面上から指を離した時に実行
マウスイベントとほとんど変わらないと思います。

二本指での操作の場合

二本指が画面上にタッチされた時は少し特殊で、以下のような順番でイベントが進行します。

1.touchstart
一本目の指が画面をタッチした時に実行
2.gesturestart
二本目の指が画面をタッチした時に実行
3.touchstart
gesturestartの後に実行
4.gesturechange
タッチした指を画面上で動かした時に実行
5.touchmove
gesturechangeの後に実行
6.gestureend
指を一本画面から離した時に実行
7.touchend
gestureendの後に実行
8.touchend
もう一本の指を画面から離した時に実行
何れかの指が画面にタッチした時、離した時に毎回touchイベントが実行されます。
また、二本タッチされている時は同時にgestureイベントも実行されるのですが、その際はgestureイベントが優先される様です。

イベント実行時に得られる値

イベント実行時に得られる値も、「touch***」と「gesture***」で異なります。

touchイベント

主に画面を触っている指の数や、位置を取得することが可能です。

function touchHandler( event ) {  
    // 画面を触っている指の本数だけ配列で渡されます
    var touches = event.touches;
    // 一本目の指の位置取得
    alert( "x = " + touches[0].pageX + " / y = " + touches[0].pageY );
}

gestureイベント

主にピンチインなどの動作によって変化した値を取得することが可能です。

function gestureHandler( event ) {  
    // ピンチインによる拡大率
    var scale = event.scale;
    // 回転角度
    var rotate = event.rotation;
    alert( "scale = " + scale + " / rotetion = " + rotate );
}

jQueryで利用する際の注意点

jQueryのbindを持ちいてイベントを実行した場合、上記値の読み方が若干変わります。

addEventListenerを用いた方法では以下のように記述しますが。

document.getElementsById("touch").addEventListener("touchstart", touchHandler, false);  
function touchHandler( event ) {  
    alert( event.touches[0].pageX );
}

jQueryを用いた場合は、引数にtouchesが与えられておらず、さらに「originalEvent」内から取得する必要があります。
上のコードをjQueryで記述すると以下のようになります。

$("#touch").bind("touchstart", touchHandler);
function touchHandler( event ) {  
    alert( event.originalEvent.touches[0].pageX );
}

詳しくは調べていませんが、引数のeventはjQuery内で生成した変数、originalEventがaddEventListenerで渡されている値と同等なのかな?と思っています。

また、touchイベントはiPhone、Andoroidで動作確認できましたが、gestureイベントはAndroidで動作しません。
その他動作環境については、こちらのページにまとめられているようなので、参考にしようかと思います。

参考サイト