美文网首页
关于Ajax无法后退的解决方案

关于Ajax无法后退的解决方案

作者: 7天苹果 | 来源:发表于2017-07-28 10:41 被阅读316次

    问题描述

    通过AJAX异步请求后,页面的URL不会发生改变,虽然可以通过页面上的按钮通过AJAX异步请求实现回退刷新。但是对于浏览器前进和后退不能支持,每当刷新与后退之后,页面都会退到最开始的欢迎页面。

    AJAX不能在浏览器的历史会话中保留记录,当你点开一个页面,AJAX各种数据加载非常快捷,例如一个列表页面可以用异步加载来翻页,但是如果用户一不小心刷新了页面,那么页码就得重新开始计算,一旦用户改变了会话状态(浏览器的前进、后退、刷新),那么AJAX就会丢失相关的数据。

    解决问题之前

    浏览器是如何记录访问历史并实现前进与后退的?

    浏览器是通过 window对象的 history对象来对浏览器历史访问记录,从而可以实现前进和后退。history对象可以理解其保存了一个有序的列表对象,每个对象都代表了一个页面信息(包括页面的url等信息),注意当前页面也被保存在里面。这样就可以通过浏览器本身提供的前进和后退按钮来操作,也可以利用javascript调用history对象的back(),forward(),和go()方法来实现页面的切换。

    我们说的历史记录都是指一个完整的页面请求url,而ajax并不是一个完整的页面请求,因此浏览器无法记录ajax的操作信息。所以我们要做的就是在ajax操作之后改变url,使之可以保存在histroy对象中。

    解决问题

    1. 使用history.pushState将url塞到浏览器历史中。
    2. 浏览器的前进与后退,会触发window.onpopstate事件,通过绑定popstate事件,就可以根据当前URL地址中的查询内容让对应的菜单执行Ajax载入,实现Ajax的前进与后退效果。

    pushState 方法

    它的完全体是 history.pushState(stateObject, title, url),包括三个参数。

    1. state:一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null。
    2. title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。
    3. url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。
    var stateObj = { foo: 'bar' };
    history.pushState(stateObj, 'page 2', '2.html');
    

    添加上面这个新记录后,浏览器地址栏立刻显示example.com/2.html,但并不会跳转到2.html,甚至也不会检查2.html是否存在,它只是成为浏览历史中的最新记录。这时,你在地址栏输入一个新的地址(比如访问google.com),然后点击了倒退按钮,页面的 URL 将显示2.html;你再点击一次倒退按钮,URL 将显示1.html。

    总之,pushState方法不会触发页面刷新,只是导致history对象发生变化,地址栏会有反应。

    popstate事件

    每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。

    需要注意的是,仅仅调用pushState方法或replaceState方法 ,并不会触发该事件,只有用户点击浏览器倒退按钮和前进按钮,或者使用JavaScript调用back、forward、go方法时才会触发。另外,该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件也不会触发。

    使用的时候,可以为popstate事件指定回调函数。这个回调函数的参数是一个event事件对象,它的state属性指向pushState和replaceState方法为当前URL所提供的状态对象(即这两个方法的第一个参数)。

    window.onpopstate = function (event) {
      console.log('location: ' + document.location);
      console.log('state: ' + JSON.stringify(event.state));
    };
    
    // 或者
    window.addEventListener('popstate', function(event) {
      console.log('location: ' + document.location);
      console.log('state: ' + JSON.stringify(event.state));
    });
    
    

    通过给window绑定popstate事件监听,可以在点击浏览器的前进和后退时,执行某些动作。

    相关文章

      网友评论

          本文标题:关于Ajax无法后退的解决方案

          本文链接:https://www.haomeiwen.com/subject/whlxlxtx.html