• 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);
    };
  • 相关阅读:
    Emqx启用Redis认证
    写在2021末
    如何让 Spring Security 「少管闲事」
    泛型就这么简单
    Spring Boot 对多线程支持提高程序执行效率
    Java桌面应用JavaFX01Hello World
    PostgreSQL实现Oracle merge into功能
    超大JSON文件解析方案(Java)
    记一次IDEA搭建Spring源码阅读环境
    Oracle转PostgreSQL之start with / connect by
  • 原文地址:https://www.cnblogs.com/chenyoumei/p/9338124.html
Copyright © 2020-2023  润新知