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 相关文章推荐
JavaScript的面向对象(一)
Nov 09 Javascript
jquery导航制件jquery鼠标经过变色效果示例
Dec 05 Javascript
JS获取文本框,下拉框,单选框的值的简单实例
Feb 26 Javascript
jQuery中outerWidth()方法用法实例
Jan 19 Javascript
jquery利用命名空间移除绑定事件的方法
Mar 11 Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
Mar 31 Javascript
JavaScript类型系统之基本数据类型与包装类型
Jan 06 Javascript
jQuery插件实现表格隔行变色及鼠标滑过高亮显示效果代码
Feb 25 Javascript
jQuery实现鼠标选中文字后弹出提示窗口效果【附demo源码】
Sep 05 Javascript
详解PHP中pathinfo()函数导致的安全问题
Jan 05 Javascript
JQuery.dataTables表格插件添加跳转到指定页
Jun 09 jQuery
JavaScript中十种一步拷贝数组的方法实例详解
Apr 22 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 在windows下配置虚拟目录的方法介绍
2013/06/26 PHP
解析阿里云ubuntu12.04环境下配置Apache+PHP+PHPmyadmin+MYsql
2013/06/26 PHP
php中文语义分析实现方法示例
2019/09/28 PHP
PHP-FPM 设置多pool及配置文件重写操作示例
2019/10/02 PHP
javascript hashtable实现代码
2009/10/13 Javascript
js判断一个元素是否为另一个元素的子元素的代码
2012/03/21 Javascript
JQuery设置文本框和密码框得到焦点时的样式
2013/08/30 Javascript
Javascript中匿名函数的多种调用方式总结
2013/12/06 Javascript
jQuery中dequeue()方法用法实例
2014/12/29 Javascript
微信小程序上传图片到服务器实例代码
2017/11/07 Javascript
angularJs-$http实现百度搜索时的动态下拉框示例
2018/02/27 Javascript
JavaScript JMap类定义与使用方法示例
2019/01/22 Javascript
JavaScript遍历DOM元素的常见方式示例
2019/02/16 Javascript
Vue.js中的组件系统
2019/05/30 Javascript
Angular 中使用 FineReport不显示报表直接打印预览
2019/08/21 Javascript
js实现坦克移动小游戏
2019/10/28 Javascript
JavaScript中的类型检查
2020/02/03 Javascript
[42:48]完美世界DOTA2联赛PWL S3 Magma vs INK ICE 第二场 12.11
2020/12/16 DOTA
Python学习之asyncore模块用法实例教程
2014/09/29 Python
python使用Tkinter显示网络图片的方法
2015/04/24 Python
Python中断言Assertion的一些改进方案
2016/10/27 Python
python可视化爬虫界面之天气查询
2019/07/03 Python
Python networkx包的实现
2020/02/14 Python
django model object序列化实例
2020/03/13 Python
Python网络爬虫四大选择器用法原理总结
2020/06/01 Python
keras load model时出现Missing Layer错误的解决方式
2020/06/11 Python
浅谈Keras的Sequential与PyTorch的Sequential的区别
2020/06/17 Python
Python return语句如何实现结果返回调用
2020/10/15 Python
python opencv角点检测连线功能的实现代码
2020/11/24 Python
输入N,打印N*N矩阵
2012/02/20 面试题
培训演讲稿范文
2014/01/12 职场文书
技校毕业生个人学习的自我评价
2014/02/21 职场文书
节约用水的口号
2014/06/20 职场文书
导游词之藏龙百瀑景区
2019/12/30 职场文书
Python开发五子棋小游戏
2022/04/28 Python
JS中forEach()、map()、every()、some()和filter()的用法
2022/05/11 Javascript