history.pushState - 不工作?

时间:2013-02-12 03:10:32

标签: javascript html5 history pushstate pjax

我想在不重新加载的情况下更改html。我这样做:

$('#left_menu_item').click(function(e) {
    if (!!(window.history && history.pushState)) {
        e.preventDefault();
        history.pushState(null, null, newUrl);
    }
});

它正常工作。但是,如果我想返回“返回”按钮 - 浏览器更改以前的网址,但它不会重新加载页面。为什么呢?

2 个答案:

答案 0 :(得分:35)

这种行为是预期的,并且与操纵历史堆栈的specifications一致。

这是一个相对复杂的问题需要解释。但简而言之,将其视为:用户推送历史堆栈(使用pushState等)的任何历史记录条目都不值得在您移动时加载页面,因为它被认为是伪造的(用户生成的)历史记录条目。

为什么? 这种行为是一件好事,并且与让开发人员更多地控制页面而不被迫重新加载它的意图是一致的(想象它就像ajax:你可以做以前只能通过页面重新加载的东西,比如获取数据但是现在你可以在不使用XMLHttpRequest对象重新加载页面的情况下完成它。如果你想模仿单击后退按钮时重新加载页面的行为..你只需在处理时调用location.reload() window.onpopstate事件


如何? 这可能超出了你的问题的范围,但我只想把它放在那里描述我们正在谈论的内容

让我通过使用现有示例here解释(摘录的文本将斜体):

假设http://mozilla.org/foo.html执行以下JavaScript:

var stateObj = { foo: "bar" };
history.pushState(stateObj, "page 2", "bar.html");

这会导致网址栏显示http://mozilla.org/bar.html,但不会导致浏览器加载bar.html甚至检查bar.html是否存在。

将其视为您在历史堆栈中创建一个与实际页面加载无关的条目..而不是“假”页面加载(即您只是使用javascript来操作dom并插入html) ..

现在假设用户现在导航到http://google.com,然后点击返回。此时,URL栏将显示http://mozilla.org/bar.html,页面将获得一个popstate事件,其状态对象包含stateObj的副本。页面本身看起来像foo.html,尽管页面可能会在popstate事件期间修改其内容。

这里的重点是bar.html是一个虚假的历史记录条目,位于原始http://mozilla.org/foo.html之上..所以你会在网址http://mozilla.org/bar.html上看到,但内容属于foo(在这个例子中注意到当我们推动bar.html时我们没有操纵dom的内容..如果我们在你的例子中做了...那么那个内容也会出现)。这里的关键是页面重新加载! ..因为我们正在服务一个在历史堆栈上有一个genuin条目的页面(即使在url上...我们正在显示一个关联的url在历史堆栈上有一个假的条目。)

还将此讨论与手动处理popstate事件的页面分开..这是一个不同的故事,只会使事情变得复杂。

如果我们再次点击返回,则URL将更改为http://mozilla.org/foo.html,文档将获得另一个popstate事件,这次使用null状态对象。在这里,返回不会改变文档内容与上一步中的内容,尽管文档可能会在收到popstate事件时手动更新其内容。

这里..页面将不会加载! ..这是因为我们正在从虚假的历史堆栈条目转移到真实的条目(并且真实的一个已经在上一步中加载..所以页面重新加载,就是这样)。

就是这个例子。这个概念有点难以解释,我鼓励你通过点击真实和虚假页面的组合来测试你的代码,你会看到一个模式,当页面实际加载时,什么时候没有..

答案 1 :(得分:13)

window.onpopstate = function(event) {    
    if(event && event.state) {
        location.reload(); 
    }
}

这是我使用的:))