Reputation: 87773
My over-engineered webapp:
history.pushState
and popState
events, to animate movement between URLs, without having to use a #
in the URL.overflow:hidden
. This is so when the user clicks back, it will not jump to the top before animating left.Now my question is, if the user clicks the forward button again, how can I preserve where they were scrolled / scroll them back down to where they were.
My first thought is to use the history.state
object as a place to save the scrolled position, and then load it up when the user clicks forward. (I would have to replaceState
on the first page which has no history.state
object.) The problem with this idea is that once the user clicks back, I no longer have access to add the scrollTop to the current state.
My next idea is to use a separate array, so I pull up the scroll location by index, but the problem with that is that if the user closes the tab and then re-opens it, or if they navigate to another site and come back to mine later, their forward-backward history is saved, but my separate array of scrollTop
s would be lost.
What is your suggestion?
Upvotes: 0
Views: 5529
Reputation: 33408
Jörn Zaefferer has written an approach for exactly this problem: https://github.com/jzaefferer/pitfalls-examples/blob/master/app/gallery/gallery.js#L29-37
(If your native language is german, take a look at his talk: http://www.youtube.com/watch?v=RGdbfKgPKI8)
Upvotes: 1
Reputation: 4477
As already mentioned, one can use the state object of the history API to track the current state of the page (e.g. scroll positions or form field entries).
At some point, of course, one has to store the page state into the history state object. When the browser has fired a popstate event, however, it is already too late because the previous history state will already be replaced by the popped one.
So one has to store the page state before the popstate event. As there is no beforepopstate event, however, the only possible way to do this is to listen constantly to changes in the page state (e.g. to scroll or input events) and constantly update the current history state object with replaceState.
In Chromium-based browsers, however, every call to replaceState shows the loading indicator briefly to the user. If you don't want this, just call replaceState once after a popstate event. In this call, store a unique id in the history state object. Use this unique id as a key to store further state in the browser's session storage. (You would have to model a cache because entries might become state.)
Upvotes: 1
Reputation:
With pushState you can add data to your history states ,like this:
var stateObj = { scrollTop: "500px" };
history.pushState(stateObj, "page 2", "page.html");
When the event of window.onpopstate is fired, it will return the stateObj (event.state), and there is your scrollTop position.
There is a nice plugin to control windows history:
jQuery Dynamic URL: https://github.com/promatik/jQuery-Dynamic-URL
Look at this example: http://promatik.no.sapo.pt/github/dynamic-url/
Upvotes: 0