【问题标题】:HTML5 onpopstate on page load页面加载时的 HTML5 onpopstate
【发布时间】:2011-04-11 15:44:12
【问题描述】:

我正在使用新的 HTML5 onpopstate 事件。使用 Firefox 4,window.onpopstate 事件在页面加载时触发,而在 Webkit 中似乎并非如此。

正确的行为是什么?

【问题讨论】:

  • 现在 Chrome Canary 中已修复此问题,并且可能会在 Chrome 的下一个(或两个)版本中修复。
  • @Agamemnus,很奇怪,不会在我的页面加载时触发。
  • 在什么条件下?

标签: javascript html


【解决方案1】:

在导航到会话历史条目时,在某些情况下会触发 popstate 事件。

http://www.whatwg.org/specs/web-apps/current-work/#event-popstate

根据我的理解,虽然我可能是错的,但加载页面确实意味着创建和遍历历史记录,是的,它应该在页面加载时触发。

另见,

http://www.mail-archive.com/whatwg@lists.whatwg.org/msg19722.html

和,

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

【讨论】:

  • 在这一点上,Firefox 和 Webkit 之间似乎存在很大的歧义。目前,Webkit 在页面加载期间不会触发 onpopstate。
  • 对于 2011 年之后访问此页面的开发人员 HTML5 规范进行了修改,使得在初始页面加载时永远不会触发“popstate”。 FireFox、IE10 等都表现出正确的行为; Chrome(可能还有 Safari)没有。 请投票code.google.com/p/chromium/issues/detail?id=63040 以使 Chrome 重新符合标准
  • @Dave:Safari Mobile 仍然(2014 年 8 月)在初始页面加载时触发此操作。
  • @Dave:能否请您发布一个指向 w3c 规范的链接,说明 popstate 事件不应在页面加载时触发?我找不到任何关于那个...
【解决方案2】:

在页面加载时触发 onpopstate 是正确的,WebKit 很快就会有这种行为。 WebKit 534.7 (Chrome 7.0517.44) 现在的行为方式是这样。

我在上面提交了一个 Chrome 错误,但事实证明这是所需的行为;它是正确处理某些后退/前进按钮操作所必需的。有关更多讨论和链接,请参阅 this bug report at code.google.com

我仍在尝试为 onpopstate 事件处理程序提出一个好的代码模式。

【讨论】:

  • 也有这个问题(onpopstate 为 webkit 触发,在第一次加载时会出现双页加载)。我通过添加一些逻辑来解决这个问题 - 例如仅在第一个 ajax 请求后添加 onpopstate 侦听器。
【解决方案3】:

我不知道这是否是您要问的,但我对 ajax-only onpopstate 事件处理程序的解决方案是在@987654323 上设置true 变量refreshed @ 并在 history.pushState 调用时将其设置为 false;然后在onpopstate 处理程序上,如果refreshedfalse,则执行操作。

看起来很傻,确实如此,但我不能做得更好。

【讨论】:

  • 在 Firefox 中,window.onload 也会在点击浏览器的后退按钮时触发,所以最好在其他地方初始化refreshed
【解决方案4】:

刚刚解决了这个问题,修复其实很简单。 Firefox 在初始页面加载时不会触发 onpopstate。触发 popstate 后,在 page.load 操作上返回 false 或阻止默认值,然后您就成功了。

干杯。

在这里行动:www.thecoffeeshopnyc.com

// Write in a new handler for Firefox, which does not fire popstate on load.
// Modern Webkit browsers fire popstate on load. The event handler below fires the controller
$(window).load(function () {
    if ($.browser.mozilla) {
        // Your func.
    }
})

// Add the event listener. If the above is false, it will still run as intended in normal browsers.
window.onpopstate = function() {
    // Your func.
}

【讨论】:

  • 当 Chrome 决定修复此问题时,这将中断。浏览器检测是一种快速修复问题的方法,但应该使用特征检测来避免难以发现的错误。
【解决方案5】:

浏览器倾向于在页面加载时以不同方式处理 popstate 事件。 Chrome 和 Safari 总是在页面加载时发出 popstate 事件,但是 Firefox 没有。

此引用摘自 Mozilla 的文档:https://developer.mozilla.org/en-US/docs/DOM/window.onpopstate

我倾向于同意 Mozilla 系统。页面加载不是需要触发额外 popstate 事件的操作,因为该状态不是弹出,而是第一次加载。

我猜 Webkit 这样做是为了方便...在我所有的实现中,延迟加载我的处理程序直到初始 popstate 触发之后总是很不方便。

代替这个(使用伪函数):

AddEventHandler(window, 'popstate', OnPopState);

我必须这样做:

AddLoadEvent(window.setTimeout(function() 
    { 
        AddEventHandler(window, 'popstate', OnPopState); 
    },0));

【讨论】:

    【解决方案6】:

    如果有人感兴趣,我想出了一个不错的模式来使用onpopstate(此代码假定为 jQuery,为了清晰起见,特征检测检查被剥离):

    $(function() {
    
      // 1. Add initial state to current history record on page load.
      var href = location.href;
      history.replaceState({"href": href}, null, href);
    
      // 2. Now attach the popstate handler.
      window.onpopstate = function(ev) {
    
        // Raised on page load this event will still contain no state.
        var state = ev.state;
        if (state && state.href) {
    
          // 3. Add your logic, use `state` and `state.href` as you see fit.          
    
        }
      };
    
    });
    

    【讨论】:

      猜你喜欢
      • 2016-05-13
      • 2014-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多