Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When the back button triggers popState how can I prevent a page refresh?

I am trying to modify the content in my page without a reload. Currently my code reads:

window.onpopstate = function(event){     // Ajax Request the Page and replace content with new content }; 

This works when I push a state then trigger the popstate event, but if I press the back button in the browser it navigates to the url instead of calling my onpopstate event. How can I prevent a page refresh and update the page with my ajax call instead?

edit: I am trying to update with pushState and popstate. I was hoping to keep my urls hash free.

like image 660
GhotiPhud Avatar asked Feb 25 '11 19:02

GhotiPhud


People also ask

Does history back trigger Popstate?

The popstate event is only triggered by doing a browser action such as a clicking on the back button (or calling history. back() in JavaScript). And the event is only triggered when the user navigates between two history entries for the same document.

What triggers Popstate?

The popstate event will be triggered by doing a browser action such as a click on the back or forward button (or calling history. back() or history. forward() in JavaScript). Browsers tend to handle the popstate event differently on page load.

How do I dispatch Popstate event?

A popstate event is dispatched to the window every time the active history entry changes between two history entries for the same document. If the history entry being activated was created by a call to history. pushState() or was affected by a call to history.


1 Answers

You have to make sure there is always a history state you've pushed from the current page on the history to prevent the back button from performing a page load.

If you're trying to keep the user "contained" in your web app so the back button always provides some kind of function, you need to push at least two states onto the stack and then make sure to push another state from your popstate handler.

var foo = {foo: true}; // state object history.pushState(foo, "unused argument", "#newInitialUri"); ... var bar = {bar: true} history.pushState(bar, "unused argument", "#newStateOfWebApp"); ... window.onpopstate = function(event){     ...     var baz = {baz: true}     history.pushState(baz, "unused argument", "#baseState"); }; 

In the above example say we loaded '/'. The script starts executing and the browser window URI changes to '/#newInitialUri' but no page load occurs. Then immediately after, the browser URI changes to '/#newStateOfWebApp' and no page load occurs.

The user pushes the back button on their browser. Your popstate handler fires. During your handler, event.state equals foo and the browser uri is '/#newInitialUri'. No page load occurs. The handler finishes completing, calling history.pushState and now the browser uri is '/#baseState'. No page load occurs. If the user clicks back again, your popstate event will fire again, event.state will equal foo (again), the browser uri will be '/#newInitialUri' (no page load) and then it will be '/#baseState' again (no page load).

The important thing to remember is that the event.state in your popstate handler always contains the state object for the URI you've just come back to, not the one you just came from. This was confusing to me at first, but made sense when I thought about it. For example, the user may have just come back to your page after perhaps having gone off to Google. The state object is your opportunity to communicate the status of your app to your code.

Keep in mind that some browsers fire the popstate event on page load (which is what's supposed to happen according to the spec from my understanding). Be sure to check for your state object in your handler before executing your code to make sure you don't run code you don't intend to on a page load.

One final note: if you're using jQuery to handle events, you'll need to use event.originalEvent.state to refer to the state object.

like image 176
peabody Avatar answered Sep 23 '22 17:09

peabody