解决返回ajax异步请求后的页面时页面内容不变的问题

事先声明:本人技术不行,做项目时遇到这个问题,,网上查资料解决后在此将解决办法记录下,有需要的可以看看,有问题的话请指教!

备注:至今该问题未解决,等解决后再补充

采用的技术:history(应该就叫技术吧)

参考文档:https://www.2cto.com/kf/201505/398119.html(装逼的写:如果有侵权或不想让我发链接,请联系我删除)。

想看思路的请从第一个解决办法看起,,想看问题的最终解决办法的请看第二个解决办法

事先说明:使用的是ajax异步请求数据之后将数据展示到页面上,,然后点击展示的数据到下个页面,从下个页面返回时要是之前的数据并且悬停位置在上次点击的地方,,我项目使用的是spring boot,技术是java

             本人代码中包含很多注释,主要是给像我这样技术不太好的一点便利,更好的看懂代码,,看的懂的请忽略注释

第一个解决办法(最终解决失败了,想看最终版本请看第二个解决办法)

  思路:通过将最后一次ajax请求的数据存到url上,返回页面时从url上取出来再次用ajax请求一次数据并展示到页面,然后将展示的内容滚动到上次点击的地方即可。

  上代码:

var arrayObj = new Array();
//下面这是用ajax访问后台,然后取出来数据之后在下面的success:function(response){}中进行处理,具体操作请查询ajax用法
//我在每次用ajax访问完数据之后都将访问的参数给使用history放到了url上
function ajaxMethods(startTime, endTime, openid, seq) {
    $.ajax({
        type: "post",
        url: "/**/**",
        data: {
            '参数1': 参数1的值,
            '参数2': 参数2的值
        },
        success: function (response) {
            arrayObj.push(startTime + "&" + endTime + "&" + openid + "&" + seq);  //给数组中添加数据
            back_ajax_mod_url();     //访问该方法
            setDate(startTime, endTime);     //因为页面上要显示时间,所以有这个方法,具体方法代码没附上,测试时可删除这句话
        },
        error: function (e) {
            抱歉,没有加载到数据,请重试
        }
    });
}
if (history.replaceState) {       //history.replaceState=true表示从其他页面到本页面了
    window.addEventListener("popstate", function() {    //网上说这个是监听页面后否是后退回来的,,但是一直没起作用
        back_ajax_mod_url();                                //这里面没起作用就不说了
        back_ajax_post();
        if(location.href.indexOf("#")==-1){
            window.location.reload();
        }
    });
    back_ajax_mod_url();
    back_ajax_post();                                   //判断是否是返回的在这个方法里
}
//网上好多说使用window.addEventListener("popstate", function() {})监听呢,但是我的一直监听不到,页面后退和进入是都监听失败,将popstate改为onpopstate也不行。  知道的麻烦说下,问题1.1

function back_ajax_mod_url(){               //将需要存的信息存到url上
    var url_ajax=arrayObj.pop();
    var title ="Testsaaaaa";
    if(url_ajax){
        history.replaceState({ title: title }, title,location.href.split("#")[0] + "#"+ url_ajax);
    }
}//为什么不用pushstate请参考我第二种解决办法中的该方法注释

function KeepScrollBar() {      //在点击进入下个页面时将该页面的滚动位置存上
    var scrollPos;
    if (typeof window.pageYOffset != 'undefined') {         //为啥要这么写我也不知道,复制的
        scrollPos = window.pageYOffset;
    }
    else if (typeof document.body != 'undefined') {
        scrollPos = document.getElementById('prerecordslist').scrollTop;
    }
    alert("sxrollPos=" + scrollPos);
    document.cookie = "scrollTop=" + scrollPos;             //将滚动的高度存到cookie中
}

function back_ajax_post() {
    if (location.href.indexOf("#")!= -1) {                  //判断为true意思为当前的url中包含至少一个“#”字符,,因为我跳转到下个页面的时候会向url中添加"#"字段,所以如果为true也表示这个页面现在是后退回来的
        var post_href =location.href.split("#")[1];         //获取我之前存到url里的内容。location.href.split("")意思是根据引号中的字符串将location.href中的信息分成几段然后存到数组中,[1]意思是取出数组中分割好的的第二个的信息。
        if (post_href.indexOf("&")!= -1) {
            var startTime = post_href.split("&")[0];
            var endTime = post_href.split("&")[1];
            var openid = post_href.split("&")[2];
            var seq = post_href.split("&")[3];
        }
        $("#prerecordslist").html('');                      //使用ajax给页面加数据之前将div置空
        ajaxMethods(startTime, endTime, openid, seq);           //使用ajax将页面的数据重新加载上
        if (document.cookie.match(/scrollTop=([^;]+)(;|$)/) != null) {  //这个正则匹配的是啥,复制的,会的麻烦说下,问题1.2
            var arr = document.cookie.match(/scrollTop=([^;]+)(;|$)/);  //将cookie中存的页面滚动高度取出来
            document.getElementById('prerecordslist').scrollTop = parseInt(arr[1]); //让页面信息滚动到上次点击的地方
        }
    }
}
//此段代码理论上没问题,先用ajax将数据取到然后展示,然后根据之前存到滚动位置将页面滚动到需要的位置,,但是有个问题就是document.getElementById('prerecordslist')获取不到
//div标签在js中没有进行过操作,就是更改里面的内容,但是不知道为什么回退回来的时候js都加载到这里了div标签还是获取不到,,网上查询说将这句话放到windows.onload,结果还是不行
//无奈之下采用了第二种办法。 问题1.3

 

