7

要素のスクロール オフセットを別の要素 (実際にはウィンドウ) と同期させる必要があり、Mobile Safari (iPad) でのスクロールの慣性的な「ロール オフ」フェーズで同期を行うのに問題があります。

いくつかの div がposition:fixed; overflow:hiddenあり、それらのスクロール オフセットをウィンドウの 1 つ (つまり、ボディ全体のスクロール) と同期させる必要があります。通常、次のようにコーディングします (jQuery):

var $win = $(window),
    $div1 = $(...)

$win.scroll(function() { 
    $div1.scrollTop($win.scrollTop())
})

しかし、iPad でインターフェイスをテストしたところ、仮想ページを指でドラッグしているタッチ段階でも、指を離してページの速度が遅くなる慣性段階でも、div が更新されていないことに気付きました。停止します。

touchmoveイベントのハンドラーとイベントのハンドラーを登録することで、ドラッグフェーズで解決しましたscroll

しかし、慣性段階の問題を解決する方法が見つかりません。慣性運動が完全に停止し、最後にスクロール イベントが発生して所定の位置にスキップするまで、div は静止したままになります (ページの残りの部分とはゆっくりと同期しなくなります)。

これが実際のデモです。

「慣性スクロール」の問題を確認するには、iPad でスクロールしてみてください。残念ながら、iframe スクロールでの iPad の奇妙な動作のため、jsFiddle で動作させることができませんでした。

そのフェーズでポーリングを実行できれば、2 つの要素間の同期を維持できます。setTimeoutsetInterval、およびで試しましrequestAnimationFrameたが、どちらも慣性スクロール フェーズ中に起動しません。そのフェーズでは、すべての Javascript が停止するようです。

質問:

  • 慣性スクロール フェーズ中に発生するタッチまたはスクロール イベントはありますか?
  • その段階で Javascript コールバックを実行する方法はありますか?
  • CSS または JS 以外の他の技術を使用して、2 つの要素 (両方ではなく X または Y のいずれか) のスクロール オフセットを同期する方法はありますか?
4

3 に答える 3

4

慣性スクロールが発生している間、 iOS は実際に DOM 操作Javascript をフリーズします。これは、通常のデスクトップ環境と iPad でのスクロールの違いを説明するために作成した簡単なデモです: http://jsfiddle.net/notjoelshapiro/LUcR6/。このコードには、次の JS のみが含まれています。

var num = 0;
function updateNum(){
    num++;
    $('#awesomeDiv').text(num);
}
$(window).scroll(updateNum);

スクロールすると、数値がインクリメントされ、ページの下部に表示されます。画面下部のスクロール番号は、慣性スクロールが停止したときにのみ増加していることがわかります。Javascript がバックグラウンドで動作している場合、スクロールが終了するまで更新されませんが、数値を大きくする必要があります。

あなたの質問に具体的に答えるには:

慣性スクロール フェーズ中に発生するタッチまたはスクロール イベントはありますか?

ネガティブ、ゴーストライダー。

その段階で Javascript コールバックを実行する方法はありますか?

上記を参照。

CSS または JS 以外の他の技術を使用して、2 つの要素 (両方ではなく X または Y のいずれか) のスクロール オフセットを同期する方法はありますか?

ここで何を意味するのかよくわかりません.JSは必要なすべての計算を行うことができますが、慣性スクロールが完了したときに行う必要があります. 正直なところ、私は今仕事をしているので、これは tl;dr の症状かもしれません。

iScrollライブラリを見たことがありますか? タッチおよび非タッチ環境の中間 (または非慣性) スクロールをシミュレートし、「スクロール」および「慣性スクロール」中/後に JS コールバックを提供し、現在の場所を計算するために使用できる多くの情報を提供します。ページ。

于 2013-03-18T18:42:45.993 に答える
4

OldDrunkenSailor はiScrollを提案するために私を打ち負かしました。

残念ながら、すぐに使用できる iScroll は、ネイティブの慣性スクロールと同じ問題を再現するだけです。慣性段階でのイベント処理はありません。

これは、モンキー パッチを適用した iScroll を使用して、慣性段階でも発生するカスタム イベントを追加したバージョンのデモです: https://dl.dropbox.com/u/15943645/scrollingdemo.html

第 2 世代の iPad で問題なく動作します。

JS:

// Disable touch events
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

// Patch iScroll for position change custom event
iScroll.prototype._oldPos = iScroll.prototype._pos;
iScroll.prototype._pos = function(x, y) {
    this._oldPos(x, y);
    if (this.options.onPositionChange) this.options.onPositionChange.call(this);
}

$(function() {
    var $win = $(window),
        $div_cols = $('#cols'),
        $div_rows = $('#rows'),
        $div_body = $('#body')

    // attach scrolling sync handler and execute it once
    function sync_scroll(e) {
        $div_cols.scrollLeft(0 - $div_body.position().left);
        $div_rows.scrollTop(0 - $div_body.position().top);

    }           

    // initialize iScroll on wrapper div, with position change handler
    var myScroll = new iScroll('iscroll_wrapper', {
        bounce: false,
        onPositionChange: sync_scroll
    });
})

CSS:

#iscroll_wrapper {
    position:absolute;
    z-index: 1;
    left: 168px; 
    top:77px; 
    bottom:0px; 
    right:0;
    overflow:auto;
}

#body {
    position:absolute;
    z-index: 1;
    width: 2046px; 
    height: 3376px;

}

ボディのみがタッチ イベントに応答することに注意してください。ただし、この手法を行と列の div に拡張して、逆の関係にすることができます。

于 2013-03-18T20:35:04.510 に答える
0

スクロールが開始されたときにトリガーされます。iOS デバイスは、スクロール中に DOM 操作をフリーズし、スクロールが終了したときに適用するためにキューに入れることに注意してください。現在、スクロールが開始される前に DOM 操作を適用できるようにする方法を調査しています。

http://jquerymobile.com/demos/1.0rc1/docs/api/events.html#/demos/1.0rc1/docs/api/events.html

それは、スクロール開始セクションの下で彼らが言わなければならなかったことです

于 2013-03-18T11:05:09.607 に答える