※一部ソースが間違えていたので修正しました[20131028]


サイトをつくっていて、特定の領域だけスクロールさせたいとき、
要素をdivでかこんで

overflow:scroll;

などとします。

スマホ用サイトでも、使うことはちょくちょくあるのですが、なんとandroidでは、overflow:scrollがきかずに、強制的にoverflow:hidden;になってしまうというバグが。

それを解決するライブラリも半日探したけれど見つからず、、
しょうがないのでjavascriptを自分で書いて解決してみたら、
思いの外簡単だったので、共有しときます。

基本的にはコピペでいけると思います。

javascript部分(というかjQuery) 

$(function(){
var box = $('#touchbox')[0];
var touchStartPositionX;
var touchStartPositionY;
var touchMovePositionX;
var touchMovePositionY;
var moveFarX;
var moveFarY;
var startScrollX;
var startScrollY;
var moveScrollX;
var moveScrollY;

box.addEventListener("touchstart",touchHandler,false);
box.addEventListener("touchmove",touchHandler,false);

function touchHandler(e){
var touch = e.touches[0];
if(e.type == "touchstart"){
touchStartPositionX = touch.pageX;
touchStartPositionY = touch.pageY;
//タッチ前スクロールをとる
startScrollX = $('#touchbox').scrollLeft();
startScrollY = $('#touchbox').scrollTop();
}
if(e.type == "touchmove"){
e.preventDefault();
//現在の座標を取得
touchMovePositionX = touch.pageX;
touchMovePositionY = touch.pageY;
//差をとる
moveFarX = touchStartPositionX - touchMovePositionX;
moveFarY = touchStartPositionY - touchMovePositionY;
//スクロールを動かす
moveScrollX = startScrollX +moveFarX;
moveScrollY = startScrollY +moveFarY;
$('#touchbox').scrollLeft(moveScrollX);
$('#touchbox').scrollTop(moveScrollY);
}
}
});


HTMLは以下のような形

<div id="touchbox">
スクロールさせたいボックスの中身が入る
</div> 


利用するときは、javascriptの中の2行目の#touchboxを好きな名前に変更してください。


やっていることとしては、

①touchstartで触った瞬間の座標をとる
②touchmoveで動かすたびに動かした量分、座標を変更する

の2つです。

androidだけで動かしたい場合は、ユーザーエージェントでandroidだけに読ませてもいいかもです。

if(navigator.userAgent.indexOf('Android') > 0){
上記のjavascriptを入れる
}




touchイベントの取り方などについては、こちらのサイト様を参考にしました!
http://www.webcyou.com/?p=3121



 タッチして動かしているときにブラウザ自体が動いちゃうのを防ぐために
preventDefault();をいれているのですが、touchした動作すべてにperventDefaultを入れると、div内にはいっているaタグが無効になっちゃうという弊害があるので、

上記の例では、touchmoveのときにだけpreventDevaultをすることでaタグがあってもちゃんとリンクがとぶようにしています。


これをもとに、超簡易なjQueryライブラリをつくってみようかと思ってるんですが、時間がないのでまた別の機会に。