Androidでoverflowするとスクロールできない問題を解決するためにつくりました。
※(追記) iOSとかではCSSで"-webkit-overflow-scrolling: touch;"にすればよいそうです。
ソースコード
使い方
CSS
#hoge {
overflow:auto;//Androidは強制的にhidden的な挙動になる
width:320px;
height:400px;
}
JS
$("#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));
}
この記事は2013-08-19の記事の転載です。