2015年10月14日水曜日

touchstart touchmove touchend そしてclick

PCのchromeのエミューレーターと、実際のモダンな端末で挙動を確認(HTC J OneやiPhone6 )


  1. touchstart
  2. touchmove
  3. touchend
  4. click

の順に発火する模様。

touchendの時にevent.preventDefaultをすれば、clickイベントが起こらない。
間違って前半2つにpreventDefaultすると、スワイプもできなくなるので注意。 ただ旧式のAndroid2.x(GalaxyS)では、clickイベントが起こってしまう。

よって以下のように、touchend発生後1秒間はclickイベントを無視する(無茶苦茶)
_callbackに好きな関数を渡せば、タップ発火で実行ができる。

var $obj = $('#sample');
var pos;
$obj.on('touchstart touchmove touchend click', function(event){
 if ('touchstart' == event.type){
  pos = touch_position(event); //X,Yを得る
  $_obj.data('data-touchposition', pos);
  $_obj.data('data-touchstarted', '');
  return;
 }

 if ('touchmove' == event.type){
  pos = touch_position(event); //X,Yを得る
  var touchpos = $_obj.data('data-touchposition');
  // ある程度以上指が動いていたら、スワイプと判定
  if ( Math.abs( pos.x - touchpos.x ) +
    Math.abs( pos.y - touchpos.y ) > 10 ){
   $_obj.removeData('data-touchstarted');
  }
  return;
 }
 if ('touchend' == event.type){
  if ('undefined' != typeof $_obj.data('data-touchstarted')){
   event.preventDefault(); // click除外のために
   $_obj.removeData('data-touchstarted');
   $_obj.removeData('data-touchposition');

   // タップ実行したフラグ(1秒後にフラグは折れる)
   $_obj.data('data-touchdone', '');
   setTimeout(function(){
    $_obj.removeData('data-touchdone');
   }, 1000);

   return _callback.call(this, event);
  }

 }
 
 // win8向けに対応しておく
 if ('click' == event.type){
  // タップは実行していないか?
  if ('undefined' == typeof $_obj.data('data-touchdone')){
   $_obj.removeData('data-touchstarted');
   $_obj.removeData('data-touchposition');
   return _callback.call(this, event);
  }
 }
});