こんにちは!プロダクト企画担当の林です。
今回は、前回予告していた通り、タッチイベントについて書かせていただきます。
他所でもタッチイベントについて取り扱っていますが、当記事でのポイントは、
- jQuery を使っている。(jQuery Mobile は不要です)
- iOS / Android で動作確認済み。
- タッチできない PC の場合、マウスで動く。
この3点です。
こちらを実際に動作するコードにて解説します。
動作確認環境
- タッチ環境 → iPhone / iPad / Android
- マウス環境 → Sleipnir / IE / Firefox / Google Chrome / Safari / Opera
タッチイベントについて
タッチイベントとは、スマートフォンなどで画面を直接指でタッチしたときに発生するイベントのことです。
イベントの種類
- touchstart : タッチしたときに発生する
- touchmove : タッチしたまま動かしたときに発生する
- touchend : タッチ状態から離れたときに発生する
- touchcancel : タッチ中に電話がかかってきた場合などに発生する(通常は使わない)
位置を取得するプロパティ
タッチされている画面位置は以下のプロパティで取得することができます。
- event.changedTouches[0].pageX : タッチされている画面位置の X 座標
- event.changedTouches[0].pageY : タッチされている画面位置の Y 座標
changedTouches の [0] を [1] にするとマルチタッチの2本目の指の位置を取得できたりします。
通常アプリでもない限り、マルチタッチは使用しないので今回は扱いません。
マウスの場合
マウスの場合は、以下のイベントでタッチイベントの代役に使います。
- mousedown : マウスボタンを押し込んだときに発生する(touchstart の代役)
- mousemove : マウスボタンを押しながらドラッグしたときに発生する(touchmove の代役)
- mouseup : マウスボタンを離したときに発生する(touchend の代役)
マウスがある位置は以下のプロパティで取得することができます。
- event.pageX : マウスがある位置の X 座標
- event.pageY : マウスがある位置の Y 座標
各イベントの使い方
タッチイベントとマウスイベントをそれぞれコードで紹介します。
touchstart イベント
<script type="text/javascript"> /* タッチの開始時のイベント */ $('#hoge').bind('touchstart', function() { event.preventDefault(); // ページが動いたり、反応を止める(A タグなど) this.pageX = event.changedTouches[0].pageX; // X 座標の位置 this.pageY = event.changedTouches[0].pageY; // Y 座標の位置 }); </script>
touchmove イベント
<script type="text/javascript"> /* タッチしたまま動かしたときのイベント */ $('#hoge').bind('touchmove', function() { event.preventDefault(); // ページが動くのを止める this.pageX = event.changedTouches[0].pageX; // X 座標の位置 this.pageY = event.changedTouches[0].pageY; // Y 座標の位置 }); </script>
ここはたくさん呼ばれるので重い処理を書かないように気をつけましょう。
また、指を動かさなければ呼ばれない場合があります。忘れないように。
touchend イベント
<script type="text/javascript"> /* タッチ状態から離れたときのイベント */ $('#hoge').bind('touchend', function() { /* 終了処理が必要ならここに書く */ /* このイベントは、位置を取得できないので注意 */ }); </script>
pageX, pageY が取得できないので touchstart/touchmove で変数などに格納し、それを使いましょう。
mousedown イベント(touchstart の代役)
<script type="text/javascript"> /* マウスボタンを押し込んだときのイベント */ $('#hoge').bind('mousedown', function() { event.preventDefault(); // ページの反応を止める(A タグや画像の反応など) this.pageX = event.pageX; // X 座標の位置 this.pageY = event.pageY; // Y 座標の位置 }); </script>
mousemove イベント(touchmove の代役)
<script type="text/javascript"> /* マウスボタンを押しながらドラッグしたときのイベント */ $('#hoge').bind('mousemove', function() { this.pageX = event.pageX; // X 座標の位置 this.pageY = event.pageY; // Y 座標の位置 }); </script>
ここもたくさん呼ばれるので重い処理を書かないように気をつけましょう。
また、マウスを動かさなければ呼ばれない場合があります。忘れないように。
mouseup イベント(touchend の代役)
<script type="text/javascript"> /* マウスボタンを離したときのイベント */ $('#hoge').bind('mouseup', function() { this.pageX = event.pageX; // X 座標の位置 this.pageY = event.pageY; // Y 座標の位置 }); </script>
実践
Touch Me !!
Touch Me !!
タッチイベントとマウスイベントをミックスして、画像をタッチで動かす処理を書いてみました。
↑の画像は実際に以下のコードで動くサンプルです。
(iPhone/iPad/Android/PC 全対応です)
動かすオブジェクトの HTML コード
スクリプトコード
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> <script type="text/javascript"> /* タッチできる環境なら true、そうでないなら false 。 ここで先に判別しておきます。 */ var isTouch = ('ontouchstart' in window); /* hoge のイベントを jQuery.bind で捕獲します。 */ $('#hoge').bind({ /* タッチの開始、マウスボタンを押したとき */ 'touchstart mousedown': function(e) { // ページが動いたり、反応を止める e.preventDefault(); // 開始位置 X,Y 座標を覚えておく // (touchmove イベントを通らず終了したときのために必ず覚えておくこと) this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); this.pageY = (isTouch ? event.changedTouches[0].pageY : e.pageY); // 現在の hoge の場所を覚えておく this.left = $(this).position().left; this.top = $(this).position().top; // タッチ処理を開始したフラグをたてる this.touched = true; }, /* タッチしながら移動、マウスのドラッグ */ 'touchmove mousemove': function(e) { // 開始していない場合は動かないようにする // 過剰動作の防止 if (!this.touched) { return; } // ページが動くのを止める e.preventDefault(); // 移動先の hoge の位置を取得する this.left = this.left - (this.pageX - (isTouch ? event.changedTouches[0].pageX : e.pageX) ); this.top = this.top - (this.pageY - (isTouch ? event.changedTouches[0].pageY : e.pageY) ); // hoge を移動させる $(this).css({left:this.left, top:this.top}); // 位置 X,Y 座標を覚えておく this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); this.pageY = (isTouch ? event.changedTouches[0].pageY : e.pageY); }, /* タッチの終了、マウスのドラッグの終了 */ 'touchend mouseup': function(e) { if (!this.touched) { return; } // タッチ処理は終了したため、フラグをたたむ this.touched = false; // 必要なら以下で最終の hoge の位置を取得し何かに使う // this.pageX // this.pageY } }); </script>
以上が、マルチプラットフォーム対応のタッチ・マウスイベント共通の処理の書き方です。
もっと効率良い方法がたくさんあると思いますが、参考になればと思います。
おまけ:シンプルなコピペ用スクリプトコード
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> <script type="text/javascript"> var isTouch = ('ontouchstart' in window); $('#hoge').bind({ 'touchstart mousedown': function(e) { e.preventDefault(); this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); this.pageY = (isTouch ? event.changedTouches[0].pageY : e.pageY); }, 'touchmove mousemove': function(e) { e.preventDefault(); }, 'touchend mouseup': function(e) { } }); </script>