聲明:本插件模仿自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); };