JavaScript
UI
jQuery

【jQuery】iOS Safariでも、ボタンをサクサク動作+ついでに長押し検知

More than 3 years have passed since last update.


ボタンをサクサク動かしたい...!

iOS Safariでタップのイベントを取得しようとして、かなりハマりました。

どこで嵌ったかというと、ボタンを連打させたいのに、

onClickやonTapイベントをlistenしていたのでは、あまりに動作が遅い。。。。

タップ後にページ遷移するならいいんですが、

連打なんかで次々処理を進めたい時には、

ちょっと耐えられないレベルです。


原因

コードに無駄があって重いのかと最初は思いましたが、

どうやらそうではなくて、ダブルタップかどうかの判別のために、

あえてタップの認識を遅延させているんですね。

https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html

でも、viewportなんかでページを拡大させないようにしているなら、

ダブルタップの認識はむしろ邪魔ですね。。。


対策

では、どうするか。

調べて見ると、

イベントの中でもtouchstart(タップ開始)やtouchend(タップ終了)は、

即、認識できる模様。

そんなわけで、ブラウザのダブルタップはいっそ無視して、

touchstartイベントとtouchendを見て、即時に処理を実行させちゃいます。

コードとしては、下記のような形になります。

$(function() {

var touched = false;
$("#button").bind({
'touchstart mousedown': function(e) { // PCにも対応させるなら、touchstartではなくmousedown
touched = true;
e.preventDefault(); // このイベントに紐つく動作をキャンセル
},
'touchend mouseup': function(e) {
if (touched) {
// なんか処理
}
touched = false;
e.preventDefault();
}
});
});

これだけで、連打でもモタつかないくらい、タップがサクサクになります。


ついでに長押し(ロングタップ)も検知する

touchstartとtouchendのイベントを利用するということは、

touchstartから何秒たったか、確認することができる、ということです。

つまり、長押しも検知できる、ということになります。

そんなわけで、上のコードにさらに手を加えて、長押しにも対応させてみました。

$(function() {

var touched = false;
var touch_time = 0;
$("#button").bind({
'touchstart mousedown': function(e) {
touched = true;
touch_time = 0;
document.interval = setInterval(function(){
touch_time += 100;
if (touch_time == 1000) {
// ロングタップ(タップから約1秒)時の処理
}
}, 100)
e.preventDefault();
},
'touchend mouseup mouseout': function(e) { // マウスが領域外に出たかどうかも拾うと、より自然
if (touched) {
if (touch_time < 1000 ) {
// 短いタップでの処理
}
}
touched = false;
clearInterval(document.interval);
e.preventDefault();
}
});
});

ここから少しいじるだけでも、ほとんどのタップのパターンに対応できるはずです。