window.onpopstate is not working; nothing happens when I navigate back to page
Asked Answered
A

3

19

I'm trying to add window.onpopstate on one of the pages on my site, but nothing is happening. I put this script on the page:

<script type="text/javascript">
  window.addEventListener('popstate', function(event) {
    if (event.state) {
      alert(event.state);
    }
  }, false);
</script>

I have also tried:

<script type="text/javascript">
  window.onpopstate = function() {
    alert("popped!");
  }
</script>

However, I don't get any alerts when I navigate back to the page.

Allineallis answered 7/4, 2015 at 20:15 Comment(1)
I found a really good and detailed explanation of the popstate event at codeguage.com/courses/js/events-popstate-event.Sorehead
N
34

You get a popstate event only if you add one or more history entry/entries and later the user clicks the back button in the browser.

Adding entries to the browser history lets you change the URL (just as the user navigates to another page) but without actually loading a new page.

You add a history entry with pushState method:

history.pushState({}, '', '/newpage');

As you add one entry and the user clicks back the URL switches back to the previous one but the page at that address is not loaded. A popstate event is triggered instead.

See https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history


Exceptions:

Older browsers don't support popstate events and manipulation of the browser's history.

Some browsers (ex. Safari) trigger a popstate event also when the page is actually loaded.

Nonappearance answered 7/4, 2015 at 20:33 Comment(5)
lets say i write window.addEventListener('popstate', (e) => console.log(e)) in the chrome devtools console, how would i see console log after i've clicked back button?Commandant
@AkinHwan popstate is only triggered when you're moving from a pushedState to a previous state (or something like that..). If you're navigating from a separate page back to the first page, it won't trigger.Vandavandal
so are you saying that if i have "localhost/page.html#1234" loaded and then I manually enter "localhost/page.html#5678" to load basically the same page, and then click the back button, onpopstate won't get called even though it's the same identical page?Spiny
this was the missing piece for me. I was trying to close a mobile nav with the browser's back button but popstate was never triggered. what I did was, whenever the nav was opened, set a local var _navIsOpened = true and push a new history state history.pushState(null, null, window.location.pathname); to keep me on the same page and on using the back button, if _navIsOpened stay on same page with same new push to history state or else go back with history.back() ✌️✌️✌️Suilmann
You might also check this simple process out: #69512744Apocopate
U
2
window.onpopstate = function(event) {
  alert(`location: ${document.location}, state: ${JSON.stringify(event.state)}`)
}

history.pushState({page: 1}, "title 1", "?page=1")
history.pushState({page: 2}, "title 2", "?page=2")
history.replaceState({page: 3}, "title 3", "?page=3")
history.back() // alerts "location: http://example.com/example.html?page=1, state: {"page":1}"
history.back() // alerts "location: http://example.com/example.html, state: null"
history.go(2)  // alerts "location: http://example.com/example.html?page=3, state: {"page":3}"
Uglify answered 28/10, 2021 at 14:21 Comment(1)
While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.Geosphere
C
0

In case anyone facing this issue in React-JS,

let's say you have a useEffect() and want to log the popState on every re-render or (Go-Forward/Go-Back)

 useEffect(() => {
    function handlePopStateEvent(e) {
        console.log(e);
        console.log("Check if the function Working")

    }

    console.log("Check if Effect Working")

    window.addEventListener("popstate", handlePopStateEvent);

    return () => window.removeEventListener("popstate", handlePopStateEvent);

}, []);

You will need to add some history manually using the history.pushState(), even if you did it by hand let's say you typed in the URL some routes/paths like

http://localhost:5173/lab

http://localhost:5173/home

http://localhost:5173/blog

http://localhost:5173/about

it will not work, the popState() event will not log anything, and if you try to invoke the function manually to see the log you will get undefined.

The solution: in the Console add some history like this:

history.pushState({}, '', '/home');

history.pushState({}, '', '/blog');

history.pushState({}, '', '/about');

history.pushState({}, '', '/lab');

Add history to the browser manullay using history.pushState() in the console

Then when you use the Back/Forward arrows in the browser or Alt + (← →) the popState() will log in to the console like this

Logging the popState event in the console on Fowrard/Back

On every Back/Forward.

For more understanding of this behavior, you can check the MDN on the History API, popState, and history.push()

Here's the Mdn description:

The popstate event of the Window interface is fired when the active history entry changes while the user navigates the session history. It changes the current history entry to that of the last page the user visited or, if history.pushState() has been used to add a history entry to the history stack, that history entry is used instead.

Link: https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event

Cordelier answered 23/11, 2023 at 4:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.