Page MenuHomePhabricator

Scroll state should be reset when visiting a new page and restored when revisiting a prior page
Closed, ResolvedPublic

Description

For client-side renders, the scroll offset should be updated whenever changing pages. On a new page, the offset should be (0, 0). On a previously visited page (by pressing back or forward), the previous state should be restored. Chrome already has some level of support for the latter (sometimes the offset isn't quite right due to loading and layout) so we may not want to change the existing behavior.

A possible implementation is to use a location listener:

history.listen((location, action) => {
  if (action === "PUSH" || action === "REPLACE") {
    // A new destination, reset the window scroll state.
    window.scrollTo(0, 0);
  }

  route(location.pathname);

  const state: HistoryState | undefined = location.state;
  if (state && action === "POP") {
    // A previously visited page, restore the window scroll state.
    window.scrollTo(state.scrollX, state.scrollY);
  }
});

And preserve scroll state in link's on-click:

const state: HistoryState = {
  scrollX: window.scrollX,
  scrollY: window.scrollY
};
context.history.push(path, state);

However, this doesn't work well for restoration since the page often isn't fully rendered at the end of route(). Other options include:

  • Encapsulate the functionality in a Preact component as described in the react-router referenced.
  • Encapsulate the functionality in the router or a client-side portion of the router as Weekipedia does.

References: