解决html5上拉加载数据时的一系列问题---页面卡顿、数据重复

页面很简单,先上效果图

吐槽

某日,暴雨,南京的某个角落

领导: 排面,来一下,我有一个小想法 。

我:怎么了,海哥,是不是有新功能要做,我等这一天好久了(MMP 就你想法多,听听歌撩撩妹不好吗)。

领导: 最近用户也突破120万了,项目处在稳定的维护期,所以我想新增加一个小功能 。

我: 什么功能你说吧,作为高级工程师,公司的颜值担当,没有什么是我解决不了的。

领导:我想做个一键洗车功能,给用户展示附近的洗车场,然后提供导航。用 h5实现,后期方便更新维护,你来写 h5和 iOS 。

我:(What?那我的王者荣耀怎么办)恩,您真是有远见,站在用户角度考虑。但我们产品和 UI 刚离职,没有原型和效果图,所以这个想法是不是有点不成熟 。

领导:只要有梦想,人人都是设计师 。

我:(ZZ....)

第二天来公司,我就收到了一副惨无人道的效果图,它大概是这个样子


我怎么怎么办,我也很绝望啊。

正文

前面加载数据的基本操作不做过多描述,直接进入正题。

判断上拉条件

此处后台接口除了返回一个头部信息外 + 10条列表数据,此时的参数 pagenum 为1。当上拉到页面底部时,再发一次 ajax 请求,参数 pagenum为2,以此类推。那么,怎么判断页面刚好到了底部。


假设此时是刚加载完数据的初始状态,可以看到还有一部分数据没有加载出来,处在在屏幕外。当此时手指往上滑动,进入下图这个状态。


所以当监听页面的 touchmove事件。 所有内容高度 = 屏幕高度 + 滑动高度时 。发送 ajax 请求,加载下一页数据。

windowH = $(window).height();
scrollH = $(document).scrollTop();
documentH = document.documentElement.scrollTop==0? document.body.scrollHeight : document.documentElement.scrollHeight;  
if (windowH + scrollH >= documentH - 20) {
      console.log("这里页面到达底部");
     //执行 ajax 操作
     $.ajax({
          datatype : "JSON",
          type : "POST",
          url : "jiekou.htm",
          timeout : 15000,
          async:true,
          data : { key:value,pagenum:pagenum},
          error : function (e) {},
          success : function(json) {
               //for 循环加载数据
               pagenum = parseInt(pagenum) + 1;
          }
     });
}  

这里选择的是异步请求,同步请求当用户网络差或者我们服务器速度慢时,会卡死页面,并且需要等到timeout 之后才能进行下一次刷新加载,严重影响用户体验。

问题关键

但是此时出现了一个新的问题,当滑动到底部时,上面的输出语句 console.log("这里页面到达底部") 会调用数十次。因为 touchmove 事件一直响应,只要满足我们的判断条件,就会进入方法内执行输出语句。

因为我们前面选择的异步请求,所以ajax 请求也会执行数十次,就会出现大量的重复数据。解决这个问题有两个办法:

  • 改为同步请求,一次加载未完成不会进行下一次请求。
  • 继续使用异步,新增一个参数进行判断,当前后两次的pagenum不同才进行新的请求。

第一个方法直接放弃吧,不然会被领导搞死。

if (windowH + scrollH >= documentH - 20) {
    if (pagenum != lastpangenum) {
     //当此时的pagenum跟上一次不同时,才调用
     lastpangenum = pagenum;//更新lastpangenum
     //执行 ajax 操作  
    }
} 

这样做得话问题好像已经被解决了。但是当你把 timeout 参数改的非常小,模拟网络差请求超时情况,发现 if (pagenum != lastpangenum) 条件永远不执行。因为没有走 success 方法,pagenum没有+1所以我们需要处理请求失败的情况。在 error 方法里打破 pagenum = lastpangenum 均衡。完整的代码如下:

if (windowH + scrollH >= documentH - 20) {
  if (pagenum != lastpangenum) {
         lastpangenum = pagenum;//更新lastpangenum
         //执行 ajax 操作
         $.ajax({
          datatype : "JSON",
          type : "POST",
          url : "jiekou.htm",
          timeout : 15000,
          async:true,
          data : { key:value,pagenum:pagenum},
          error : function (e) {
                lastpangenum = lastpangenum - 1;
          },
          success : function(json) {
               //for 循环加载数据
               pagenum = parseInt(pagenum) + 1;
          }
     });
 }
}  

小Tips

问题基本上就是这么多,作为一个非专业前端开发,一切还在摸索的过程中。这里放上几个常用的小方法,以备后用。

1,取当前URL 中的参数
function getUrlVars() {
    var vars = {};
    var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&#]*)/gi,
          function(m,key,value) {
          vars[key] = value;
           }
     );
    return vars;
}

//用法(假设 url 为 www.baidu.com?guid=12345&token=kd1247da)
var guid = getUrlVars()["guid"];
2,获取时间戳,时间戳与正常格式转换
var nowtimestamp = new Date().getTime();//得到时间戳
var commentime = getLocalTime(nowtimestamp);//得到普通格式时间

function getLocalTime(ns) {  
        var d = new Date(ns);  
        var dformat = [ d.getFullYear(), d.getMonth() + 1, d.getDate() ].join('-')   
                    + ' ' + [ d.getHours(), d.getMinutes(), d.getSeconds() ].join(':');  
        return dformat;  
}
3,Android平台与iOS平台判断
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if(isAndroid ===true){
}else if(isiOS===true){
}
4,iOS返回不响应
<a href="#" onclick="window.history.back();return false;>
//在后面加return false,屏蔽 a 标签的默认操作

持续更新中...........

结语

整个功能做下来持续了一个多星期,也遇到过不少问题,对于 h5的很多底层原理知之甚少,更谈不上优化。最近在看俞甲子那本程序员的自我修养--链接、装载与库 发现自己对于一些底层知识越来越感兴趣,总觉得它像武林里的内功,一通则百通。好吧,扯得有点远了。等等.....领导好像又在叫我了.......

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容