简体   繁体   English

history.pushState - 不工作?

[英]history.pushState - not working?

I want to change html without reload. 我想在不重新加载的情况下更改html。 I do it like: 我这样做:

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

It works correctly. 它工作正常。 But if I want to go back with "Back" button - browser change url on previous, but it not reload page. 但是,如果我想返回“返回”按钮 - 浏览器更改以前的网址,但它不会重新加载页面。 Why? 为什么?

this behaviour is expected and is in accordance with the specifications of manipulating the history stack. 这种行为是预期的,并且符合操纵历史堆栈的规范

this is a relatively complex problem to explain. 这是一个相对复杂的问题需要解释。 but in short think of it as this: any history entry the user pushes on the history stack (using pushState etc) doesn't merit a page load when you move from it because it is considered a fake (user generated) history entry. 但简而言之,将其视为:用户推送历史堆栈(使用pushState等)的任何历史记录条目都不值得在您移动时加载页面,因为它被认为是伪造的(用户生成的)历史记录条目。

why? 为什么? this behaviour is a good thing and is consistent with the intent of giving the developer more control over the page without being forced to reload it (think of it like ajax: you can do things that were previously only possible by page reloading like fetching data but now you can do it without reloading the page using the XMLHttpRequest object).. if you want to mimic the behaviour of reloading the page when clicking the back button.. you can simply call location.reload() when you handle the window.onpopstate event 这种行为是一件好事,并且与让开发人员更多地控制页面而不被迫重新加载它的意图是一致的(想象它就像ajax:你可以做以前只能通过页面重新加载的东西,比如获取数据但是现在你可以在不使用XMLHttpRequest对象重新加载页面的情况下完成它。如果你想模仿单击后退按钮时重新加载页面的行为..你只需在处理window.onpopstate时调用location.reload()事件


how? 怎么样? this may be outside the scope of your question but i just wanted to put it there to describe what we're talking about 这可能超出了你的问题的范围,但我只想把它放在那里描述我们正在谈论的内容

let me explain by using an existing example here (excerpted text will be italicised ): 让我通过使用现有示例解释(摘录的文本将是斜体 ):

Suppose http://mozilla.org/foo.html executes the following JavaScript: 假设http://mozilla.org/foo.html执行以下JavaScript:

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

This will cause the URL bar to display http://mozilla.org/bar.html , but won't cause the browser to load bar.html or even check that bar.html exists. 这将导致URL栏显示http://mozilla.org/bar.html ,但不会导致浏览器加载bar.html甚至检查bar.html是否存在。

think of it as that you are creating an entry in the history stack that is not associated with an actual page load.. rather a 'fake' page load (ie you are just using javascript to manipulate the dom and insert html).. 把它想象成你在历史堆栈中创建一个与实际页面加载无关的条目..而不是'假'页面加载(即你只是使用javascript来操作dom并插入html)。

Suppose now that the user now navigates to http://google.com , then clicks back. 现在假设用户现在导航到http://google.com ,然后点击返回。 At this point, the URL bar will display http://mozilla.org/bar.html , and the page will get a popstate event whose state object contains a copy of stateObj. 此时,URL栏将显示http://mozilla.org/bar.html ,该页面将获得一个popstate事件,其状态对象包含stateObj的副本。 The page itself will look like foo.html, although the page might modify its contents during the popstate event. 页面本身看起来像foo.html,尽管页面可能会在popstate事件期间修改其内容。

the point here is that bar.html is a fake history entry that sits on top of the original http://mozilla.org/foo.html .. so you will see on the url http://mozilla.org/bar.html but the contents will belong to foo (in this example notice that we didnt manipulate the content of the dom when we pushed bar.html.. if we did like in your example.. then that content will also show up). 这里的重点是bar.html是一个虚假的历史记录条目,位于原始的http://mozilla.org/foo.html之上。所以你会在网址http://mozilla.org/bar上看到。 html但是内容将属于foo(在这个例子中,当我们推动bar.html时,我们没有操纵dom的内容..如果我们在你的例子中做了...那么那个内容也会出现)。 the key thing here is that the page reloads! 这里的关键是页面重新加载! .. because we are serving a page that has a genuin entry on the history stack (even if on the url.. we are displaying a url that is associated with a fake entry on the history stack). ..因为我们正在服务一个在历史堆栈上有一个genuin条目的页面(即使在url上...我们正在显示一个与历史堆栈上的虚假条目相关联的URL)。

also separate this discussion from the page manually handling the popstate event.. that's a different story and will just complicate things. 也将这个讨论与手动处理popstate事件的页面分开..这是一个不同的故事,只会让事情复杂化。

If we click back again, the URL will change to http://mozilla.org/foo.html , and the document will get another popstate event, this time with a null state object. 如果我们再次单击,则URL将更改为http://mozilla.org/foo.html ,文档将获得另一个popstate事件,这次使用null状态对象。 Here too, going back doesn't change the document's contents from what they were in the previous step, although the document might update its contents manually upon receiving the popstate event. 在这里,返回不会改变文档内容与上一步中的内容,尽管文档可能在收到popstate事件时手动更新其内容。

here.. the page will not load! 这里..页面不会加载! .. that's because we are making the transfer from a fake history stack entry to the real one (and the real one was already loaded in the previous step.. so the page reloaded and that's it). ..那是因为我们正在从虚假的历史堆栈条目转移到真实的条目(并且真正的一个已经在上一步中加载了......所以页面重新加载,就是这样)。

that's it for the example. 就是这个例子。 the concept is kind of hard to explain and i encourage you to test your code by clicking through a combination of real and fake pages and you will see a pattern of when the page actually loads and when it doesn't.. 这个概念有点难以解释,我鼓励你通过点击真实和虚假页面的组合来测试你的代码,你会看到一个页面实际加载的时间和不加载时的模式。

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

This is what I use :) 这是我用的:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM