Androidでoverflowした要素をスクロール可能にするjQueryプラグイン

Androidでoverflowするとスクロールできない問題を解決するためにつくりました。

使い方

#hoge {
overflow:auto;//Androidは強制的にhidden的な挙動になる
width:320px;
height:400px;
}
$("#hoge"). overflowScroll();

iOSでもoverflowを設定すると慣性スクロールが効かなくなるので有用かもしれませんが、
よほどでなければUAを判定してAndroidだけ適応するほうがいいと思います。

仕組み

touchStartで取得したポイントをと現在の指の位置の差分をscrollTopに設定しているだけです。
模式的に書くと次のようなかんじです。

タッチ開始

$target.on("touchStart", function(event) {
            event = event.originalEvent;
            var touch = event.touches[0];
            touchStartX = touch.pageX;
            touchStartY = touch.pageY;
});

タッチ中(ドラッグ中)

$target.on("touchMove", function(event) {
            event = event.originalEvent;
            var touch = event.touches[0];
            touchX = touch.pageX;
            touchY = touch.pageY;

            $target.scrollLeft(touchStartX - touchX);
            $target.scrollTop(touchStartY - touchY);
});

タッチ完了

$target.on("touchEnd", function(event) {
            event = event.originalEvent;
            var touch = event.touches[0];
            touchStartX = touch.pageX;
            touchStartY = touch.pageY;

            //何かあれば
});

実際にはtouchEndで直前の touchX/touchYとの差分をもとに話した時の指の速度を割り出し
それをもとに慣性スクロールっぽくするよう試みてます。

$target.on("touchEnd", function(event) {
            event = event.originalEvent;
            var touch = event.changedTouches[0];

            touchSpeedX = (touchX - touch.pageX);
            touchSpeedY = (touchY - touch.pageY);

            intervalID = setInterval(afterMoving, INTERVAL_TO_MOVE);
});
function afterMoving() {
            //速度があまりにも小さくなったら止まったことにする。
            if ((Math.abs(touchSpeedX)<LIMIT_TO_STOP && Math.abs(touchSpeedY)<LIMIT_TO_STOP)) {
                clearInterval(intervalID);
                return;
            }

            var oldX = $target.scrollLeft(),
                oldY = $target.scrollTop();

            //摩擦係数をかけて減速
            touchSpeedX *= FRICTION;
            touchSpeedY *= FRICTION;

            $target.scrollLeft(oldX + Math.round(touchSpeedX));
            $target.scrollTop(oldY + Math.round(touchSpeedY));
}