I found a lot of questions about this on Stack Overflow, but they were all very specific about certain parts. I did find this question whose answers provide some nice references, but they don't actually explain how it all works, and their examples hardly do anything. I want to know more about how it all works together, and I want to use vanilla JavaScript.
(Also, many of the answers on other questions are years old.)
GETTING STARTED
First of all, you can remove the
window
part. Justhistory
works fine. But before we get into how everything works together, we need to know what we can use.Important Events
window.onload
This event fires whenever your webpage is loaded. There are two cases that will fire this event:
window.onpopstate
This event fires when you navigate between history states that you have set. Your browser automatically sets history states (to null) during normal browsing, but navigating to/from these states will not trigger this event.
window.onunload
This event fires whenever your webpage is unloaded. There are two cases that will fire this event:
Important Objects
The history interface contains five functions (described below), two read-only objects (described here), and works a bit like a linked list. The two objects contained in each 'link' of the history object are:
null
by default.You can access them by calling
history.length
andhistory.state
respectively, thoughhistory.state
can only be used to get the current history state.Important Functions
history.go(distance)
This function does the same thing as pressing the back or forward button in your browser, with the added functionality of being able to specify exactly how far you want to go. For example,
history.go(3)
has the same effect as would pushing your forward button three times, without actually loading the pages between your start and end locations. A negative value will likewise move you backwards through your history.history.go(0)
,history.go()
, and evenhistory.go(NaN)
have the same effect as refreshing the page (this does not trigger thepopstate
event). If you cannot move forward/backward as far as specified, the function will do nothing.history.back()
This function has the same functionality as the back button in your browser. It is equivalent to
history.go(-1)
. If it cannot go back, the function will do nothing.history.forward()
This function has the same functionality as the forward button in your browser. It is equivalent to
history.go(1)
. If it cannot go forward, the function will do nothing.history.replaceState(state, title[, location])
This function replaces the current history state. It takes three arguments, though the last one is optional. The arguments are:
history.state
for later retrieval. This is a deep copy, so if you later modify the original object it will not change the saved state. You could also set this tonull
, but if you aren't going to use it, there's not much point in usinghistory
at all.popstate
rather thanload
orunload
. Refreshing the page after changing its URL will load the page specified by the URL rather than the page you were previously on. This functionality could be used to provide a link to your page in its current state, but I would recommend only changing the query string rather than the full URL. If this argument is not used, the URL will not change.history.pushState(state, title[, location])
This function works the same as
history.replaceState
, except it puts the new state after the current state instead of replacing the current state. All history states that could have previously been accessed withforward
are discarded, and the new state becomes the current state.ASSEMBLING THE PIECES
The history interface is very useful for allowing your users to navigate through dynamically generated content from within their browser without having to reload the entire page, but you need to be mindful of all the possible things your users could do that could affect the history state.
history
, or even JavaScript?back/forward
to return to your pageback/forward
from a refreshed pageNote there is no way to delete a saved state (other than a specific case with
pushState()
mentioned above). You can only replace it with new content.PUTTING IT ALL TOGETHER
Since this is starting to get a bit wordy, lets finish it off with some code.
Notice that I never called
history.pushState
anywhere. This is becausehistory.pushState
should not be called anywhere in these functions. It should be called by the function that actually changes the page in some way that you want your users to be able to use the back button to undo.So in conclusion, a generic setup might work like this:
if (history.state == null)
in thewindow.onload
function.history.pushState
when important things happen that should be undoable with the back button.popstate
event is triggered, use the history state you set to return the page to its previous state.unload
event to finalize the history state before the user leaves the page.