【问题标题】:When the back button triggers popState how can I prevent a page refresh?当后退按钮触发 popState 时,如何防止页面刷新?
【发布时间】:2011-07-04 13:08:24
【问题描述】:

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

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

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

edit:我正在尝试使用 pushState 和 popstate 进行更新。我希望保持我的网址无哈希。

【问题讨论】:

  • 你的“onpopstate”函数是返回false还是在返回之前对事件对象调用“.preventDefault()”?
  • (其实只是返回false可能不行。)
  • 我尝试返回 false,但它没有做任何事情。
  • 我遇到了相反的问题:当我按下后退按钮时,它既不会导航到 URL,也不会调用 onpopstate!

标签: javascript jquery html history


【解决方案1】:

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

如果您试图将用户“包含”在您的网络应用程序中,以便后退按钮始终提供某种功能,您需要将至少两个状态推送到堆栈上,然后确保从你的 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");
};

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

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

要记住的重要一点是,您的 popstate 处理程序中的 event.state 始终包含您刚刚返回的 URI 的状态对象,而不是您刚来的那个 来自。起初这让我感到困惑,但当我想到它时,这是有道理的。例如,用户可能在离开 Google 之后才回到您的页面。状态对象是您向代码传达应用状态的机会。

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

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

【讨论】:

    【解决方案2】:

    This 可能会有所帮助

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

    参考

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

    未经测试

        $(window).unload(function(e){    
            e.preventDefault();
            $(window).trigger('popstate ');      
    
        });    
    
        $(window).bind('popstate ',function(){
    
       //your ajax call here 
        });
    

    最后是 DEMO 点击浏览器的后退按钮查看它是否正常工作

    更新

    你是对的 unload 被取消,但你可以做一些类似的事情

    $(window).unload(function(e){
        e.preventDefault();
        $(window).trigger('beforeunload');   
    
    });
    
    
    $(window).bind('beforeunload',function(){
    
    alert('call your ajax here');
        return '';
    });
    

    yet another DEMO

    【讨论】:

    • 我不确定这是否能满足我的要求。根据jquery页面:无法用.preventDefault()取消卸载事件。此事件可用,以便脚本可以在用户离开页面时执行清理。
    • 单击后退按钮后,此答案仍会离开页面。我只想用ajax更新。使用哈希是防止整个页面重新加载的唯一方法吗?
    猜你喜欢
    • 2015-04-20
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 2018-09-30
    • 2014-08-26
    • 1970-01-01
    相关资源
    最近更新 更多