[JS] タップイベントが実装されているのかを調べる方法(2つ)
こんにちは、@yoheiMuneです。
今日は、スマホ向けサービスの開発で必要になる、タップイベントが実装されているかを調べる方法をブログに書きたいと思います。
 
これは、例えばボタンがクリックされた場合に、
そのため、スマホ用には、タップした場合の処理に以下のように実装します。
ただし上記の実装の場合、上のコードを実行する前に、なんらかのJSがwindowオブジェクトにontouchstartプロパティを追加していたら、誤判定してしまいます。
この問題に対処するには、HTMLでの記述順を注意するか、または以下のように判定を行うことで対応することができます。
最後までご覧頂きましてありがとうございました。
今日は、スマホ向けサービスの開発で必要になる、タップイベントが実装されているかを調べる方法をブログに書きたいと思います。
 
Special Thanks to http://flic.kr/p/dP1Fjh
タップイベントの実装有無を調べる理由
主にスマホ向けのサービスを作っている時に、以下のようなことをしたい場合がよくあります。
var EVENT = {};
if (/*タップイベントが使える場合*/) {
    EVENT.TOUCH_START = 'touchstart';
    EVENT.TOUCH_MOVE = 'touchmove';
    EVENT.TOUCH_END = 'touchend';
} else {
    /*タップイベントが使えない場合*/
    EVENT.TOUCH_START = 'mousedown';
    EVENT.TOUCH_MOVE = 'mousemove';
    EVENT.TOUCH_END = 'mouseup';
}
// クリックやタップにイベントを貼る
$('#btn1').on(EVENT.TOUCH_END, function (e) {
    // タップされた場合の処理
});
上記のように、DOMにイベントを貼る場合に、PCでもスマホでも使えるようにしたいのですが、
その場合に「touchXXX」と「mouseXXX」のどちらを付与すれば良いのかを知りたいということなのです。これは、例えばボタンがクリックされた場合に、
$('#btn1').on('click', function () {
    alert('クリックされたよー');
});
とすれば、PCでもスマホでもちゃんとイベントは発火するのですが、しかし、
スマホの場合にはclickイベントだとタップしてからタイムラグがあり遅いのです!つまり「使い勝手が悪く感じる」ということです。そのため、スマホ用には、タップした場合の処理に以下のように実装します。
var tapEnable =false; // 有効なタップかを保持する
$('#btn1').on('touchstart', function () {
    tapEnable = true;
}).on('touchmove', function () {
    // スクロール用のタップの場合とかは、ボタンタップは発火させない。
    tapEnable = false;
}).on('touchend', function () {
    if (tapEnable) {
        tapEnable = false;
        alert('タップされたよー');
    }
});
ということで、体感品質向上のために上のようなコードを書きたいのです。
しかし上記のようにtouchstartなどをべたっと書くと、PCでは押せないボタンになってしまいます。
そのような場合に、touchXXXとmouseXXXのどちらを使うか、を知りたいのです。タップイベントが存在するかを判定する方法 その1
まず1つめは、簡単な方法です。以下のようにタップイベントが存在するかをチェックすることができます。
var hasTapEvent = ('ontouchstart' in window);
これは、windowオブジェクトにontouchstartというプロパティが存在するかをチェックすることで、タップイベントが存在するかをチェックしています。ただし上記の実装の場合、上のコードを実行する前に、なんらかのJSがwindowオブジェクトにontouchstartプロパティを追加していたら、誤判定してしまいます。
この問題に対処するには、HTMLでの記述順を注意するか、または以下のように判定を行うことで対応することができます。
var hasTapEvent;
// iframeを新規に作って、汚されていないiframeのwindowを使って判定する。
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
hasTapEvent = ('ontouchstart' in iframe.contentWindow);
iframe.remove();
基本的にはこの方法でいいかなぁー、と思います。タップイベントが存在するかを判定する方法 その2
もう1つは、最近見かけたコードなのですが、こーゆうのもできるのかと思ったコードです。
var hasTapEvent = (function(){
     var div = document.createElement('div');
     div.setAttribute('ontouchstart', 'return');
     return (typeof div.ontouchstart === 'function');
})();
自分が試してみたところ、Chrome(ver.32)ではtapイベントをエミュレートしてもfalseになりましたが、iPhoneのSafariやAndroidのブラウザではtrueになるようです。
色々な実装があるもんだなぁー、と感じた次第でした。最後に
今日は、タップイベントが実装されているかを判定する方法でした。 スマホ向けWebサービスを作る際に、使い勝手を向上しようとすれば(きっと)必要になることなので、どなたかの役に立てばいいなぁと思います。最後までご覧頂きましてありがとうございました。
 
  
