abernier
abernier

Reputation: 28208

history.pushState does not trigger 'popstate' event

Why

window.addEventListener('popstate', () => alert('pop'));

window.history.pushState(null, '', '/foo');

does not alert pop ?

NB: Testing on latest chrome

--

According to MDN:

A popstate event is dispatched to the window every time the active history entry changes. If the history entry being activated was created by a call to pushState or affected by a call to replaceState, the popstate event's state property contains a copy of the history entry's state object.

So why my pushState does not trigger the popstate event?

Upvotes: 32

Views: 25277

Answers (6)

Pacerier
Pacerier

Reputation: 89613

You are reading MDN's "guide page" which is not meant to be normative.

Consider reading MDN's "documentation page" for WindowEventHandlers.onpopstate instead:

Note that just calling history.pushState() or history.replaceState() won't trigger a popstate event. 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.

Another undocumented way of triggering popstate is by direct manipulation of the window.location object.

// this also triggers popstate 
window.location.hash = "#some-new-hash"

Upvotes: 14

sgtpep
sgtpep

Reputation: 869

You can manually trigger popstate event on window every time you call history.pushState().

history.pushState(state, '', url);

var popStateEvent = new PopStateEvent('popstate', { state: state });
dispatchEvent(popStateEvent);

Upvotes: 69

zhuxy
zhuxy

Reputation: 140

Document https://developer.mozilla.org/en-US/docs/Web/Events/popstate says:

Note that just calling history.pushState() or history.replaceState() won't trigger a popstate event. The popstate event will been 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).

Upvotes: 0

the constant gardener
the constant gardener

Reputation: 125

My solution:

var url = "http://awesome.website.net/route/to/paradise";
window.history.pushState({}, "", url);
window.history.pushState({}, "", url); // yes twice
window.history.back();

It will trigger a soft-navigation via 'popstate' event and no HTTP request.

Upvotes: 2

JeKo
JeKo

Reputation: 59

I ran into this too... I think the event only fires if you have something at the top level of your data object that is distinct from the previous state.

Try this:

var data = {rand: Math.random()};
window.history.pushState(data, '', '/foo');

Upvotes: -1

Sean Hogan
Sean Hogan

Reputation: 2920

The paragraph you reference is a little ambiguous. Reading the example on the same page, it is clear that popstate is only triggered when the user clicks the back button, not when the script calls pushState().

Upvotes: 16

Related Questions