先日ガワネイティブのアプリを作ろうと思ってWebViewを組み込んだテストアプリを作ってみた(iOS, Android)。その際クリックに対する反応が悪いのが気になった。
スマホのブラウザではダブルタップによるズームを考慮するためにタップを離してから300msの遅れを待ってから実際にクリックされたという判定を行っているらしい。その性で応答が悪く感じられてしまう。
そこでFastClickというJavaScriptのライブラリを 使って、タップの応答がどう変わるかテストしてみる。
結論
ダブルタップが必要ないページにFastClickを組み込むのは有効。
動作デモ
1番目が onclick
イベントを使ったアイテム、2番目が ontouchend
イベントを使ったアイテム、3番目が FastClick を使ったアイテムとなっている。
onclick
イベントを使ったものはタップしてからちょっと遅れて onclick
ハンドラが呼び出され、背景色が反転する。
ontouchend
イベントを使ったものはタップを離してすぐに反応する。しかしエリア内でタッチしてそのまま動かしてから離してもタッチエンドイベントが呼び出されるため、スワイプによってスクロールさせる動作の場合にも色が反転してしまう。
FastClickを使った場合にはすぐに反応し、またスワイプした場合には反応しないようになっている。しかし長押しした場合にはonclick
イベントが呼び出されてしまっている。
FastClickの使い方
FastClickを有効にするには、スマホ対応のページであるということを指定してある必要がある。実際には、ビューポートでページ幅をデバイス幅に指定してあると有効になる。
<meta name="viewport" content="width=device-width"> |
FastClickを適用するには、適用する要素自体じゃなくて、それらを含む要素を与える必要がある。
<div id="fastclick_area"> |
window.addEventListener('load', function() { |
ページ全体に適用するためにdocument.body
を渡す分にはよいが、そうでない場合には注意。
FastClickの仕組み
基本的には自分でontouchイベントを扱ってる場合と原理的には同じで、ontouchイベントを適切に処理して必要な時にonclickイベントを呼び出している。
機種やバージョンによって様々な挙動の差があるのを吸収してくれている。
AndroidのChromeでは対策が取られている
最近のAndroidのChromeでは、htmlのビューポート指定でデバイス幅以下の場合にはダブルタップによるズームは効かなくなっていて、300ms待たないようになっているらしい。(300ms tap delay, gone away)
- ピンチによるズームはできる
- iOS, Safariだとダブルタップにスクロールが割り当てられているので、できないんじゃないか という話
FastClickはそのへんも対応していて、必要ない場合にはontouch
リスナーを設定しないようになっている。(試したところonclick
からontouchend
までは10~50msくらいの遅れが生じているようだが…)