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

时间:2021-06-26 15:57:09

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进行更新。我希望保持我的网址免费。

2 个解决方案

#1


23  

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.

如果您试图让用户“包含”在您的Web应用程序中,以便后退按钮始终提供某种功能,您需要将至少两个状态推送到堆栈,然后确保从您的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的状态对象,而不是您刚刚来的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来引用状态对象。

#2


1  

This may help

这可能有所帮助

The unload event 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 DEMO click on browser's back button to see it working

最后这里是一个DEMO点击浏览器的后退按钮,看它是否正常工作

update

更新

you are right the unload be 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

另一个DEMO

#1


23  

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.

如果您试图让用户“包含”在您的Web应用程序中,以便后退按钮始终提供某种功能,您需要将至少两个状态推送到堆栈,然后确保从您的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的状态对象,而不是您刚刚来的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来引用状态对象。

#2


1  

This may help

这可能有所帮助

The unload event 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 DEMO click on browser's back button to see it working

最后这里是一个DEMO点击浏览器的后退按钮,看它是否正常工作

update

更新

you are right the unload be 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

另一个DEMO