第二种解决办法(我的终极解决办法)

  思路:使用sessionStorage将要显示的页面全部存储上,返回后将存储的页面取出来展示即可。

function ajaxMethods(startTime, endTime, openid, seq) {
    $.ajax({
        type: "post",
        url: "/**/**",
        data: {
            '参数1': 参数1的值,
            '参数2': 参数2的值
        },
        success: function (response) {
            arrayObj.push(startTime + "&" + endTime);       //因为页面需要显示时间,所以存一下,存到arryObj数组中
            back_ajax_mod_url();                             //访问该方法
        },
        error: function (e) {
            抱歉,没有加载到数据,请重试
        }
    });
}
function back_ajax_mod_url(){           //将页面需要展示的时间存到history的url中
    var url_ajax=arrayObj.pop();
    var title ="Testsaaaaa";
    if(url_ajax){
        history.replaceState({ title: title }, title,location.href.split("#")[0] + "#"+ url_ajax);      //还有个方法history.pushState
    }
}
//为什么使用replaceState而不使用pushState: 比如前一页的url为111,本页的url为222,下一页的url为333,因为replaceState是用咱们新写的url(444)替换了本页的url(222),这样到下一页时history里
//存的就是111,444,333(本页时存的就是111,444),如果使用pushState就是向history加入一条信息,比如加入的是444,那进入下一页之后history存的是111,222,444,333.这种情况下从333后退时会先退到444,
//在点击后退回到222而不是后退到111
//上面内容是我自己的理解
//不明白的可以参考https://www.2cto.com/kf/201505/398119.html

function KeepScrollBar() {              //这个是在页面点击后跳转下个页面时执行的方法,执行下个页面之前将本页面的时间存到url上
    var scrollPos;
    var startTime = $("#START_TIME").val();
    var endTime = $("#END_TIME").val();
    arrayObj.push(startTime + "&" + endTime);
    back_ajax_mod_url();
    if (typeof window.pageYOffset != 'undefined') {         //这个if else是我网上找的复制的,为啥这样写我也不清楚,明白的请指正。这是问题2.2
        scrollPos = window.pageYOffset;                         //我只知道else里的那句话是获取当前滚动条的位置,我获取的是div,滚动条也是div的滚动的
    }                                                               //其他的滚动请参考
    else if (typeof document.body != 'undefined') {
        scrollPos = document.getElementById('prerecordslist').scrollTop;
    }
    sessionStorage.setItem("allPrescriptionListAjax", $("#prerecordslist").html());     //用sessionStorage将返回到本页面时需要显示的内容全部存上
}

if (history.replaceState) {                         //history.replaceState=true表示从其他页面到本页面了,至于为什么不用监听请到第一个方法同样的地方找原因
    if (location.href.indexOf("#")!= -1) {          //判断为true意思为当前的url中包含至少一个“#”字符,,因为我跳转到下个页面的时候会向url中添加"#"字段,
        //根据自己的需求实现自己的功能                //所以如果为true也表示这个页面现在是后退回来的
        $("#prerecordslist").html(sessionStorage.getItem("allPrescriptionListAjax"));   //将要显示的内容放到要显示的地方
        var post_href = location.href.split("#")[1];            //获取我之前存到url里的内容。location.href.split("")意思是根据引号中的字符串将location.href中的信息
        var startTime,endTime;                                      //分成几段然后存到数组中,[1]意思是取出数组中分割好的的第二个的信息。
        if (post_href.indexOf("&") != -1) {
            startTime = post_href.split("&")[0];
            endTime = post_href.split("&")[1];
        }
        setDate(startTime, endTime);
    }else {                                         //表示页面是点击进来而不是后退回来的
        InitializeDate();                           //自己干自己的事情,我这里是设置我自己页面的初始时间
    }
}
//网上好多说使用window.addEventListener("popstate", function() {})监听呢,但是我的一直监听不到,,刚好因为我跳转下个页面时向url里存了信息,
//所以使用了上面的那个办法,就是判断url中是否有#来判断是否是返回的。
感觉sessionStorage是将页面的所有格式存上了,,在代码中我只是将页面存储然后返回时取出来,结果在显示的时候页面自动显示到之前点击的地方,我没做任何其他操作,
至此,问题解决,返回时内容显示正常,也滚动到之前点击的地方了
问题总结:
问题1.1:网上好多说使用window.addEventListener("popstate", function() {})监听后退返回呢,但是我的一直监听不到,页面后退和进入是都监听失败,将popstate改为onpopstate也不行。
问题1.2:document.cookie.match(/scrollTop=([^;]+)(;|$)/) != null这句话中的正则是匹配啥的,没看懂。
问题1.3:第一种解决方法最后的document.getElementById('prerecordslist')结果为{},这句话是在向div中添加内容语句之后写的,不知道为什么获取的还是{},当写个alert之后,在弹窗出现后等一会关闭弹窗时div中的内容位置会移动到上次点击位置,不知代码哪有问题
问题2.1:typeof window.pageYOffset != 'undefined'和typeof document.body != 'undefined'是判断什么的,不判断会咋样。

 

嗯嗯,就这样!

你可能感兴趣的:(web,前端,js,history,sessionStorage)