js实现加载更多功能实例


Posted in Javascript onOctober 27, 2016

项目的一个前端页面展示已购买商品时,要求能下拉加载更多。关于如何实现『加载更多』功能,网上有插件可用,例如比较著名的使用iscroll.js实现的上拉加载更多、下拉刷新功能。

但实际用起来却是很麻烦。由于是第三方插件,要按照对方定义的方法使用,用起来总感觉很不顺心。再加上iscroll.js本身并没有集成加载更多的功能,需要进行自行扩展。想继续使用iscroll.js实现加载更多功能的,上面给的链接可以看看。

h5项目里需要实现简单的分页功能,由于是移动端,考虑用『加载更多』会更好,而不是PC端的翻页。

基于按钮实现加载更多

最简单的就是给一个加载更多的按钮,如果还有数据,点击下加载更多,继续拉几条数据;直到没有更多数据了,隐藏加载更多按钮。

效果如下:

js实现加载更多功能实例

页面html:

<div class="content">
  <div class="weui_panel weui_panel_access">
    <div class="weui_panel_hd">文章列表</div>
    <div class="weui_panel_bd js-blog-list">
      
    </div>
  </div>
  
  <!--加载更多按钮-->
  <div class="js-load-more">加载更多</div>
  
</div>
<script src="js/zepto.min.js"></script>

加载更多按钮样式:loadmore.css:

@charset "utf-8";

.js-load-more{
  padding:0 15px;
  width:120px;
  height:30px;
  background-color:#D31733;
  color:#fff;
  line-height:30px;
  text-align:center;
  border-radius:5px;
  margin:20px auto;
  border:0 none;
  font-size:16px;
  display:none;/*默认不显示,ajax调用成功后才决定显示与否*/
}

加载更多的js代码:

$(function(){

  /*初始化*/
  var counter = 0; /*计数器*/
  var pageStart = 0; /*offset*/
  var pageSize = 4; /*size*/
  
  /*首次加载*/
  getData(pageStart, pageSize);
  
  /*监听加载更多*/
  $(document).on('click', '.js-load-more', function(){
    counter ++;
    pageStart = counter * pageSize;
    
    getData(pageStart, pageSize);
  });
});

这里的代码并不多。其中getData(pageStart, pageSize)是业务逻辑代码,负责从服务端拉去数据。这里给个示例:

function getData(offset,size){
  $.ajax({
    type: 'GET',
    url: 'json/blog.json',
    dataType: 'json',
    success: function(reponse){
  
      var data = reponse.list;
      var sum = reponse.list.length;
  
      var result = '';
      
      /****业务逻辑块:实现拼接html内容并append到页面*********/
      
      //console.log(offset , size, sum);
      
      /*如果剩下的记录数不够分页,就让分页数取剩下的记录数
      * 例如分页数是5,只剩2条,则只取2条
      *
      * 实际MySQL查询时不写这个不会有问题
      */
      if(sum - offset < size ){
        size = sum - offset;
      }
      
      /*使用for循环模拟SQL里的limit(offset,size)*/
      for(var i=offset; i< (offset+size); i++){
        result +='<div class="weui_media_box weui_media_text">'+
            '<a href="'+ data[i].url +'" target="_blank"><h4 class="weui_media_title">'+ data[i].title +'</h4></a>'+
            '<p class="weui_media_desc">'+ data[i].desc +'</p>'+
          '</div>';
      }
  
      $('.js-blog-list').append(result);
      
      /*******************************************/
  
      /*隐藏more按钮*/
      if ( (offset + size) >= sum){
        $(".js-load-more").hide();
      }else{
        $(".js-load-more").show();
      }
    },
    error: function(xhr, type){
      alert('Ajax error!');
    }
  });
}

还是比较简单的。

基于滚动事件实现加载更多
上面我们通过按钮点击实现加载更多,整体过程还是比较简单的。这里,我提供另一种方法实现加载更多:基于于滚动(scroll)事件。

直接贴代码了:

$(function(){

  /*初始化*/
  var counter = 0; /*计数器*/
  var pageStart = 0; /*offset*/
  var pageSize = 7; /*size*/
  var isEnd = false;/*结束标志*/
  
  /*首次加载*/
  getData(pageStart, pageSize);
  
  /*监听加载更多*/ 
  $(window).scroll(function(){
    if(isEnd == true){
      return;
    }

    // 当滚动到最底部以上100像素时, 加载新内容
    // 核心代码
    if ($(document).height() - $(this).scrollTop() - $(this).height()<100){
      counter ++;
      pageStart = counter * pageSize;
      
      getData(pageStart, pageSize);
    }
  });
});

