展开目录
关于自动加载的问题
htmljavascript单页应用自动加载下一页
X
陈尼玛的博客
记录开发生涯的踩坑经历,用时间来验证成长
加载中

最近在做卖东西的网站时遇到一个需求,浏览商品列表的翻页功能需要做成瀑布流加载模式,滚动条靠近底部时自动开始加载下一页。 一开始我想的办法是在滚动条位置改变的事件上增加一个回调方法,一旦接近底部就触发一次网络请求。这么做在pc上能满足需求,然而在移动端设备上调试的时候却发生了意外情况。。 移动端设备浏览器通常带手势操作,上滑隐藏导航条,下滑显示导航条。如果初始内容的高度不够,那么这个设定总是会导致滚动条事件不触发。 假设初始内容高度600px,设备高度630px,导航条高度40px,可以计算出窗口高度590px,导航条距离底部10px。在用户进行手势操作后,这些事件将被依次触发:导航条高度变化,窗口高度变化,滚动条位置改变。所以此时窗口高度变为630px,因为内容高度600px<窗口高度630px,所以在滚动条位置改变之前滚动条已经不存在了,所以滚动条事件自然不会被触发。 既然事件无法利用,那么用计时器监听滚动条位置变化是解决问题的最快办法了。最终代码如下:

<meta charset='utf-8' />
<script src='https://blog.xdelve.com/js-lib/plus/jquery.js'></script>
<style>
div{
  position: absolute;
  left:0;
  top:0;
  height:300px;
  width:200px;
  overflow-x:hidden;
  overflow-y:scroll;
  line-height: 3;
  padding:10px;
}
</style>
<div id='c'></div>
<script>

// 滚动条到底部时自动加载下一页
// 设计要求:
// 1. 一个实例中最多只可能存在一个网络io等待
// 2. 如果本次请求失败,则立即重试
// 3. 如果本次请求超时,应该忽略本次返回结果

var pageloader=function(selector,params,handler){
  var c=$(selector),page=null,lock=false;
  params.page=params.page||1;
  params.distance=params.distance||10;
  params.timeout=params.timeout||3000;
  if(!params.handler)throw alert('业务接口必填');

  var r=setInterval(function(){
    if(!lock && page!==null){
      lock=true;
      params.handler(page,function(p,data){
        if(p!==page)return;
        handler(page,data);
        params.page++;
        page=null;
        lock=false;
      },function(p){
        lock=false;
        console.log(p+'失败');
      });
      setTimeout(function(){
        lock=false;
      },params.timeout);
    }
    if(c.scrollTop()+c.outerHeight()+params.distance<c[0].scrollHeight)
      return;
    page=params.page;
  },16);

  // 销毁计时器
  return {
    destory:function(){
      clearInterval(r);
    }
  };
};

var a=pageloader('div#c',{
  // getlist模拟一个封装了网络请求业务接口,接收参数为:页码,成功时回调,失败时回调(失败回调可省)
  handler:function getlist(page,success,fail){
    // 模拟网络延时
    setTimeout(function(){
      // 以一定概率模拟成功和失败
      if(Math.random()<.8)
        success(page,'# '+page+', '+Math.random());
        // 模拟传入成功收到的数据
      else fail && fail(page); // 模拟失败
    },500*(1+Math.random()*1|0));
  }
},function(page,data){
  // 页码和此页上的数据
  c.innerHTML+='<span>page: '+page+' => '+data+'</span><br/>';
});

// 如果需要销毁这个实例,使用此代码
// a.destory();

</script>

相关文档

暂无

随便看看

  1. mac ssh透过代理连接

  2. react项目webpack打包时拆分异步加载的文件

  3. pip安装nltk临时使用国内源

  4. css3 文字渐变色

  5. npm包命令行调用

  6. nodejs本地双向代理 端口转发

  7. mongodb 批量修改字段语句

  8. npm设置仓库地址和代理

  9. webrtc服务搭建

  10. cdn资源列表

  11. webpack使用外部资源

  12. TIME_WAIT过多

  13. python下载文件,带进度条控制

  14. mysql选取内容导出到文件

  15. replace2正则扩展方法

  16. centos7 开放或者关闭端口

  17. ie8上Image.onload不触发问题

  18. 随机取某个概率区间的代码

  19. youku电脑版跳过广告代码

畅言模块加载中