绑定窗口到popstate事件触发两次

时间:2012-02-11 12:57:29

标签: jquery html5 history

简单地将窗口(在jQuery中)绑定到popstate,事件总是被触发两次。

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

myFunction()中没有任何内容可以导致这种情况 - 我尝试将此函数解析为一个简单的函数:

console.log( 'triggered' );

结果是一样的。它总是被触发两次(在Safari,Chrome和Firefox中测试)。

我知道HTML5历史记录API存在问题,但我们非常感谢“尝试历史记录.js”以外的任何建议!

4 个答案:

答案 0 :(得分:6)

好的,我找到了解决这个问题的方法:

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 );

});

仅触发一次该功能,但状态仍然被触发两次!

答案 1 :(得分:1)

使用历史API,即histry.back()和history.go(-1)时,popstate事件被触发两次。但只需使用一次浏览器后退按钮。

我使用超时作为解决方法:

var timeout = null;
$(window).bind('popstate', function(event) {
    clearTimeout(timeout);
    timeout = setTimeout(function() {
        console.log( 'triggered' );
    }, 50);
});

答案 2 :(得分:1)

这不能直接回答问题,但是对发现此问题的其他人可能会有帮助。因为我只需要侦听一次popstate,然后立即删除侦听器即可。

如果要在触发侦听器后(仅一次)处置它,可以将以下对象添加到addEventListener的第三个参数中:

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

一次

一个布尔值,指示在添加侦听器后最多应调用一次。如果为true,则调用时将自动删除该侦听器。

以下是文档:https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

答案 3 :(得分:0)

在reactjs中处理后退按钮时遇到以下问题

  1. 第一次没有调用 popstate 事件
  2. 执行后退按钮自定义逻辑后调用两次

要解决问题1,我做了以下代码

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

解决问题2我在下面的代码中做了

   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;
       }
    }
  }

别忘了在构造函数中添加 this.isBackButtonClicked = false; 并取消显示事件。

  componentWillUnmount = () => {
    window.removeEventListener('popstate', this.onBackButtonEvent);
  }