【问题标题】:history.pushState does not trigger 'popstate' eventhistory.pushState 不会触发“popstate”事件
【发布时间】:2012-06-12 00:57:57
【问题描述】:

为什么

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

  window.history.pushState(null, '', '/foo');
});

不提醒pop

注意:在最新的 chrome 上测试

--

根据MDN

每次活动历史条目发生变化时,都会向窗口发送一个 popstate 事件。如果被激活的历史条目是通过调用 pushState 创建的或受到调用 replaceState 的影响,则 popstate 事件的 state 属性包含历史条目的 state 对象的副本。

那么为什么我的pushState 没有触发popstate 事件呢?

【问题讨论】:

    标签: html history.js


    【解决方案1】:

    您正在阅读 MDN 的“指南页面”,这并不意味着规范。

    考虑改为阅读 MDN 的 "documentation page" for WindowEventHandlers.onpopstate

    请注意,仅调用 history.pushState() 或 history.replaceState() 不会触发 popstate 事件。 popstate 事件仅由浏览器操作触发,例如单击后退按钮(或在 JavaScript 中调用 history.back())。并且仅当用户在同一文档的两个历史条目之间导航时才会触发该事件。

    另一种未记录的触发popstate 的方法是直接操作window.location 对象。

    // this also triggers popstate 
    window.location.hash = "#some-new-hash"
    

    【讨论】:

    • 这应该是公认的答案,因为 window.location.hash 的事情
    • 这种方式不会传递状态,只对无状态操作有用
    【解决方案2】:

    不知道你究竟想达到什么目标,但如果你只是想让你的 popState 事件处理程序启动,你可以简单地将它提取到如下函数中:

    function popStateHandler(event) {
         // Event handling Code here
    }
    window.onpopstate = popStateHandler;
    

    然后你可以在 pushState 之后简单地调用你的 popStateHandler。

    【讨论】:

      【解决方案3】:

      您可以在每次调用history.pushState() 时手动触发window 上的popstate 事件。

      history.pushState(state, '', url);
      
      var popStateEvent = new PopStateEvent('popstate', { state: state });
      dispatchEvent(popStateEvent);
      

      【讨论】:

      • 很好的答案,非常感谢!!
      【解决方案4】:

      文件https://developer.mozilla.org/en-US/docs/Web/Events/popstate 说:

      请注意,仅调用 history.pushState()history.replaceState() 不会触发 popstate 事件。 popstate 事件将通过执行浏览器操作来触发,例如单击后退或前进按钮(或在 JavaScript 中调用 history.back()history.forward())。

      【讨论】:

        【解决方案5】:

        我的解决方案:

        var url = "http://awesome.website.net/route/to/paradise";
        window.history.pushState({}, "", url);
        window.history.pushState({}, "", url); // yes twice
        window.history.back();
        

        它将通过“popstate”事件触发软导航,并且没有 HTTP 请求。

        【讨论】:

        • 所有的前端框架也是这样吗?
        • 这很糟糕,因为你最终会得到冗余的前向状态。不,框架不会那样做。他们只是有很好的代码在popstatepushState 之后调用相同的回调。
        【解决方案6】:

        我也遇到过这种情况...我认为只有在数据对象的顶层有与先前状态不同的内容时才会触发该事件。

        试试这个:

        var data = {rand: Math.random()};
        window.history.pushState(data, '', '/foo');
        

        【讨论】:

        • 这也不叫 popstate。至少在 Firefox 26 上没有。
        【解决方案7】:

        您引用的段落有点模棱两可。阅读同一页面上的example,很明显popstate仅在用户单击返回按钮时触发,而不是在脚本调用pushState()时触发。

        【讨论】:

        • popstate 也会在用户按下前进按钮时触发。
        • pushstate 确实会触发 popstate!因此“每次活动历史条目更改时都会向窗口发送一个 popstate 事件”!
        • @AlexGill 你有演示这种行为的测试用例吗?类似于:`window.onpopstate = function(e) { alert('popstate'); } history.pushState(null, ''); `
        • popstatewindow.location.hash = "<some new hash>"触发。 Dmitri Farkov 在下面的回答提到了这个细节,我认为这很重要。
        猜你喜欢
        • 2017-05-18
        • 1970-01-01
        • 2021-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多