$('.link').on('touchend click', function(){
//処理...
});
スクロール領域の内部全体にtouchendおよびclickイベントを設定した要素を置くと、タッチデバイスでのスクロール動作が、内部に対するtouchendイベントとして認識されてしまう。
【候補1】windowオブジェクトによるタッチイベント対応判別
有効ではない。 近年タッチイベント対応かつマウス操作もできるデバイスが登場したので、イベント自体発火しなくなるおそれがある。
【候補2】scrollイベントによるフラグ管理
有効ではない。 scrollイベントが発火する前にtouchstartイベントが発火するためか誤動作の抑止にはつながらなかった。
【候補3】そもそもtouchイベントを使わず、metaタグ(name="viewport")にuser-scalable=noを設定して遅延を解消する
有効…だけど微妙。 user-scalable=noは画面の拡大・縮小を禁止する設定。ダブルタップか否かを確認する待ち時間がなくなり、タッチデバイスでのクリックイベントが高速化する。
ただ「拡大・縮小できる」というユーザビリティを損なうことにはなる。
【候補4】touchstartとイベントとtouchendイベントで要素位置を比較する方法
有効。 両者の位置が同一の場合、スクロール動作ではないことが判別できる。
ただこの次の解決法のがよりシンプルなのでそちらを採用。
let touchStartPos = '';
let touchEndPos = '';
$('.box').on('touchstart', function(){
touchStartPos = $('.box').scrollTop();
return false;
});
$('.link').on('touchend click', function(){
touchEndPos = $modalScrollCnt.scrollTop();
if(!touchStartPos || (touchStartPos && touchStartPos === touchEndPos)){
//処理...
}
return false;
});
【候補5・採用】touchstartからtouchmoveイベントがあるかを確認して発火を判別する方法
有効。 scrollFlg(スクロールもといタッチポイントの移動を判別するためのフラグ)のほか、touchendとclickの記述をまとめて書くためのisTouchFlg(touchstartが実際に発火しているかどうかを判別するフラグ)が必要になる。
https://sterfield.co.jp/programmer/%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%B3%E3%81%A7%E3%81%AE%E3%82%BF%E3%83%83%E3%83%81%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%A8%E7%A7%BB%E5%8B%95%E3%82%92%E5%8C%BA%E5%88%A5/
let scrollFlg = false;
let isTouchFlg = false;
$('.box').on({
'touchstart': function() {
scrollFlg = true;
isTouchFlg = true;
},
'touchmove': function() {
scrollFlg = false;
}
});
$('.link').on('touchend click', function(){
if(!isTouchFlg || (isTouchFlg && scrollFlg)){
//処理
}
});