h5项目开发过程中会碰到这样一个需求,在列表页滚动浏览之后,点击某个链接去到详情页浏览内容后再返回到列表页,要保持列表页原来的状态,包括滚动到的位置等,因为作者自己也研究了一段时间,也基本实现了这样的功能,但这里有个矛盾的地方,就是记住了列表页的状态后就无法实时刷新最新的数据了,需要像app那样做一个类似下拉刷新的动作来刷新最新的数据,但我们的页面又是滚动加载的,并非在顶部刷新最新数据,这个却又不是需求所希望的。下面将代码贴出来大家参考。
实现原理:
其实很简单,就是进来当前列表页的时候用localStorage 或 sessionStorage记住要记住的数据,返回到这一页的时候判断此环境有没有BFcache,如果没有则要执行localStorage 或 sessionStorage记住的状态来模拟BFcache(有BFcache缓存的环境已直接实现这个功能,无需模拟);具体代码如下:
var loadingFlag=false;//防止滚动重复请求
var AjaxRequestWholeVar;//请求的全局变量;用于终止ajax请求
var NeedBFcache=false;
$(function(){
//判断BF缓存是否存在
if($(".order-list-BFcache-js").hasClass("order-list-BFcache")){
//记住数据
BFcacheMemoryPageHide();
//判断是否需要BF缓存处理
window.addEventListener('pageshow',function(event){
//背景色
if($("#pageContainer").hasClass("page-order-list-msp")){
$(".page-order-list-msp").parents("body").css("background-color","#EFEFEF");
}
//console.log(event.persisted)
//BF缓存不存在
if(!event.persisted){
NeedBFcache=true;
console.log("页面需要缓存模拟:"+NeedBFcache);
}
})
}
})
//给我的订单列表加载数据用
//这里通过传参与不传参来区分是否是初始化的状态,IsInit是初始化情况,flagScroll是滚动情况,IsClickInit是判读是否是点击加载
function AjaxLoadMyOrder(IsInit,flagScroll,IsClickInit){
var $memory=$(".type-state-memory-input-js");
var $loading=$(".loading-img");
var $loadingEnd=$(".loading-img-end-js");
var dataListType=$memory.attr("data-list-type");
var dataType=$memory.attr("data-type");
var dataState=$memory.attr("data-state");
var dataKeyword=$memory.attr("data-keyword");
//不传参 搜索状态的时候要将页码变回1
if(IsInit){
$memory.attr("data-Index",1);
$loadingEnd.hide().removeClass("no-more-data");
}
//如果是第一页的时候防止滚动加载,避免重复请求
if(flagScroll){
if($memory.attr("data-Index")-0==1){
return;
}
}
var dataIndex=$memory.attr("data-Index")-0;
var dataPageSize=$memory.attr("data-pageSize");
var Ajaxurl=$memory.attr("data-url");
//时间都是空,加了未支付和已过期的参数字段dataListType
var data={
PaymentStatusId:dataListType,
teamTypeId:dataType,
statusId:dataState,
keyword:dataKeyword,
page:dataIndex,
pageSize:dataPageSize
}
if(!$loadingEnd.hasClass("no-more-data")){
AjaxRequestWholeVar=$.ajax({
url:Ajaxurl,
type:'get',
data:data,
beforeSend:function(){
if(IsInit){
//非滚动事件先清空列表再加载
$("#product-list-order-all").empty();
if(AjaxRequestWholeVar){
AjaxRequestWholeVar.abort();//如果同时有多次请求,只保留最后一次请求,防止发生数据不对应的问题
}
$loading.show();
}
},
success:function(msg){
console.log("success",msg);
//加载完才执行BF缓存模拟
if(IsInit && !IsClickInit){
//初始化时才执行这个函数,(IsClickInit)滚动/搜索/点击切换的时候都不执行
BFcacheMemoryShow(msg);
}
},
error:function(msg){
console.log(msg);
},
complete:function(e){
$loading.hide();
}
})
}else{
$loading.hide();
$loadingEnd.show().addClass("no-more-data");
}
}
//离开订单列表页记住要记住的数据
function BFcacheMemoryPageHide(){
//只在订单列表页执行
if($(".order-list-BFcache-js").hasClass("order-list-BFcache")){
window.addEventListener('pagehide', function(event) {
//console.log(event);
var ScrollTop=$(window).scrollTop();
var NoMoreDataOBJ=$(".loading-img-end-js.no-more-data");
var NoMoreData=0;
if(NoMoreDataOBJ.length){
NoMoreData=NoMoreDataOBJ.height();
}
var MemoryOBJ=$(".type-state-memory-input-js");
var dataListType=MemoryOBJ.attr("data-list-type")-0;
var dataType=MemoryOBJ.attr("data-type")-0;
var dataState=MemoryOBJ.attr("data-state")-0;
var dataKeyword=MemoryOBJ.attr("data-keyword");
var dataIndex=MemoryOBJ.attr("data-Index")-0;
var dataPageSize=MemoryOBJ.attr("data-pageSize")-0;
var OrderUrl=window.location.href;
var html=$("#product-list-order-all").html().replace(/[\r\n]+/gm, '');
var data={
'html':html,
'OrderUrl':OrderUrl,
'ScrollTop':ScrollTop,
'NoMoreData':NoMoreData,
'PaymentStatusId':dataListType,
'teamTypeId':dataType,
'statusId':dataState,
'keyword':dataKeyword,
'page':dataIndex,
'pageSize':dataPageSize
};
//console.log(data);
localStorage.setItem(BFDataListItem,JSON.stringify(data));
});
}
}
//列表页面加载完毕之后执行的BF缓存模拟替换
function BFcacheMemoryShow(msg){
if(NeedBFcache){
var BFDataListStr=localStorage.getItem(BFDataListItem);
//console.log(JSON.parse(BFDataListStr));
var JsonBF=JSON.parse(BFDataListStr);
//console.log(JsonBF);
$.each([JsonBF],function(){
var UrlCurrentPage=window.location.href;
if(UrlCurrentPage==this.OrderUrl){
//是否订单列表页,是则进来处理模拟BF;
//console.log(this.OrderUrl);
var PaymentStatusId=this.PaymentStatusId;
var html=this.html;
//选中支付状态
$(".head-fixed-top-js .hd-ul li").each(function(){
if(PaymentStatusId==$(this).attr("data-list-type")){
//console.log(PaymentStatusId);
$("#leftTabBoxList .hd .hd-ul >li").removeClass("border-bottom2px");
$(this).addClass("border-bottom2px");
}
})
//将隐藏的参数值全部重置到之前的状态
var MemoryOBJ=$(".type-state-memory-input-js");
MemoryOBJ.attr({
"data-list-type":this.PaymentStatusId,
"data-type":this.teamTypeId,
"data-state":this.statusId,
"data-keyword":this.keyword,
"data-Index":this.dataIndex,
"data-pageSize":this.pageSize
})
//将html加回来
$("#product-list-order-all").empty().append(html);
//如果是已经加载到没有更多数据了那么还原到没有更多数据的状态
if((this.NoMoreData>0)&&($(".no-find-data-js").length<=0)){
$(".loading-img").hide();
$(".loading-img-end-js").show().addClass("no-more-data");
}
//滚动到之前的位置
if(this.ScrollTop>0){
window.scrollTo(0,this.ScrollTop);
}
return false;
}
})
}
}