4-3.clickイベントが遅延する

スマートフォンではclickイベントの反応速度は遅い

samplejpg

スマートフォンでも画面をタップするとclickイベントが発生します。 このため、clickイベントのみを使っていれば、PC用のプログラムとスマートフォン用のプログラムは同じにできます。

ただし、スマートフォンではclickイベントは少し遅延します。 このため、リアルタイム性が要求されるゲームでは、実質的にスマートフォン用のイベントを使う必要が生じます。

イベントの発生状況を確認する

以下のサンプルページでは、通常のマウスイベント(mousedown/mousemove/mouseup/click)処理関数とスマートフォンのイベント(touchstart/touchmove/touchend)処理関数の両方を登録し、イベントが発生した場合に0.5秒間画面に文字表示するようにしています。

スマートフォンで実際にアクセスしてみれば判りますが、スマートフォンでもclickイベントは発生します。 しかし、スマートフォン用のイベントと比べると発生するタイミングはワンテンポ遅れます。 また、mousedown/mouseupイベントは発生しませんし、mousemoveイベントについては発生したりしなかったりします。

サンプルページを見る

スマートフォン用のイベントを使う

上記のような状況ですので、ゲームのようなレスポンスを重視するアプリでは、スマートフォンでの操作を想定する場合には、スマートフォン用のイベントを処理する必要があります。

しかし、スマートフォン用のイベントはPC/Mac上のブラウザでは発生しません。 このため、PC/Macとスマートフォンの両方に対応させるためには、実行中のプラットフォームを認識して、それに応じてイベントを使い分ける必要があります。

var lasttouchx,lasttouchy;
var touchdev = false;
if (navigator.userAgent.indexOf('iPhone') > 0
	|| navigator.userAgent.indexOf('iPod') > 0
	|| navigator.userAgent.indexOf('iPad') > 0
	|| navigator.userAgent.indexOf('Android') > 0) {
  touchdev = true;
}
if (touchdev == false) {
  canvas2.addEventListener('click',clickfunc,false);
} else {
  canvas2.addEventListener("touchstart", touchstart, false);
  canvas2.addEventListener("touchmove", touchmove, false);
  canvas2.addEventListener("touchend", touchend, false);
}

function execlick(x,y) {
  // クリック相当イベントの処理
}

function clickfunc(event) {
  var rect = event.target.getBoundingClientRect();
 var x = event.clientX - rect.left;
 var y = event.clientY - rect.top;
  execlick(x,y);
}

function touchstart(event) {
  var rect = event.target.getBoundingClientRect();
  var x = event.touches[0].pageX - rect.left;
  var y = event.touches[0].pageY - rect.top;
  lasttouchx = x;
  lasttouchy = y;
}

function touchmove(event) {
  var rect = event.target.getBoundingClientRect();
  var x = event.touches[0].pageX - rect.left;
  var y = event.touches[0].pageY - rect.top;
  lasttouchx = x;
  lasttouchy = y;
}

function touchend(event) {
  execlick(lasttouchx,lasttouchy);
}

上記のコードでは、実行中のプラットフォームがiPhone/iPod/iPad/Androidの場合には、スマートフォン用のイベントを処理し、それ以外の場合には通常のマウスイベントを処理します。

なお、スマートフォンでのマウスクリックと同様のイベントはtouchendイベントになりますが、このイベント発生時には画面から指が離れているため、クリック位置に相当する位置を把握できません。 このため、上記コードでは、touchstart/touchmoveイベントでタッチ位置を捕捉しておき、touchendイベント発生時には最後に捕捉した位置をクリック位置として使用しています。