JS实现页面数据无限加载


Posted in Javascript onSeptember 13, 2016

在手机端浏览网页时,经常使用一个功能,当我们浏览京东或者淘宝时,页面滑动到底部,我们看到数据自动加载到列表。之前并不知道这些功能是怎么实现的,于是自己在PC浏览器上模拟实现这样的功能。先看看浏览效果:

当滚动条滚动到页面底部时,提示“正在加载…”。

JS实现页面数据无限加载 

当页面已经加载了所有数据后,滚动到页面底部会提示“数据已加载到底了”:

JS实现页面数据无限加载

实现数据无限加载的过程大致如下:

1.滚动条滚动到页面底部。

2.触发ajax加载,把请求返回的数据加载到列表后面。

如何判断滚动条是否滚动到页面底部?我们可以设置一个规则:当滚动条的滚动高度和整个文档高度相差不到20像素,则认为滚动条滚动到页面底部了:

文档高度 - 视口高度 - 滚动条滚动高度 < 20

要通过代码实现这样的判断,我们必须要了解上面的这些高度通过哪些代码获取?可以参考我之前写的一篇“HTML元素坐标定位,这些知识点得掌握”。

上面的判断,我封装了一个方法: 

//检测滚动条是否滚动到页面底部
 function isScrollToPageBottom(){
 //文档高度
 var documentHeight = document.documentElement.offsetHeight;
 var viewPortHeight = getViewportSize().h;
 var scrollHeight = window.pageYOffset ||
  document.documentElement.scrollTop ||
  document.body.scrollTop || 0;

 return documentHeight - viewPortHeight - scrollHeight < 20;
 }

判断有了,我们就可以开启一个定时器,900毫秒监测一次,如果isScrollToPageBottom()返回true则调用ajax请求数据,如果返回false则通过900毫秒之后再监测。

下面是核心代码实现: 

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>无限分页</title>
 <link rel="stylesheet" href="assets/css/index.css"/>
</head>
<body>
<div class="l-page">
 <ul id="list" class="list">
 </ul>
</div>
<script src="//cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
<script src="js/jquery.mockjax.js"></script>
<script type="text/javascript" src="js/dataMock.js"></script>
<script type="text/javascript">
 //作为一个对象的w和h属性返回视口的尺寸
 function getViewportSize(w){
 //使用指定的窗口, 如果不带参数则使用当前窗口
 w = w || window;

 //除了IE8及更早的版本以外,其他浏览器都能用
 if(w.innerWidth != null)
  return {w: w.innerWidth, h: w.innerHeight};

 //对标准模式下的IE(或任意浏览器)
 var d = w.document;
 if(document.compatMode == "CSS1Compat")
  return {w: d.documentElement.clientWidth, h: d.documentElement.clientHeight};

 //对怪异模式下的浏览器
 return {w: d.body.clientWidth, h: d.body.clientHeight};
 }

 //检测滚动条是否滚动到页面底部
 function isScrollToPageBottom(){
 //文档高度
 var documentHeight = document.documentElement.offsetHeight;
 var viewPortHeight = getViewportSize().h;
 var scrollHeight = window.pageYOffset ||
  document.documentElement.scrollTop ||
  document.body.scrollTop || 0;

 return documentHeight - viewPortHeight - scrollHeight < 20;
 }

 //商品模板
 function getGoodsTemplate(goods){
 return "<li>" +
  "<div class='pic-wrap leftFloat'>" +
  "<img src='" + goods.pic + "'>" +
  "</div>" +
  "<div class='info-wrap leftFloat'>" +
  "<div class='info-name'><span>" + goods.name + "</span></div>" +
  "<div class='info-address'><span>" + goods.address +"</span></div>" +
  "<div class='info-bottom'>" +
  "<div class='info-price leftFloat'><span>¥" + goods.price + "</span></div>" +
  "<div class='info-star leftFloat'><span>" + goods.star + "人推荐</span></div>" +
  "<div class='info-more leftFloat'><span>更多信息</span></div>" +
  "</div>" +
  "</div>" +
  "</li>";
 }

 //初始化的时候默给list加载100条数据
 $.ajax("http://localhost:8800/loadData?sessionId=" + (+ new Date)).done(function(result){
 if(result.status){
  var html = "";
  result.data.forEach(function(goods){
  html += getGoodsTemplate(goods);
  });
  $("#list").append(html);
 }
 });


 //加载数据
 function loadDataDynamic(){
 //先显示正在加载中
 if( $("#loadingLi").length === 0)
  $("#list").append("<li id='loadingLi' class='loading'>正在加载...</li>");
 else{
  $("#loadingLi").text("正在加载...").removeClass("space");
 }
 var loadingLi = document.getElementById("loadingLi");
 loadingLi.scrollIntoView();
 //加载数据,数据加载完成后需要移除加载提示
 var hasData = false, msg = "";
 $.ajax("http://localhost:8800/loadData?sessionId=" + (+ new Date)).done(function(result){
  if(result.status){
  if(result.data.length > 0){
   hasData = true;
   var html = "";
   result.data.forEach(function(goods){
   html += getGoodsTemplate(goods);
   });
   $("#list").append(html);
  }else{
   msg = "数据已加载到底了"
  }
  }
  $("#list").append(loadingLi);
 }).fail(function(){
  msg = "数据加载失败!";
  }).always(function(){
  !hasData && setTimeout(function(){
  $(document.body).scrollTop(document.body.scrollTop -40);
  }, 500);
  msg && $("#loadingLi").text(msg);
  //重新监听滚动
  setTimeout(watchScroll, 900);
  });
 }

 //如果滚动条滚动到页面底部,需要加载新的数据,并且显示加载提示
 function watchScroll(){
 if(!isScrollToPageBottom()){
  setTimeout( arguments.callee, 900);
  return;  }
 loadDataDynamic();
 }

 //开始检测滚动条
 watchScroll();
