私は運動量スクロールし、すべての感覚で、iScrollで、この問題に対する最適なソリューションを得ることができたhttps://github.com/cubiq/iscroll githubのドキュメントは素晴らしいですし、私はほとんどそれに続きました。これが私の実装の詳細です。
HTML:
iScrollが使用できるいくつかのdivでコンテンツのスクロール可能な領域をラップしました:
<div id="wrapper">
<div id="scroller">
... my scrollable content
</div>
</div>
CSS:
私は「タッチ」にModernizrクラスを使用して、スタイルの変更をタッチデバイスのみにターゲティングしました(タッチ時にインスタンス化されるのはiScrollのみであるため)。
.touch #wrapper {
position: absolute;
z-index: 1;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: hidden;
}
.touch #scroller {
position: absolute;
z-index: 1;
width: 100%;
}
JS:
iScrollダウンロードからiscroll-probe.jsをインクルードしてから、以下のようにスクローラーを初期化しました。ここで、updatePositionは、新しいスクロール位置に反応する私の関数です。
# coffeescript
if Modernizr.touch
myScroller = new IScroll('#wrapper', probeType: 3)
myScroller.on 'scroll', updatePosition
myScroller.on 'scrollEnd', updatePosition
現在の位置を取得するには、スクロールオフセットではなく、myScrollerを使用する必要があります。これは、http://markdalgleish.com/presentations/embracingtouch/から取得した関数です(非常に役立つ記事ですが、現在は少し古くなっています)。
function getScroll(elem, iscroll) {
var x, y;
if (Modernizr.touch && iscroll) {
x = iscroll.x * -1;
y = iscroll.y * -1;
} else {
x = elem.scrollTop;
y = elem.scrollLeft;
}
return {x: x, y: y};
}
他の唯一の問題は、スクロールしようとしていたページの一部が失われることがあり、スクロールを拒否することでした。#wrapperの内容を変更するたびにmyScroller.refresh()への呼び出しを追加する必要があり、それで問題が解決しました。
編集:もう1つの問題は、iScrollがすべての「クリック」イベントを食べることです。iScrollに「タップ」イベントを発生させ、「クリック」イベントではなくそれらを処理するオプションをオンにしました。ありがたいことに、スクロール領域をあまりクリックする必要がなかったので、これは大した問題ではありませんでした。
window.pageYOffset
とは 異なり、動作するだけdocument.body.scrollTop||document.documentElement.scrollTop
です。