可以看出,代码变化不大,主要看核心代码里的判断条件:当滚动到最底部以上100像素时, 加载新内容。

业务逻辑getData(pageStart, pageSize)只需要把if ( (offset + size) >= sum)里面的逻辑改成:

if ( (offset + size) >= sum){
  isEnd = true;//没有更多了
}

就行了。

当然,这里面还有要优化的地方,例如:如何防止滚动过快,服务端没来得及响应造成多次请求?

综合实例

通过上面的例子,显然第二种更好,不用去点击。但是第二个方法有个问题:

如果设置页面大小每次显示2条或3条(size=2),总记录是20,你会发现无法触发向下滚动加载更多的逻辑。这时候有个加载更多的点击按钮就好了。

因此,我们可以把以上两种方法合在一起:

默认使用滚动事件实现加载更多,当显示数目太小不足以触发向下滚动加载更多的逻辑时,使用加载更多点击事件。
这里,我对加载更多这个行为进行简单的抽象,写了个简单的插件:

loadmore.js

/*
 * loadmore.js
 * 加载更多
 *
 * @time 2016-4-18 17:40:25
 * @author 飞鸿影~
 * @email jiancaigege@163.com
 * 可以传的参数默认有:size,scroll 可以自定义
 * */

;(function(w,$){
  
  var loadmore = { 
    /*单页加载更多 通用方法
     * 
     * @param callback 回调方法
     * @param config 自定义参数
     * */
    get : function(callback, config){
      var config = config ? config : {}; /*防止未传参数报错*/

      var counter = 0; /*计数器*/
      var pageStart = 0;
      var pageSize = config.size ? config.size : 10;

      /*默认通过点击加载更多*/
      $(document).on('click', '.js-load-more', function(){
        counter ++;
        pageStart = counter * pageSize;
        
        callback && callback(config, pageStart, pageSize);
      });
      
      /*通过自动监听滚动事件加载更多,可选支持*/
      config.isEnd = false; /*结束标志*/
      config.isAjax = false; /*防止滚动过快,服务端没来得及响应造成多次请求*/
      $(window).scroll(function(){
        
        /*是否开启滚动加载*/
        if(!config.scroll){
          return;
        }
        
        /*滚动加载时如果已经没有更多的数据了、正在发生请求时,不能继续进行*/
        if(config.isEnd == true || config.isAjax == true){
          return;
        }
        
        /*当滚动到最底部以上100像素时, 加载新内容*/
        if ($(document).height() - $(this).scrollTop() - $(this).height()<100){
          counter ++;
          pageStart = counter * pageSize;
          
          callback && callback(config, pageStart, pageSize);
        }
      });

      /*第一次自动加载*/
      callback && callback(config, pageStart, pageSize);
    },
      
  }

  $.loadmore = loadmore;
})(window, window.jQuery || window.Zepto);

如何使用呢?很简单:

$.loadmore.get(getData, {
  scroll: true, //默认是false,是否支持滚动加载
  size:7, //默认是10
  flag: 1, //自定义参数,可选,示例里没有用到
});

第一个参数是回调函数,即我们的业务逻辑。我把最终修改过的业务逻辑方法贴出来:

