声明:本插件模仿自mescroll.js,随手所作,仅以注释提供思路,只实现了部分效果,且没有考虑兼容,有兴趣的朋友随意一看。api大家可参考mescroll.js API汇总一文。
demo:点我下载实例
插件全部js原代码如下:
//上拉加载插件 Mescroll = function(){ var that = this; that.mescrollCallBack;//回调函数,可拆分为上拉加载回调函数、下拉刷新回调函数,此处上拉加载、下拉刷新调用同一个回调函数 that.page = {//列表信息的页码信息,包括每页条数、页码 num: 1,//初始页码,默认列表页初始页码为1。第一种访问方式,页码变化,列表条数不变 size: 10,//每页显示条数,默认列表页每页显示10条 trueNum: "",//另一种页码计算方式,此计算方式中,页码不变,变化的只有列表页条数,此变量用于记录页码,初始值为page.num。第二种访问方式,页码不变,列表条数变化 trueSize: "",//列表页条数,初始值为page.size }; that.emptyId = "ListUl";//列表信息为空时,显示列表为空的信息的div的id值,默认为ListUl that.empty = {//列表信息为空时,显示列表为空的信息 icon: "../../images/mescroll-empty.png",//默认图标地址 tip: "暂无相关数据~", //提示 btntext: "返回上一页", //按钮,默认"" btnHref: "javascript:history.go(-1)"//点击按钮的回调,默认null }; that.noMoreSize = 5;//如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(譬如只有一条数据),显示无更多数据会不好看;默认设置为5 that.noMore = {//列表无更多信息时,显示的提示 tip: "-- END --"//提示 }; that.toTop = {//配置回到顶部按钮 src: "../../images/mescroll-totop.png",//默认图标 offset: window.innerHeight,//默认滚出设备屏幕高度时显示 time: 1000//回到顶部的时间,默认1秒钟 }; that.upLoadHeight = 60;//距离底部60px时,即触发上拉加载,不必完全拉到底部 that.upLoad = true;//是否启用上拉加载,默认启用 that.downLoad = true;//是否启用下拉刷新,默认启用 that.scrollToptimer;//定时循环回到顶部的定时器 var firstLoadStatu = true;//是否第一次执行此函数 var scrollUpLoad = true;//滚动条触发上拉加载,一段范围内,只允许触发一次 var oldScrollHeight = 0;//存储上一个滚轮的位置,用以判断滚轮是向上滚动、还是向下滚动,初始值为0 var pageY;//当前页面高度 var sheBeiY = window.innerHeight;//设备屏幕高度 var scrollY;//当前滚动条的位置 var startY;//起点Y轴位置 var endY;//终点Y轴位置 that.firstLoad = function(){//初始化此插件时,执行回调函数 if(firstLoadStatu){ that.page.trueNum = that.page.num;//第二种访问方式,为页码赋值 that.page.trueSize = that.page.size;//为列表页条数赋值 that.mescrollCallBack(that.page);//若是第一次执行此函数,直接执行回调函数 firstLoadStatu = false;//实例化此插件后,只能执行一次此函数 }; }; that.endMescroll = function(listNum){//传入列表信息条数,判断显示的内容 document.getElementById(that.emptyId).innerHTML="";//执行此函数前,先把之前添加的参数清空 if(listNum == 0){//若列表信息为空时,显示列表为空的信息 document.getElementById(that.emptyId).innerHTML="<div class="mescroll_empty">" +"<img class="mescroll_empty_icon" src=""+that.empty.icon+"">" +"<p class="mescroll_empty_tip">"+that.empty.tip+"~</p>" +"<a class="mescroll_empty_btn" href=""+that.empty.btnHref+"">"+that.empty.btntext+"</a>" +"</div>"; }else if(that.noMoreSize<listNum && listNum<that.page.trueSize){//列表无更多信息时,显示提示 document.getElementById(that.emptyId).innerHTML="<h4 class="mescroll_end">"+that.noMore.tip+"</h4>"; } if(listNum < that.page.trueSize){ that.upLoad = false;//禁止上拉加载 }else{ that.upLoad = true;//启用上拉加载 } }; document.addEventListener("touchstart",function(ev){//手指在屏幕上的起始位置 startY = ev.touches[0].pageY;//获取起点Y轴位置 },false); document.addEventListener("touchend",function(ev){//手指在屏幕上的结束位置 pageY = document.body.scrollHeight;//获取当前页面高度 scrollY = window.scrollY;//获取当前滚动条的位置 endY = ev.changedTouches[0].pageY;//获取终点Y轴位置 //上拉加载 if(pageY-sheBeiY < 0 || (pageY-sheBeiY-scrollY-that.upLoadHeight<0)){//若 当前页面高度 - 设备屏幕高度 < 0 ,即屏幕不满一页,需要拉动的距离设置为0 var upDistanceY = 0; }else{ var upDistanceY = pageY - sheBeiY - scrollY -that.upLoadHeight;//当前页面高度-设备屏幕高度-当前滚动条的位置=需要拉动的距离,60是指距离底部60px,即触发下拉加载,不必完全拉到底部 } var upY = startY - endY;//上拉时,向上拉动的距离 if(upY > upDistanceY){//上拉加载 if(that.scrollToptimer){//若正处于回到顶部的过程中,立即停止回到顶部,清除掉定时器 clearInterval(that.scrollToptimer); } if(that.upLoad){//启用了上拉加载 that.page.num += 1;//页码数+1 that.page.trueSize = that.page.num*that.page.size;//计算列表页条数 that.mescrollCallBack(that.page);//执行回调函数 } }; //下拉刷新 var dowmY = endY - startY;//下拉刷新时,向下拉动的距离 if(dowmY>scrollY){//下拉刷新 if(that.downLoad){//启用了下拉刷新 that.page.num = that.page.trueNum;//页码数还原为初始页码 that.page.trueSize = that.page.size;//列表页条数还原为初始列表页条数 that.mescrollCallBack(that.page);//执行回调函数 }; }; },false); //监听滚动条 document.addEventListener("scroll",function(ev){ pageY = document.body.scrollHeight;//获取当前页面高度 scrollY = window.scrollY;//获取当前滚动条的位置 if(scrollY>oldScrollHeight){//如果当前位置>上一个滚轮的位置,即为向下滚动,即上拉 if(that.scrollToptimer){//若正处于回到顶部的过程中,立即停止回到顶部,清除掉定时器 clearInterval(that.scrollToptimer); } } oldScrollHeight = scrollY; //console.log("当前滚动条的位置:"+scrollY); //上拉加载 if(pageY - scrollY - sheBeiY < that.upLoadHeight){//当前页面高度 - 若 当前滚动条的位置 - 设备屏幕高度 < 60 ,即触发上拉加载 if(scrollUpLoad){//是否允许滚动条触发上拉加载 scrollUpLoad = false;//滚动条触发上拉加载后,禁止滚动条触发上拉加载,一段范围内,只允许触发一次 if(that.upLoad){//启用了上拉加载 that.page.num += 1;//页码数+1 that.page.trueSize = that.page.num*that.page.size;//计算列表页条数 that.mescrollCallBack(that.page);//执行回调函数 } } }else{ scrollUpLoad = true;//滚动条无法触发上拉加载后,允许滚动条触发上拉加载 } if(scrollY>that.toTop.offset){//若滚动条位置 > 设置的高度,新增一个回到顶部的img元素 if(document.getElementsByClassName("mescroll_toTop_img").length==0){//若没有回到顶部的img,添加它 var toTopImg = document.createElement("img");//创建一个img元素 toTopImg.className="mescroll_toTop_img";//为该img元素添加一个class名 toTopImg.src=that.toTop.src;//为该img元素的src属性赋值 document.getElementById(that.emptyId).before(toTopImg);//在指定的dom元素前添加该子元素img document.getElementsByClassName("mescroll_toTop_img")[0].addEventListener("click",function(ev){ //document.documentElement.scrollTop = 0; var toTop = document.body.scrollTop || document.documentElement.scrollTop;//获取初始时距顶部距离的值 var toTopHeight = toTop * 20 * 3 / that.toTop.time;//初始时距顶部距离的值 * 定时器的时间 / 回到顶部的时间 = 单位时间内,往上滑的距离,多乘了一个3,是因为测试时觉得太慢 that.scrollToptimer = setInterval(function (){//定时循环回到顶部,speed值越小,动画效果越慢 var currentToTop = document.body.scrollTop || document.documentElement.scrollTop;//获取当前距顶部距离的值 if (document.body.scrollTop!=0){ document.body.scrollTop -= toTopHeight; }else{ document.documentElement.scrollTop -= toTopHeight; } if(currentToTop == 0){ clearInterval(that.scrollToptimer); } },20); },false); } }else{//若滚动条位置 < 设置的高度,移除该回到顶部的img元素 if(document.getElementsByClassName("mescroll_toTop_img").length==1){//若有回到顶部的img,移除它 var toTopImg=document.getElementsByClassName("mescroll_toTop_img")[0];//获取该回到顶部的img元素 toTopImg.parentNode.removeChild(toTopImg);//移除该回到顶部的img元素 } } },false); };