Androidでtouchmoveがうまくうごかない件とflipsnapでの対応策

この件。主に2.1とかっぽい。
http://www.youtube.com/watch?v=s6c3n7IjKuY

手元の端末だとIS03で同じ現象だった。エミュレーターでも同じ挙動になったので端末依存じゃないかも。

んで検証してみたらtouchstartをpreventDefault()すればうまく動くことがわかった。
http://dl.dropbox.com/u/336104/demo/touch/touchmove.html

この例だと上二つはうまく動くけど下二つは動画みたいになる。つまりtouchstartをpreventDefaultすれば問題解決なんだけど、touchstartをpreventDefaultすると、ネイティブのスクロールが効かなくなる。

これで何が困るか。flipsnapはtouchmoveで横と縦どっちに動いたかを判定して、ネイティブのスクロールを止めるかどうかを判定してる。こうすることで、横にスワイプしたときはネイティブのスクロールをとめて要素がスライドする、縦に動かしたときはflipsnapの動きをとめてネイティブのスクロールを有効にする、という動作になってる。つまりtouchstartでpreventDefaultしちゃうとネイティブのスクロールのコントロールできなくて困る。

対応策としては3つ。

何もしない

特に何も対応しない。touchmoveがtouchendまで起きないだけなので指を離したときに動くのは動く。ただ指についてくるような動作にならないだけ。個人的にはこれでいいと思う。同じような挙動のGoogle画像検索もこうなってた。

touchstartをpreventDefaultする

flipsnap側では対応しないけど、flipsnapじゃないところでtouchstartをpreventDefaultしとけばOK。(対象端末の判定は適当にやってね)

if (ua.android21) {
  $('.flipsnap').bind('touchstart', function(e) { e.preventDefault() });
}

ただしflipsnapの部分はネイティブスクロールが効かなくなる。クライアントにネイティブのスクロールはいらないからどうしても他の端末と同じにしたいんだよねー。とか言われたときに力を発揮。

ボタン的なのをつくる

こんな感じでボタンつけてあげる。
http://pxgrid.github.com/js-flipsnap/demo.html#demo-nextprev

中途半端に動くのがイヤならタッチの動作を切るのもあり。
http://pxgrid.github.com/js-flipsnap/demo.html#demo-touchDisable