function getData(config, offset,size){

  config.isAjax = true;

  $.ajax({
    type: 'GET',
    url: 'json/blog.json',
    dataType: 'json',
    success: function(reponse){
    
      config.isAjax = false;

      var data = reponse.list;
      var sum = reponse.list.length;
      
      var result = '';
      
      /************业务逻辑块:实现拼接html内容并append到页面*****************/
      
      //console.log(offset , size, sum);
      
      /*如果剩下的记录数不够分页,就让分页数取剩下的记录数
      * 例如分页数是5,只剩2条,则只取2条
      *
      * 实际MySQL查询时不写这个
      */
      if(sum - offset < size ){
        size = sum - offset;
      }

      
      /*使用for循环模拟SQL里的limit(offset,size)*/
      for(var i=offset; i< (offset+size); i++){
        result +='<div class="weui_media_box weui_media_text">'+
            '<a href="'+ data[i].url +'" target="_blank"><h4 class="weui_media_title">'+ data[i].title +'</h4></a>'+
            '<p class="weui_media_desc">'+ data[i].desc +'</p>'+
          '</div>';
      }

      $('.js-blog-list').append(result);
      
      /*******************************************/
      
      /*隐藏more*/
      if ( (offset + size) >= sum){
        $(".js-load-more").hide();
        config.isEnd = true; /*停止滚动加载请求*/
        //提示没有了
      }else{
        $(".js-load-more").show();
      }
    },
    error: function(xhr, type){
      alert('Ajax error!');
    }
  });
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS提交并解析后台返回的XML的代码
Nov 03 Javascript
javascript调试说明
Jun 07 Javascript
jquery实现图片按比例缩放示例
Jul 01 Javascript
JavaScript实现的GBK、UTF8字符串实际长度计算函数
Aug 27 Javascript
jquery使整个div区域可以点击的方法
Jun 24 Javascript
jQuery添加options点击事件并传值实例代码
May 18 Javascript
Javascript的比较汇总
Jul 25 Javascript
纯js实现的积木(div层)拖动功能示例
Jul 19 Javascript
在Web关闭页面时发送Ajax请求的实现方法
Mar 07 Javascript
JavaScript剩余操作符Rest Operator详解
Jul 20 Javascript
Node.js系列之安装配置与基本使用(1)
Aug 30 Javascript
VUEX采坑之路之获取不到$store的解决方法
Nov 08 Javascript
Vue.js一个文件对应一个组件实践
Oct 27 #Javascript
JavaScript实现类似拉勾网的鼠标移入移出效果
Oct 27 #Javascript
node.js文件上传处理示例
Oct 27 #Javascript
Vue.js表单控件实践
Oct 27 #Javascript
vue实现可增删查改的成绩单
Oct 27 #Javascript
vuex实现简易计数器
Oct 27 #Javascript
微信小程序  生命周期详解
Oct 27 #Javascript
You might like
发挥语言的威力--融合PHP与ASP
2006/10/09 PHP
PHP 常见郁闷问题答解
2006/11/25 PHP
深入解读php中关于抽象(abstract)类和抽象方法的问题分析
2014/01/03 PHP
Yii框架弹出窗口组件CJuiDialog用法分析
2017/01/07 PHP
php微信开发之关注事件
2018/06/14 PHP
PHP SESSION跨页面传递失败解决方案
2020/12/11 PHP
AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
2010/03/04 Javascript
Js实现动态添加删除Table行示例
2014/04/14 Javascript
Node.js 去掉种子(torrent)文件里的邪恶信息
2015/03/27 Javascript
JS实现队列与堆栈的方法
2016/04/21 Javascript
Bootstrap table使用方法详细介绍
2016/12/09 Javascript
JS常用加密编码与算法实例总结
2016/12/22 Javascript
微信小程序 页面传值详解
2017/03/10 Javascript
javascript基于定时器实现进度条功能实例
2017/10/13 Javascript
JavaScript之创意时钟项目(实例讲解)
2017/10/23 Javascript
vue 自定义组件 v-model双向绑定、 父子组件同步通信的多种写法
2017/11/27 Javascript
微信小程序实现animation动画
2018/01/26 Javascript
基于JS开发微信网页录音功能的实例代码
2019/04/30 Javascript
react 中父组件与子组件双向绑定问题
2019/05/20 Javascript
微信小程序判断用户是否需要再次授权获取个人信息
2019/07/18 Javascript
Vuex 模块化使用详解
2019/07/31 Javascript
深入理解 TypeScript Reflect Metadata
2019/12/12 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
2020/07/11 Javascript
[02:56]DOTA2亚洲邀请赛 VG出场战队巡礼
2015/02/07 DOTA
[01:18]PWL开团时刻DAY4——圣剑与抢盾
2020/11/03 DOTA
[49:08]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第一场 11.27
2020/12/01 DOTA
Django中URL视图函数的一些高级概念介绍
2015/07/20 Python
浅谈python字符串方法的简单使用
2016/07/18 Python
浅谈numpy库的常用基本操作方法
2018/01/09 Python
pip install python 快速安装模块的教程图解
2019/10/08 Python
python 实现矩阵填充0的例子
2019/11/29 Python
TensorFlow的环境配置与安装方法
2021/02/20 Python
C语言基础笔试题
2013/04/27 面试题
肯尼迪就职演说稿
2013/12/31 职场文书
pytorch 实现变分自动编码器的操作
2021/05/24 Python
Python图片处理之图片裁剪教程
2021/05/27 Python