binding window to popstate event triggered twice
Asked Answered
B

4

5

Simply binding the window (in jQuery) to popstate, the event is always triggered twice.

$( window ).bind( 'popstate', myFunction );

There's nothing in myFunction() to cause this - I've tried stripping out this function to a simple:

console.log( 'triggered' );

And the result is the same. It's always triggered twice (tested in Safari, Chrome & Firefox).

I know there are issues with the HTML5 history API, but any advice other than 'try History.js' would be gratefully received!

Boohoo answered 11/2, 2012 at 12:57 Comment(3)
Not reproducable in FF 10. Can you show your full code?Vermilion
Hi @RobW - the 'full' code is 3000+ lines! But myFunction() doesn't seem to have anything to do with the event firing twice. I still get the issue in FF 10.0.1 (OSX)Boohoo
This also may appear to happen in ASP.NET if you use a regular ASP:button as its trying to history.go/back, then executing a asp,net postback.Poe
B
6

Ok, I figured out a way to solve this:

jQuery( function( $ ){

  var currentPageNo = location.hash || 1;

  var myFunction = function(){

    var pageNo = location.hash;

    if( pageNo != currentPageNo ){

      // trigger AJAX stuff here

      currentPageNo = pageNo;

    }

  };

  $( window ).bind( 'popstate', myFunction );

});

Only triggers the function once, but the state is still triggered twice!

Boohoo answered 12/2, 2012 at 9:42 Comment(0)
S
5

This does not answer the question directly, but it might be of help to others who find this question. Because I only needed to listen for the popstate once, and remove the listener immediately.

If you want to dispose of the listener after it has been triggered (only once), you can add the following object to the third parameter of addEventListener:

window.addEventListener('popstate', myFunction, {once: true});

once

A Boolean indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.

Here is the documentation: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

Santamaria answered 29/5, 2020 at 0:12 Comment(1)
this solved my problem. By navigating "back" and "forward" I realised that I had accidentally registered the back button event listener twiceResourceful
F
2

the popstate event is triggered twice when using the history API i.e. histry.back() and history.go(-1). but just once using the browser back button.

I use a timeout as a workaround:

var timeout = null;
$(window).bind('popstate', function(event) {
    clearTimeout(timeout);
    timeout = setTimeout(function() {
        console.log( 'triggered' );
    }, 50);
});
Footboy answered 11/3, 2012 at 3:41 Comment(0)
E
0

I having below problems when handling the back button in reactjs

  1. First popstate event is not being called at the first time
  2. It is called twice after executing my back button custom logic

to Solve problem 1 I did the following code

  componentDidMount() {
    window.history.pushState(null, null, window.location.pathname);
    window.addEventListener('popstate', this.onBackButtonEvent);
  }

to solve problem 2 I did below code,

   onBackButtonEvent = (e) => {
    e.preventDefault();
    if (!this.isBackButtonClicked) {

  if (window.confirm("Do you want to save your changes")) {
       this.isBackButtonClicked = true;
       // your custom logic to page transition
        } else {
         window.history.pushState(null, null, window.location.pathname);
         this.isBackButtonClicked = false;
       }
    }
  }

don't forget to add this.isBackButtonClicked = false; in constructor and unscubscribe the events.

  componentWillUnmount = () => {
    window.removeEventListener('popstate', this.onBackButtonEvent);
  }
Eldrid answered 2/4, 2020 at 5:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.