Javascript history.pushState - 不工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14824766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 18:03:06  来源:igfitidea点击:

history.pushState - not working?

javascripthtmlhistorypushstatepjax

提问by indapublic

I want to change html without reload. I do it like:

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

$('#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?

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

回答by abbood

this behaviour is expected and is in accordance with the specificationsof 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 XMLHttpRequestobject).. 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.onpopstateevent

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



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.htmlexecutes 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. 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. The page itself will look like foo.html, although the page might modify its contents during the popstate event.

现在假设用户现在导航到http://google.com,然后点击返回。此时,URL 栏将显示http://mozilla.org/bar.html,页面将获得一个 popstate 事件,其 state 对象包含 stateObj 的副本。页面本身看起来像 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.htmlbut 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). 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).

这里的重点是 bar.html 是一个假历史条目,它位于原始http://mozilla.org/foo.html之上。所以你会在 url http://mozilla.org/bar上看到。 html但内容将属于 ​​foo (在这个例子中注意,当我们推送 bar.html 时,我们没有操作 dom 的内容。如果我们在你的例子中喜欢......那么该内容也会显示出来)。这里的关键是页面重新加载!.. 因为我们提供的页面在历史堆栈上有一个真正的条目(即使在 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. 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.

如果我们再次单击返回,URL 将更改为http://mozilla.org/foo.html,并且文档将获得另一个 popstate 事件,这次是一个空状态对象。在这里,虽然文档可能会在收到 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..

这就是示例。这个概念有点难以解释,我鼓励您通过单击真实和虚假页面的组合来测试您的代码,您将看到页面何时实际加载和何时不加载的模式。

回答by Jimbob

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

This is what I use :)

这就是我使用的:)