Javascript 窗口绑定状态

Javascript 窗口绑定状态,javascript,jquery,html,history,Javascript,Jquery,Html,History,鉴于以下情况: $(window).bind("popstate", function() { alert('popstate'); }); 在第一次加载时,警报会使用FireFox和Chrome启动,但不会使用Safari。为什么呢?其他人看到了这一点并且知道如何最好地解决这一问题吗?Webkit中有一个错误,它错误地实现了“popstate”事件。查看这篇解释问题的简单帖子(很酷的小节目): 我的建议是为Safari实现您自己的“popstate”事件跟踪器。大概是这样的: $(w

鉴于以下情况:

$(window).bind("popstate", function() {
    alert('popstate');
});

在第一次加载时,警报会使用FireFox和Chrome启动,但不会使用Safari。为什么呢?其他人看到了这一点并且知道如何最好地解决这一问题吗?

Webkit中有一个错误,它错误地实现了“popstate”事件。查看这篇解释问题的简单帖子(很酷的小节目):

我的建议是为Safari实现您自己的“popstate”事件跟踪器。大概是这样的:

$(window).load(function(){
  function fire_popstate(){
    $(this).trigger("popstate"); // fire it when the page first loads
  }
  var lasthash = window.location.hash;
  setInterval(function(){
    var currenthash = window.location.hash;
    if(lasthash != currenthash){
      fire_popstate();
    }
  }, 500);//check every half second if the url has changed
});
window.onpopstate = callback();

您可以在浏览器测试中包装该语句以检查safari。更好的方法是在DOM准备就绪时查看“popstate”是否已触发,然后应用内部函数替换实现。您不希望发生的一件事是触发两个popstate事件(复制事件处理程序逻辑,这是锁定UI的好方法)。

现在情况正好相反。Chrome已经修复了这个bug,现在在页面加载时触发popstate,但是Firefox4(自RC以来)已经脱离了规范,并且


更新:HTML5规范在2011年被更改为状态popstate不应在页面加载时触发。Firefox和Chrome现在都做了正确的事情,就像Firefox 4和。pjax现在是相当流行的开源库,因此下面的逻辑可能是避免此问题的最佳方法

var popped = ('state' in window.history), initialURL = location.href
$(window).bind('popstate', function(event) {
  // Ignore inital popstate that some browsers fire on page load
  var initialPop = !popped && location.href == initialURL
  popped = true
  if ( initialPop ) return
  ...
这是我的解决方法

window.setTimeout(function() {
  window.addEventListener('popstate', function() {
    // ...
  });
}, 1000);

在webkit中,popstate事件在页面加载时触发。为了避免这种情况,这种简单的变通方法对我很有效:

每次我触发
history.push(…)
时,我都会将
class
history push添加到
body
-标记中:

history.push(...);
$("body").addClass("historypushed");
当我触发popstate事件时,我检查该类:

$(window).bind('popstate', function(e) {
 if($("body").hasClass("historypushed")) { 
  /* my code */ 
 } 
});

避免此问题的一个简单方法是将pushState上的第一个参数设置为true,然后对照onpopstate进行检查。与pjax示例类似,但更简单一点。下面的示例将为每个popstate事件运行doSomething(),第一页加载除外

function setupPopState() {
  if (history.popState) {
    # immediately replace state to ensure popstate works for inital page
    history.replaceState(true, null, window.location.pathname);

    $(window).bind('popstate', function(event) {
      if (event.originalEvent.state) {
        doSomething();
      }
    });
  }
}

我将@Nobu&@Tamlyn answers转换为一个对象,我还添加了一点 通过添加“window.history.state!==null”进行修复。在某些浏览器中 存在history.state,但它为null,因此无法运行

/**

*HTML5规范在2011年被修改为“不应该” *页面加载时激发。Chrome(34)和Firefox(4)已经修复了这个bug,但是 *某些浏览器(如Safari 5.1.7)仍在启动popstate *页面加载。此对象是从Pjax库创建的,用于处理 *这个问题。 */ var popstatePageloadFix={ 弹出:('state'在window.history&&window.history.state!==null), initialUrl:location.href, 首字母pop:false, init:function(){ this.initialPop=!this.popped&&location.href==this.initialUrl; this.popped=true; 返回这个.initialPop; } }; $(窗口).on(“popstate”,函数(事件){ //忽略某些浏览器在页面加载时触发的初始状态 if(popstatePageloadFix.init())返回; ... });
建议在
popstate
事件处理程序中检查
event.state
的布尔真值:

window.addEventListener('popstate', function(event) {
    if (event.state) {
        alert('!');
    }
}, false);

您还可以将回调函数绑定到
popstate
事件,如下所示:

$(window).load(function(){
  function fire_popstate(){
    $(this).trigger("popstate"); // fire it when the page first loads
  }
  var lasthash = window.location.hash;
  setInterval(function(){
    var currenthash = window.location.hash;
    if(lasthash != currenthash){
      fire_popstate();
    }
  }, 500);//check every half second if the url has changed
});
window.onpopstate = callback();

查看了解有关该解决方案的更多信息

这有什么作用?也许你不应该把它贴出来,而应该把它解释一下。@drozzy当然!这段代码向popstate事件添加了一个新的事件侦听器(1秒后)。使用这种方法,popstate事件不会在页面加载时激发。@Baggz认为,
1 ms
更合适。HTML5规范在2011年更改为状态popstate不应在页面加载时激发。向上投票是让Chrome重新符合标准的最佳方式。谷歌两年前就知道Chrome的行为是不正确的。