0

I'm trying to update the url without refreshing the page keeping the possibility to use the back and forward browser buttons. I'm using this logic https://stackoverflow.com/a/3354511/6783371 but I have some problem.

When I load the page I immediately execute this code:

window.onpopstate = function (e) {
    if (e.state) {
        changeStep(e.state.step);
    }
};

changeStep is just a function which display the right content based on the url.

And whenever I change page I call this function:

function updateUrl(step, url){
    window.history.pushState({"step": step}, "", url);
}

Now the point is, the first page does not get reached when I press the back button. The url gets updated but not the content of the page. And that's why when the onpopstate event gets handled, the e event does not have a state attribute. This is because the first time the page gets loaded it does not push a state. But if I do that, so if I call updateUrl when the page gets loaded, I have another problem, when I start to go backwards (through the browser back button) to test the correct behaviour, the first page gets loaded twice, the first time with the attribute state inside the event, and the second and last time without it. So in other words I still have the same problem.

But I noticed also another thing, the onpopstate event has also the property target which in turn contains location.href which is the url of the targeted page. Base on that url I can understand which content I have to display in that exact page.

So my question is, since I do not need any particular data, stored inside the state property, but the only thing I need in order to update the content of the page is the targeted url, can I just ignore the property state of the onpopstate event and go straight with target.location.href? Does it have any kind of throwback? Maybe a particular case in which this does not work?

The code would look like this

window.onpopstate = function (e) {
    if (e.target && e.target.location && e.target.location.href) {
        changeStep(e.target.location.href);
    }
};

I would not even need to set a state the first time the page gets loaded.

Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
Stefano Sambruna
  • 767
  • 2
  • 10
  • 29

1 Answers1

1

You could update the first state by using history.replaceState() when the page loads. This will keep the URL te same but adds a state to the initial page.

Now you won't have the problem of going back twice, one with a state object and one without.

window.addEventListener('load', function(event) {
  let step = 0;
  history.replaceState({ step }, '');
});
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32