Question

On OS X, user can scroll past the viewport, and the browser will bounce the page.
As user, I like this effect, but it causes an unfortunate bug in our website.

When user clicks a large “Next Article” banner on the bottom of a page, next article is loaded and most DOM on the page is replaced. When this happens, I reset scroll position to the top:

window.scrollTo(0, 0);

This usually works fine. However if user manages to click “Next Article” while the browser is bouncing the page due to elastic scroll, scrollTo doesn't work properly. It seems that after replacing most of the DOM and resetting scroll position, some remaining events from the bouncing effect “arrive” and make scrolling jump a screen or two below after it has been reset to zero.

How do I force the browser to scroll to the beginning and ignore leftover bouncing events?
This happens on WebKit.

Was it helpful?

Solution

I was unable to fix the issue, so as a workaround I wrote a function that returns a promise. This promise is resolved when elastic scroll is finished.

When user clicks “Next Article”, I load the article but I wait until promise is resolved before I perform DOM operations and call scrollTo. This works well for me.

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();

    });
  });
}

I'm using Bluebird for Promises and animation-frame for rAF polyfill.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top