zoukankan      html  css  js  c++  java
  • 移动端下拉刷新上拉加载更多组件Iscroll组件的使用

    前阶段做app H5页面

    有一个列表页需要下拉刷新上拉加载更多的需求,找到了Iscroll组件。看了相应的js,其实现这个功能的原理是监听滚动事件,利用滚动的方向,滚动的距离实现功能。之前用过的iscroll的逻辑大致是监听滚动的距离和5px做了一个比较,然后给固定的头部(内容为向下刷新)活底部(内容为上拉加载更多)添加或者移除相应的类,然后在通过判断头部或者底部是否存在这个类来进行的一个判断,从而触发刷新或者ajax请求加载更多。

    其实为了完成这个需求找过两版插件,但是第一版出现了问题:当内容大于一屏的时候才能显现出来,当上拉的时候,屏幕并不能顺滑的向上滑动,而且在松开手之后内容总是定位到最上端,效果和里面内容设置了top:0一样。其实我就简单的试验了一下demo,后来出了bug在去试验demo的时候发现demo也有这个问题(囧)。

    后来又找了一个基于iscroll的dem,因为适合具体的业务相关,所以对其进行了实例化,下面贴出代码:

    //
    function pullWay(option) {
    var pageNo = 2;

    function Refresh() {
    setTimeout(function () { // <-- Simulate network congestion, remove setTimeout from production!
    var el, li, i;
    el = document.getElementById('thelist');
    //这里写你的刷新代码
    document.getElementById("wrapper").querySelector(".pullDownIcon").style.display = "none";
    document.getElementById("wrapper").querySelector(".pullDownLabel").innerHTML = "<img src='../../images/ok.png'/>刷新成功";
    setTimeout(function () {
    wrapper.refresh();
    document.getElementById("wrapper").querySelector(".pullDownLabel").innerHTML = "";
    }, 1000); //模拟qq下拉刷新显示成功效果
    /****remember to refresh after action completed! ---yourId.refresh(); ----| ****/
    }, 1000);
    }

    function Load() {
    setTimeout(function () { // <-- Simulate network congestion, remove setTimeout from production!
    var el, li, i;
    el = document.getElementById('thelist');
    $.ajax({
    type: "GET",
    url: option.url,
    data: {
    pageSize: 1,
    pageNo: pageNo++
    },
    dataType: "json",
    // contentType: 'application/json',
    success: function (data) {
    var html = option.ajaxWay(data);
    for (i = 0; i < 1; i++) {
    li = document.createElement('li');
    li.innerHTML = html;
    el.appendChild(li, el.childNodes[0]);
    if (option.details) {
    option.details();
    }
    wrapper.refresh(); // 数据加载完成后,调用界面更新方法 Remember to refresh when contents are loaded (ie: on ajax completion)

    }
    }
    });

    }, 1000); // <-- Simulate network congestion, remove setTimeout from production!
    setTimeout(function(){
    wrapper.refresh(); // 数据加载完成后,调用界面更新方法 Remember to refresh when contents are loaded (ie: on ajax completion)
    },3300)

    }

    var refresher = {
    info: {
    "pullDownLable": "下拉刷新",
    "pullingDownLable": "释放立即刷新",
    "pullUpLable": "上拉加载更多",
    "pullingUpLable": "释放加载更多",
    "loadingLable": "加载中..."
    },
    init: function (parameter) {
    var wrapper = document.getElementById(parameter.id);
    var div = document.createElement("div");
    div.className = "scroller";
    wrapper.appendChild(div);
    var scroller = wrapper.querySelector(".scroller");
    var list = wrapper.querySelector("#" + parameter.id + " ul");
    scroller.insertBefore(list, scroller.childNodes[0]);
    var pullDown = document.createElement("div");
    pullDown.className = "pullDown";
    var loader = document.createElement("div");
    loader.className = "pullDownIcon";
    pullDown.appendChild(loader);
    var pullDownLabel = document.createElement("div");
    pullDownLabel.className = "pullDownLabel";
    pullDown.appendChild(pullDownLabel);
    scroller.insertBefore(pullDown, scroller.childNodes[0]);
    var pullUp = document.createElement("div");
    pullUp.className = "pullUp";
    var loader = document.createElement("div");
    loader.className = "pullUpIcon";
    pullUp.appendChild(loader);
    var pullUpLabel = document.createElement("div");
    pullUpLabel.className = "pullUpLabel";
    var content = document.createTextNode(refresher.info.pullUpLable);
    pullUpLabel.appendChild(content);
    pullUp.appendChild(pullUpLabel);
    scroller.appendChild(pullUp);
    var pullDownEle = wrapper.querySelector(".pullDown");
    var pullDownOffset = pullDownEle.offsetHeight;
    var pullUpEle = wrapper.querySelector(".pullUp");
    var pullUpOffset = pullUpEle.offsetHeight;
    this.scrollIt(parameter, pullDownEle, pullDownOffset, pullUpEle, pullUpOffset);
    },
    scrollIt: function (parameter, pullDownEle, pullDownOffset, pullUpEle, pullUpOffset) {
    eval(
    parameter.id + "= new iScroll(
    parameter.id,
    {
    useTransition: true,
    vScrollbar: false,
    topOffset: pullDownOffset,
    onRefresh: function () {
    refresher.onRelease(pullDownEle,pullUpEle);
    },
    onScrollMove: function () {
    refresher.onScrolling(this,pullDownEle,pullUpEle,pullUpOffset);
    },
    onScrollEnd: function () {
    refresher.onScrollEnd(pullDownEle,parameter.pullDownAction,pullUpEle,parameter.pullUpAction);
    }
    })"
    );
    },
    onScrolling: function (e, pullDownEle, pullUpEle, pullUpOffset) {
    if (e.y > -(pullUpOffset) && !pullDownEle.className.match('loading')) {
    pullDownEle.classList.remove("flip");
    pullDownEle.querySelector('.pullDownLabel').innerHTML = refresher.info.pullDownLable;
    pullDownEle.querySelector('.pullDownIcon').style.display = "block";
    e.minScrollY = -pullUpOffset;
    }
    if (e.scrollerH < e.wrapperH && e.y > e.maxScrollY - pullUpOffset && pullUpEle.className.match("flip") || e.scrollerH > e.wrapperH && e.y > e.maxScrollY - pullUpOffset && pullUpEle.className.match("flip")) {
    pullUpEle.classList.remove("flip");
    pullUpEle.querySelector('.pullUpLabel').innerHTML = refresher.info.pullUpLable;
    }
    if (e.y > 0 && !pullUpEle.className.match('loading') && !pullDownEle.className.match('loading')) {
    pullDownEle.classList.add("flip");
    pullDownEle.querySelector('.pullDownLabel').innerHTML = refresher.info.pullingDownLable;
    e.minScrollY = 0;
    }
    if (e.scrollerH < e.wrapperH && e.y < (e.minScrollY - pullUpOffset) && !pullDownEle.className.match('loading') && !pullUpEle.className.match('loading') || e.scrollerH > e.wrapperH && e.y < (e.maxScrollY - pullUpOffset) && !pullDownEle.className.match('loading') && !pullUpEle.className.match('loading')) {
    pullUpEle.classList.add("flip");
    pullUpEle.querySelector('.pullUpLabel').innerHTML = refresher.info.pullingUpLable;
    }

    },
    onRelease: function (pullDownEle, pullUpEle) {
    if (pullDownEle.className.match('loading')) {
    pullDownEle.classList.toggle("loading");
    pullDownEle.querySelector('.pullDownLabel').innerHTML = refresher.info.pullDownLable;
    }
    if (pullUpEle.className.match('loading')) {
    pullUpEle.classList.toggle("loading");
    pullUpEle.querySelector('.pullUpLabel').innerHTML = refresher.info.pullUpLable;
    }
    },
    onScrollEnd: function (pullDownEle, pullDownAction, pullUpEle, pullUpAction) {
    if (pullDownEle.className.match('flip') && !pullDownEle.className.match('loading')) {
    pullDownEle.classList.add("loading");
    pullDownEle.classList.remove("flip");
    pullDownEle.querySelector('.pullDownLabel').innerHTML = refresher.info.loadingLable;
    if (pullDownAction) pullDownAction();
    }
    if (pullUpEle.className.match('flip') && !pullUpEle.className.match('loading')) {
    pullUpEle.classList.add("loading");
    pullUpEle.classList.remove("flip");
    pullUpEle.querySelector('.pullUpLabel').innerHTML = refresher.info.loadingLable;
    if (pullUpAction) pullUpAction();
    }
    }
    }
    refresher.init({
    id: "wrapper", //<------------------------------------------------------------------------------------┐
    pullDownAction: Refresh,
    pullUpAction: Load
    });
    }

    原版的init函数,Refresh函数和Load函数不在这个js里面,为了做成一个统一的组件,将其封装在这个js里面,这样pullWay就是唯一的入口,传入相应的参数即可,
    你可以把page,ajax等在外部随意变化,最后当做参数传进来。对比一个之前的js,我做了一个比较,区别在于对于距离的选取更精确和更准确,并木有明确的数字,
    而是在触发事件的时候,对于相应的事件距离和容器距离进行获取和对比,从而进行下一步的判断和事件触发。实现的效果和官方demo的效果一样,符合现在大部分的下拉
    刷新上拉加载更多的需求,和原生的区别在于最下面的上拉加载更多的按钮不能在顶部定位,而是始终在内部内容的最下方。这个我后续会去找demo或者方法去优化,
    希望这篇文章对大家有用,如果有什么不清楚的地方或者由于自己的项目造成的不适用,欢迎一起来讨论。
  • 相关阅读:
    服务器/服务器架构/阿里云服务器/虚拟机
    第十五章、线程之协程
    第十五章、线程池和进程池
    第十五章、线程之queue模块的各种队列
    第十五章、Python多线程之信号量和GIL
    第十五章、Python多线程同步锁,死锁和递归锁
    第十五章、并发编程之守护线程
    第十五章、并发编程之线程
    抢票小程序
    队列与生产者消费者模型
  • 原文地址:https://www.cnblogs.com/wyliunan/p/9698546.html
Copyright © 2011-2022 走看看