Javascript 当后退按钮触发 popState 时,如何防止页面刷新?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5121666/
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-23 15:45:05  来源:igfitidea点击:

When the back button triggers popState how can I prevent a page refresh?

javascriptjqueryhtmlhistory

提问by GhotiPhud

I am trying to modify the content in my page without a reload. Currently my code reads:

我正在尝试在不重新加载的情况下修改页面中的内容。目前我的代码是:

window.onpopstate = function(event){
    // Ajax Request the Page and replace content with new content
};

This works when I push a state then trigger the popstate event, but if I press the back button in the browser it navigates to the url instead of calling my onpopstate event. How can I prevent a page refresh and update the page with my ajax call instead?

当我推送一个状态然后触发 popstate 事件时,这会起作用,但是如果我按下浏览器中的后退按钮,它会导航到 url 而不是调用我的 onpopstate 事件。如何防止页面刷新并使用我的 ajax 调用更新页面?

edit: I am trying to update with pushState and popstate. I was hoping to keep my urls hash free.

编辑:我正在尝试使用 pushState 和 popstate 进行更新。我希望保持我的 url 没有哈希值。

回答by peabody

You have to make sure there is always a history state you've pushed from the current page on the history to prevent the back button from performing a page load.

您必须确保始终存在从历史记录中的当前页面推送的历史记录状态,以防止后退按钮执行页面加载。

If you're trying to keep the user "contained" in your web app so the back button always provides some kind of function, you need to push at least two states onto the stack and then make sure to push another state from your popstate handler.

如果您试图将用户“包含”在您的网络应用程序中,以便后退按钮始终提供某种功能,您需要将至少两个状态推送到堆栈中,然后确保从您的 popstate 处理程序推送另一个状态.

var foo = {foo: true}; // state object
history.pushState(foo, "unused argument", "#newInitialUri");
...
var bar = {bar: true}
history.pushState(bar, "unused argument", "#newStateOfWebApp");
...
window.onpopstate = function(event){
    ...
    var baz = {baz: true}
    history.pushState(baz, "unused argument", "#baseState");
};

In the above example say we loaded '/'. The script starts executing and the browser window URI changes to '/#newInitialUri' but no page load occurs. Then immediately after, the browser URI changes to '/#newStateOfWebApp' and no page load occurs.

在上面的例子中,我们加载了“/”。脚本开始执行,浏览器窗口 URI 更改为“/#newInitialUri”,但不会加载页面。紧接着,浏览器 URI 更改为“/#newStateOfWebApp”,并且不会发生页面加载。

The user pushes the back button on their browser. Your popstate handler fires. During your handler, event.state equals foo and the browser uri is '/#newInitialUri'. No page load occurs. The handler finishes completing, calling history.pushState and now the browser uri is '/#baseState'. No page load occurs. If the user clicks back again, your popstate event will fire again, event.state will equal foo (again), the browser uri will be '/#newInitialUri' (no page load) and then it will be '/#baseState' again (no page load).

用户按下浏览器上的后退按钮。您的 popstate 处理程序触发。在处理程序期间,event.state 等于 foo,浏览器 uri 是“/#newInitialUri”。没有页面加载发生。处理程序完成完成,调用 history.pushState,现在浏览器 uri 是“/#baseState”。没有页面加载发生。如果用户再次点击,您的 popstate 事件将再次触发,event.state 将等于 foo(再次),浏览器 uri 将是 '/#newInitialUri'(无页面加载),然后它将再次是 '/#baseState' (无页面加载)。

The important thing to remember is that the event.state in your popstate handler always contains the state object for the URI you've just come back to, not the one you just came from. This was confusing to me at first, but made sense when I thought about it. For example, the user may have just come back to your page after perhaps having gone off to Google. The state object is your opportunity to communicate the status of your app to your code.

要记住的重要一点是,在您popstate处理程序event.state始终包含状态对象的URI你刚刚回来,你不只是附带的一个。一开始这让我感到困惑,但当我想到它时就说得通了。例如,用户可能在访问了 Google 之后才返回您的页面。状态对象是您将应用程序状态传达给代码的机会。

Keep in mind that some browsers fire the popstate event on page load (which is what's supposed to happen according to the spec from my understanding). Be sure to check for your state object in your handler before executing your code to make sure you don't run code you don't intend to on a page load.

请记住,某些浏览器会在页面加载时触发 popstate 事件(根据我的理解,根据规范应该会发生这种情况)。在执行代码之前,请务必检查处理程序中的状态对象,以确保不会在页面加载时运行您不打算运行的代码。

One final note: if you're using jQuery to handle events, you'll need to use event.originalEvent.state to refer to the state object.

最后一个注意事项:如果您使用 jQuery 来处理事件,则需要使用 event.originalEvent.state 来引用状态对象。

回答by Rafay

Thismay help

可能有帮助

The unloadevent is sent to the window element when the user navigates away from the page. This could mean one of many things. The user could have clicked on a link to leave the page, or typed in a new URL in the address bar. The forward and back buttons will trigger the event. Closing the browser window will cause the event to be triggered. Even a page reload will first create an unload event.

卸载当用户导航离开该页面事件被发送到窗口元素。这可能意味着许多事情之一。用户可以点击链接离开页面,或者在地址栏中输入新的 URL。前进和后退按钮将触发事件。关闭浏览器窗口将导致事件被触发。即使页面重新加载也会首先创建一个卸载事件。

Reference

参考

http://api.jquery.com/unload/

http://api.jquery.com/unload/

untested

未经测试

    $(window).unload(function(e){    
        e.preventDefault();
        $(window).trigger('popstate ');      

    });    

    $(window).bind('popstate ',function(){

   //your ajax call here 
    });

and finally here is a DEMOclick on browser's back button to see it working

最后这里是一个演示单击浏览器的后退按钮以查看它的工作

update

更新

you are right the unloadbe canceled but you can do some thing like

你是对的卸载被取消,但你可以做一些像

$(window).unload(function(e){
    e.preventDefault();
    $(window).trigger('beforeunload');   

});


$(window).bind('beforeunload',function(){

alert('call your ajax here');
    return '';
});

yet another DEMO

另一个演示