Javascript – Prevent browser scroll on HTML5 History popstate

browser-historydom-eventshtmljavascript

Is it possible to prevent the default behaviour of scrolling the document when a popstate event occurs?

Our site uses jQuery animated scrolling and History.js, and state changes should scroll the user around to different areas of the page whether via pushstate or popstate. The trouble is the browser restores the scroll position of the previous state automatically when a popstate event occurs.

I've tried using a container element set to 100% width and height of the document and scrolling the content inside that container. The problem with that I've found is it doesn't seem to be nearly as smooth as scrolling the document; especially if using lots of css3 like box-shadows and gradients.

I've also tried storing the document's scroll position during a user initiated scroll and restoring it after the browser scrolls the page (on popstate). This works fine in Firefox 12 but in Chrome 19 there is a flicker due to the page being scrolled and restored. I assume this is to do with a delay between the scroll and the scroll event being fired (where the scroll position is restored).

Firefox scrolls the page (and fires the scroll event) before popstate fires and Chrome fires popstate first then scrolls the document.

All the sites I've seen that use the history API either use a solution similar to those above or just ignore the scroll position change when a user goes back/forward (e.g. GitHub).

Is it possible to prevent the document being scrolled at all on popstate events?

Best Answer

if ('scrollRestoration' in history) {
  history.scrollRestoration = 'manual';
}

(Announced by Google on September 2, 2015)

Browser support:

Chrome: supported (since 46)

Firefox: supported (since 46)

IE: not supported

Edge: supported (since 79)

Opera: supported (since 33)

Safari: supported

For more info, see Browser compatibility on MDN.