mescroll.js简单的上拉加载、下拉刷新插件,带完整注释

声明:本插件模仿自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);
};
原文地址:https://www.cnblogs.com/chenyoumei/p/9338124.html