</script>
</body>
</html>

demo中ajax请求我是通过jquery-mockjax模拟的数据。代码如下: 

/**
 * 模拟接口.
 */
var i = 0, len = 200, addresses = ["四川", "北京", "上海", "广州", "深圳", "甘肃", "云南", "浙江", "青海", "贵州"];


function getData(){
 var size = Math.min(i + 50, len), arr = [];
 for(; i < size; i++){
 arr.push({
  name: "苹果" + (i % 10 + 1),
  pic: "assets/images/iphone" + (i % 10 + 1) + ".jpg",
  price: parseInt(Math.random() * 10000),
  star: parseInt(Math.random() * 1000),
  address: addresses[i % 10]
 })
 }

 return arr;
}

$.mockjax({
 url: 'http://localhost:8800/loadData*',
 responseTime: 1000,
 response: function(settings){
 this.responseText = {
  status: true,
  data: getData()
 }
 }
});

整个完整的demo我已上传到github上:
 https://github.com/heavis/pageLoader

在线演示:
 https://heavis.github.io/pageLoader/index.html

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

Javascript 相关文章推荐
Prototype最新版(1.5 rc2)使用指南(1)
Jan 10 Javascript
JS Loading功能的简单实现
Nov 29 Javascript
jQuery中scrollLeft()方法用法实例
Jan 16 Javascript
超级给力的JavaScript的React框架入门教程
Jul 02 Javascript
js实现下拉列表选中某个值的方法(3种方法)
Dec 17 Javascript
js随机生成26个大小写字母
Feb 12 Javascript
ES6中非常实用的新特性介绍
Mar 10 Javascript
JS+Canvas绘制时钟效果
Aug 20 Javascript
jquery与js实现全选功能的区别
Jun 11 jQuery
VueJs使用Amaze ui调整列表和内容页面
Nov 30 Javascript
前端axios下载excel文件(二进制)的处理方法
Jul 31 Javascript
ES5和ES6中类的区别总结
Dec 21 Javascript
jQuery实现可展开折叠的导航效果示例
Sep 12 #Javascript
jQuery简单实现列表隐藏和显示效果示例
Sep 12 #Javascript
jQuery实现弹出带遮罩层的居中浮动窗口效果
Sep 12 #Javascript
jQuery实现的无限级下拉菜单功能示例
Sep 12 #Javascript
jQuery实现的图片轮播效果完整示例
Sep 12 #Javascript
Vue组件BootPage实现简单的分页功能
Sep 12 #Javascript
jQuery实现的多张图无缝滚动效果【测试可用】
Sep 12 #Javascript
You might like
PHP中HTTP方式下的Gzip压缩传输方法举偶
2007/02/15 PHP
PHP导入Excel到MySQL的方法
2011/04/23 PHP
php生成百度sitemap站点地图类函数实例
2014/10/17 PHP
php中get_defined_constants函数用法实例分析
2015/05/12 PHP
PHP使用Pear发送邮件(Windows环境)
2016/01/05 PHP
微信小程序 消息推送php服务器验证实例详解
2017/03/30 PHP
如何让页面在打开时自动刷新一次让图片全部显示
2012/12/17 Javascript
jquery简单的拖动效果实现原理及示例
2013/07/26 Javascript
JS实现图片横向滚动效果示例代码
2013/09/04 Javascript
javascript转换静态图片,增加粒子动画效果
2015/05/28 Javascript
jQuery超简单选项卡完整实例
2015/09/26 Javascript
jquery validate demo 基础
2015/10/29 Javascript
jQuery Password Validation密码验证
2016/12/30 Javascript
Vue+axios 实现http拦截及路由拦截实例
2017/04/25 Javascript
使用bootstrap插件实现模态框效果
2017/05/10 Javascript
lhgcalendar时间插件限制只能选择三个月的实现方法
2017/07/03 Javascript
js表单序列化判断空值的实例
2017/09/22 Javascript
基于js 字符串indexof与search方法的区别(详解)
2017/12/04 Javascript
vue实现菜单切换功能
2019/05/08 Javascript
vue+element-ui+axios实现图片上传
2019/08/20 Javascript
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
Flask之flask-session的具体使用
2018/07/26 Python
python 监听salt job状态,并任务数据推送到redis中的方法
2019/01/14 Python
python简单验证码识别的实现方法
2019/05/10 Python
Python利用scapy实现ARP欺骗的方法
2019/07/23 Python
django 通过URL访问上传的文件方法
2019/07/28 Python
对Django 转发和重定向的实例详解
2019/08/06 Python
Python3爬虫中Splash的知识总结
2020/07/10 Python
移动端Web页面的CSS3 flex布局快速上手指南
2016/05/31 HTML / CSS
英国经济型酒店品牌:Travelodge
2019/12/17 全球购物
网络程序员自荐信
2014/01/25 职场文书
教师自我反思材料
2014/02/14 职场文书
大学自主招生自荐信范文
2014/02/26 职场文书
社区母亲节活动方案
2014/03/05 职场文书
积极贯彻学习两会精神总结
2014/03/17 职场文书
Consul在linux环境的集群部署
2022/04/08 Servers