html5的replaceState实现详情页到列表页的无刷新且回到上次位置

最近遇到一个用户体验问题,即从详情页回到列表页的时候,需要记住用户上次的位置,并且不刷新。

最开始返回使用的是 history.go(-1),发现并不好使,也许在有些浏览器下有效果。折腾半天,突然看到html5里新加的 window.history.replaceState的方法,以下是亲自实践:

假如 列表页位 list.html (其中有获取列表的方法 getList(),支持分页   和   构建列表的方法dealWithResult()  和  到详情页的方法 viewDetail()   和   一个全局变量data,用来累加存储列表数据),详情页是 detail.html ,我们不需要在detail页面做任何动作,只需要修改list页面。

1.在viewDetail方法里面处理,记住当前页码 和 当前滚动条的位置 和 当前列表显示的所有数据,如下:

var statedata = {}; statedata .curPage = curPage(当前页码);statedata. data = data;(列表所有的数据)  

statedata .sh = function () {//当前滚动条位置

            var scrollTop = 0;
                if (document.documentElement && document.documentElement.scrollTop) {
                    scrollTop = document.documentElement.scrollTop;
                }else if (document.body) {
                    scrollTop = document.body.scrollTop;
                }             
                return scrollTop;
           
    }();
      // 替换state,不推荐使用 history.pushState方法,因为pushState每次都会加入一条数据,导致在列表页返回的时候会一直返回上一个state,不能推出列表页
           
   history.replaceState(statedata , "", "list.html");

       //跳转到详情页

      window.location.href = 'detail.html?id=';

2.在list.html的onload里面处理

//判断如果有history.state.data,说明是从详情页返回的

if (!!(window.history.state && window.history.state.data)) {

$("#loading").hide(); $("#nomore").hide(); $("#loadmore").show();//隐藏loading,显示 加载更多(为了分页)

dealWithResult(window.history.state);//根据记录的数据显示列表

curPage = window.history.state.curPage; statedata  = window.history.state;//把页面和data赋值给全局变量

window.history.replaceState({}, "", "list.html");//清空state,防止列表页点返回的时候会回到上一个state

}else{

getList();//没有window.history.state.data,说明不是从详情页来的,则调用ajax从服务器获取数据

}

3.在dealWithResult方法里处理:

function dealWithResult(listdata){

//构建列表  略

//判断如果是详情页回来,获取上次的滚动条位置,等列表构建完成后,用js设置当前滚动条位置为上次的位置

if (!!(window.history.state && window.history.state.data)) {

// 延迟 0.5秒滚动,防止页面中列表还没构建完成,保险起见(其实在执行这里之前,列表页已经构建完成)

setTimeout(window.scroll(0, window.history.state.sh || 0), 500); //此处用window.scroll方法,不用window.scrollBy,因为window.scrollBy会乱跳

}

}

4.不能漏掉,在getList方法里需要给全局变量statedata赋值

if (curPage == 1) { statedata = data; } else { // data为ajax调用接口返回的数据

var s = statedata.data;

//如果当前页码不是1,则把返回的结果累加到statedata里面

for (var t in data.data) {

s.push(data.data[t]);

}

statedata.data = s;

}

你可能感兴趣的:(JavaScript)