0

OS X では、ユーザーがビューポートを越えてスクロールでき、ブラウザーがページをバウンスします。
ユーザーとして、私はこの効果を気に入っていますが、残念なことに私たちの Web サイトにバグが発生します。

ユーザーがページの下部にある大きな「次の記事」バナーをクリックすると、次の記事が読み込まれ、ページのほとんどの DOM が置き換えられます。これが発生すると、スクロール位置を一番上にリセットします。

window.scrollTo(0, 0);

これは通常うまくいきます。ただし、エラスティック スクロールによりブラウザがページをバウンスしているときに、ユーザーが「次の記事」をクリックすると、scrollTo正しく動作しません。DOM の大部分を置き換えてスクロール位置をリセットした後、バウンス効果からのいくつかの残りのイベントが「到着」し、ゼロにリセットされた後、スクロールが 1 つまたは 2 つ下の画面にジャンプするようです。

ブラウザーを強制的に最初までスクロールさせ、残りのバウンス イベントを無視するにはどうすればよいですか?
これは WebKit で発生します。

4

1 に答える 1

1

問題を解決できなかったので、回避策として promise を返す関数を作成しました。この約束は、エラスティック スクロールが終了すると解決されます。

ユーザーが「次の記事」をクリックすると記事が読み込まれますが、promise が解決されるまで待ってから DOM 操作を実行して を呼び出しますscrollTo。これは私にとってはうまくいきます。

function waitForElasticScroll() {

  // If user scrolls part viewport and clicks while elastic scroll
  // has not fully "returned", scroll position will get messed up in Chrome.

  // Our workaround is to wait for elastic scroll to finish before transitioning.
  // rAF calls help avoid unnecessary layout.

  return new Promise(function (resolve) {
    window.requestAnimationFrame(function () {
      var maxScrollY = document.body.scrollHeight - window.innerHeight;

      function isReady() {
        var scrollY = window.scrollY || window.pageYOffset;
        return scrollY <= maxScrollY;
      }

      function resolveIfReady() {
        if (isReady()) {
          resolve();
        } else {
          window.requestAnimationFrame(resolveIfReady);
        }
      }

      resolveIfReady();

    });
  });
}

PromisesにはBluebirdを、rAF ポリフィルにはanimation-frameを使用しています。

于 2014-05-08T16:31:03.317 に答える