JS三教九流系列-iscroll.js-页面下拉刷新上拉加载等效果实现

与世无争的帅哥 提交于 2019-12-09 10:14:40

一.准备环节

iscroll.js 5.x版本项目地址 https://github.com/cubiq/iscroll 

演示地址:http://pnc.co.il/dev/iscroll-5-pull-to-refresh-and-infinite-demo.html 

下载解压,我们打开demos目录,把click复制,改名字为app,也就是我们处理的基础,app文件目录下的index.html改为app.html,都是为了更好理解为自己创建的应用

我们打开app.html,先预览一下js文件,就是iscroll.js,看看就好,我们没必要去改,我们返回html页面,

js部分做出修改如下:

<script type="text/javascript">
window.onload=function(){
 var myScroll;
 myScroll = new IScroll('#wrapper', { mouseWheel: true, click: true });
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
};
</script>

html的body标签调用的载入去掉,这样看着才舒心:

<body>

:::::最重要的一点,在引入类库的目录下我们可以看到很多iscroll.js的类库文件,我们选择下面的,这是事最全的,可以保证所有api被支持:

我们引入js部分代码改成如下:

<script type="text/javascript" src="../../build/iscroll-probe.js"></script>

我们需要找到针对iscroll的api,根据api提供的属性和方法等去修改目标效果。

二.接口使用和基本封装

----1.思考

我们要找到的是事件:

1.下拉事件接口

2.上拉事假接口

我们找到后,

针对下拉做提示刷新图标显示

针对上拉,就去ajax请求调用,当然我们只要模拟插入数据就好了。

针对5.x版本,我们一定要找到对应的api,不同版本的api是不同的,我们大致罗列iscroll5.x的所有api:

网上的一套总结:http://www.cnblogs.com/leolai/articles/4204345.html 

官网虽好,英文水平不行:http://iscrolljs.com/

 

----2.事件:

myScroll.on('scrollStart', function(){console.log("拖拽开始")});
myScroll.on('scroll', function(){console.log("拖拽中")});
myScroll.on('scrollEnd', function(){console.log("拖拽结束")});

我们修改代码,加入事件测试:

<script type="text/javascript">
window.onload=function(){
 var myScroll;
 myScroll = new IScroll('#wrapper', { 
  mouseWheel: true,  //是否监听鼠标滚轮事件
  bounceTime:600,    //弹力动画持续的毫秒数
  probeType: 3
 });
 myScroll.on('scrollStart', function(){console.log("开始")}); 
 myScroll.on('scroll', function(){console.log("拖拽中")}); 
 myScroll.on('scrollEnd', function(){console.log("结束")}); 
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
 //alert(myScroll.y)
 
};
</script>

 测试的日志显示,表示我们需要的事件被支持:

 

----3.属性

 myScroll.x   //当前位置
 myScroll.y
 
 myScroll.maxScrollX   //当滚动到底部时的 myScroll.x/y
 myScroll.maxScrollY
 
 myScroll.directionX  //上一次的滚动方向(-1 下/右, 0 保持原状, 1 上/左)
 myScroll.directionY 
 
 myScroll.currentPage //当前Snap信息

 我们的处理都是下拉和上拉处理,毫无疑问在y轴的处理才是我们需要的,我们需要的api属性大概应该如下:

myScroll.y  //当前位置y
myScroll.maxScrollY //当滚动到底部时的 y

我们在 scroll 事件输出这两个信息测试,js代码修改如下:

<script type="text/javascript">
window.onload=function(){
 var myScroll;
 myScroll = new IScroll('#wrapper', { 
  mouseWheel: true,  //是否监听鼠标滚轮事件
  bounceTime:600,    //弹力动画持续的毫秒数
  probeType: 3
 });
 myScroll.on('scrollStart', function(){console.log("开始")}); 
 myScroll.on('scroll', function(){
  console.log("拖拽中y:"+myScroll.y);
  console.log("拖拽底部y:"+myScroll.maxScrollY);
 }); 
 myScroll.on('scrollEnd', function(){console.log("结束")}); 
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
 
 
};
</script>

分析打印日志,我们得出myScroll.maxScrollY 是固定值;

myScroll.y是时时变化值;

我们结合实际:

下拉就是myScroll.y大于0;

下拉就是myScroll.y小于myScroll.maxScrollY

 

----4.根据y值做出最基本封装

根据上面的结果,我们做了下面判断处理,并日志打印,我们写个5的差值,就是为了避免一移动就触发

<script type="text/javascript">
window.onload=function(){
 var myScroll;
 myScroll = new IScroll('#wrapper', { 
  mouseWheel: true,  //是否监听鼠标滚轮事件
  bounceTime:600,    //弹力动画持续的毫秒数
  probeType: 3
 });
 myScroll.on('scrollStart', function(){console.log("开始")}); 
 myScroll.on('scroll', function(){
  if (this.y > 5) {
   //下拉刷新效果  
   console.log("下拉");
  } else if (this.y < (this.maxScrollY - 5)) {
   //上拉刷新效果  
   console.log("上拉");
  };  
 }); 
 myScroll.on('scrollEnd', function(){console.log("结束")}); 
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
 
 
};
</script>

 

----5.二次封装处理

我们问题在哪里?拿下拉举例子,就是只要下拉就打印日志,这是不符合逻辑的,应该是

  1. 判断出下拉或者上拉 事件

  2. 在下拉或者上拉结束打印日志或者处理

我们删除开始事件,这个已经不用,

我们创建表示上拉和下拉的变量,然后在结束时间根据标志去做判断处理,代码修改如下:

<script type="text/javascript">
window.onload=function(){
 var myScroll;
 myScroll = new IScroll('#wrapper', { 
  mouseWheel: true,  //是否监听鼠标滚轮事件
  bounceTime:600,    //弹力动画持续的毫秒数
  probeType: 3
 });
 var handle=0;//初始为0,无状态;1表示下拉,2表示上拉
 myScroll.on('scroll', function(){
  if (this.y > 5) {
   //下拉刷新效果 ,标识设置为1 
   handle=1;
  } else if (this.y < (this.maxScrollY - 5)) {
   //上拉刷新效果 ,表示设置为2 
   handle=2;
  };  
 }); 
 myScroll.on('scrollEnd', function(){
  if(handle==1){
   //下拉刷新处理
   console.log("下拉");
   myScroll.refresh();
   handle=0;//重设为0,改为无状态
  }else if(handle==2){
   //上拉刷新处理
   console.log("上拉");
   handle=0;//重设为0,改为无状态
  }else{handle=0;};  
 }); 
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
  
};
</script>

我们谷歌浏览器,去测试,就发现是没什么问题的,下拉/上拉+结束才会处理。

这样会显得结构比较乱,我们会好把处理的程序代码放在外面调用处理,我们进一步修改优化如下:

<script type="text/javascript">
window.onload=function(){
 var myScroll;
 myScroll = new IScroll('#wrapper', { 
  mouseWheel: true,  //是否监听鼠标滚轮事件
  bounceTime:600,    //弹力动画持续的毫秒数
  probeType: 3
 });
 var handle=0;//初始为0,无状态;1表示下拉,2表示上拉
 myScroll.on('scroll', function(){
  if (this.y > 5) {//下拉刷新效果 ,标识设置为1 
   handle=1;
  } else if (this.y < (this.maxScrollY - 5)) {//上拉刷新效果 ,表示设置为2 
   handle=2;
  };  
 }); 
 myScroll.on('scrollEnd', function(){
  if(handle==1){//下拉刷新处理
   downrefresh()
   handle=0;//重设为0,改为无状态
  }else if(handle==2){//上拉刷新处理
   upajaxload()   
   handle=0;//重设为0,改为无状态
  }else{handle=0;};  
 }); 
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
 
 
 function downrefresh(){//刷新处理
  console.log("下拉");
  myScroll.refresh();
 };
 function upajaxload(){//加载处理
  console.log("上拉");
 };
  
};
</script>

对于结束时的判断我们只要放在这两个函数里面就好了,下拉刷新和上拉加载的处理代码。

 

----6.三次封装处理

下拉就不必多说,app里面就是加载下面的数据,但是下拉的时候我们会看到提示内容:

 

下拉过程中,那个位置要显示些什么(提示啊),我们现在就在这个部分加上处理,其实上拉要是也有的话,原理一样。

我们在页面这个位置定位一个标签,写入要显示的内容,开始透明度为0,我们在下拉时改变透明度去显示

<script type="text/javascript">
window.onload=function(){
 var requestf5=document.getElementById("requestf5");
 var myScroll;
 myScroll = new IScroll('#wrapper', { 
  mouseWheel: true,  //是否监听鼠标滚轮事件
  bounceTime:600,    //弹力动画持续的毫秒数
  probeType: 3
 });
 var handle=0;//初始为0,无状态;1表示下拉,2表示上拉
 myScroll.on('scroll', function(){
  if (this.y > 5) {//下拉刷新效果 ,标识设置为1 
   handle=1;
   if(this.y>20){
    requestf5.style.opacity=1;
   }else{
    requestf5.style.opacity=0;
   };
  } else if (this.y < (this.maxScrollY - 5)) {//上拉刷新效果 ,表示设置为2 
   handle=2;
  };  
 }); 
 myScroll.on('scrollEnd', function(){
  if(handle==1){//下拉刷新处理
   downrefresh()
   handle=0;//重设为0,改为无状态
  }else if(handle==2){//上拉刷新处理
   upajaxload()   
   handle=0;//重设为0,改为无状态
  }else{handle=0;};  
 }); 
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
 
 
 function downrefresh(){//刷新处理
  console.log("下拉");
  myScroll.refresh();
 };
 function upajaxload(){//加载处理
  console.log("上拉");
 };
  
};
</script>

当时我的是非常粗糙的处理,这个提示根据你的设计可以丰富起来。

基本的处理和封装以及api的使用就结束了,还有很多参数的设置,可以参考api。

三.非常简单的模拟实例

刷新就这样就可以了,我们给下拉加入请求处理,就是ajax载入数据,我们修改页面结构,第一页内容默认显示,我们引入jq类库,方便我们ajax的模拟处理和节点插入

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<title>iScroll demo: click</title>
<script type="text/javascript" src="../../build/iscroll-probe.js"></script>
<script type="text/javascript" src="jquery-1.10.2.js"></script>
<script type="text/javascript">
$(function(){
 var requestf5=document.getElementById("requestf5");
 var myScroll;
 myScroll = new IScroll('#wrapper', { 
  mouseWheel: true,  //是否监听鼠标滚轮事件
  bounceTime:600,    //弹力动画持续的毫秒数
  probeType: 3
 });
 var handle=0;//初始为0,无状态;1表示下拉,2表示上拉
 myScroll.on('scroll', function(){
  if (this.y > 5) {//下拉刷新效果 ,标识设置为1 
   handle=1;
   if(this.y>20){
    requestf5.style.opacity=1;
   }else{
    requestf5.style.opacity=0;
   };
  } else if (this.y < (this.maxScrollY - 5)) {//上拉刷新效果 ,表示设置为2 
   handle=2;
  };  
 }); 
 myScroll.on('scrollEnd', function(){
  if(handle==1){//下拉刷新处理
   downrefresh()
   handle=0;//重设为0,改为无状态
  }else if(handle==2){//上拉刷新处理
   upajaxload()   
   handle=0;//重设为0,改为无状态
  }else{handle=0;};  
 }); 
 document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
 
 
 function downrefresh(){//刷新处理
  console.log("下拉");
  page=1;
  myScroll.refresh();
 };
 
 
 var page=1;
    var limit=10;
  var jsondata=[
        {'aa':111,'bb':111111},
        {'aa':222,'bb':111111},
        {'aa':333,'bb':111111},
        {'aa':444,'bb':111111},
        {'aa':555,'bb':111111},
        {'aa':666,'bb':111111},
        {'aa':777,'bb':111111},
        {'aa':888,'bb':111111},
        {'aa':999,'bb':111111},
        {'aa':123,'bb':111111},
        {'aa':456,'bb':111111},
        {'aa':789,'bb':111111},
        {'aa':987,'bb':111111},
        {'aa':654,'bb':111111},
        {'aa':321,'bb':111111},
        {'aa':556,'bb':111111},
        {'aa':223,'bb':111111},
        {'aa':112,'bb':111111},
        {'aa':889,'bb':111111},
        {'aa':778,'bb':111111},
        {'aa':998,'bb':111111},
        {'aa':447,'bb':111111},
        {'aa':852,'bb':111111},
        {'aa':741,'bb':111111},
        {'aa':963,'bb':111111},
        {'aa':369,'bb':111111},
        {'aa':258,'bb':111111},
        {'aa':147,'bb':111111},
        {'aa':753,'bb':111111},
        {'aa':159,'bb':111111},
        {'aa':999999,'bb':999999999999},
        {'aa':999,'bb':999999},
        {'aa':9,'bb':999999999},
        {'aa':99,'bb':999999999}
    ];
 var isfirst=true;
 function upajaxload(){//加载处理  
  if(isfirst){
   isfirst=false;
   setTimeout(function(){
    page+=1;
    for(var i=(page-1)*limit;i<(page-1)*limit+limit;i++){
     if(i<jsondata.length){
      $(".demo").append('<div class="list"><p>'+jsondata[i].aa+'</p><p>'+jsondata[i].bb+'</p></div>');
     };
    };
    myScroll.refresh();//刷新结构
    isfirst=true;
   },1000);
  }
 };
  
});
</script>
<style type="text/css">
* {
 -webkit-box-sizing: border-box;
 -moz-box-sizing: border-box;
 box-sizing: border-box;
}
html {
 -ms-touch-action: none;
}
*{
 padding: 0;
 margin: 0;
 border: 0;
}
body {
 font-size: 12px;
 font-family: ubuntu, helvetica, arial;
 overflow: hidden; /* this is important to prevent the whole page to bounce */
}
#header {
 position: absolute;
 z-index: 2;
 top: 0;
 left: 0;
 width: 100%;
 height: 45px;
 line-height: 45px;
 background: #CD235C;
 padding: 0;
 color: #eee;
 font-size: 20px;
 text-align: center;
 font-weight: bold;
}
#footer {
 position: absolute;
 z-index: 2;
 bottom: 0;
 left: 0;
 width: 100%;
 height: 48px;
 background: #444;
 padding: 0;
 border-top: 1px solid #444;
}
#wrapper {
 position: absolute;
 z-index: 1;
 top: 45px;
 bottom: 48px;
 left: 0;
 width: 100%;
 background: #ccc;
 overflow: hidden;
}
#scroller {
 position: absolute;
 z-index: 1;
 -webkit-tap-highlight-color: rgba(0,0,0,0);
 width: 100%;
 -webkit-transform: translateZ(0);
 -moz-transform: translateZ(0);
 -ms-transform: translateZ(0);
 -o-transform: translateZ(0);
 transform: translateZ(0);
 -webkit-touch-callout: none;
 -webkit-user-select: none;
 -moz-user-select: none;
 -ms-user-select: none;
 user-select: none;
 -webkit-text-size-adjust: none;
 -moz-text-size-adjust: none;
 -ms-text-size-adjust: none;
 -o-text-size-adjust: none;
 text-size-adjust: none;
}
#requestf5{position:absolute; width:100px; height:20px; line-height:20px; text-align:center; 
left:50%; margin-left:-50px; top:45px; z-index:2; opacity:0;}
.demo{ background:#FFF;}
.demo .list{ height:200px;}
</style>
</head>
<body>
<div id="header">iScroll</div>
<div id="requestf5">请求刷新</div>
<div id="wrapper">
 <div id="scroller">
  <div class="demo">
         <div class="list">
             <p>1</p>
                <p>1111111</p>
            </div>
            <div class="list">
             <p>2</p>
                <p>222222</p>
            </div>
            <div class="list">
             <p>1</p>
                <p>333333</p>
            </div>
            <div class="list">
             <p>1</p>
                <p>444444444</p>
            </div>
            <div class="list">
             <p>1</p>
                <p>5555555555</p>
            </div>
            <div class="list">
             <p>1</p>
                <p>666666666666</p>
            </div>
            <div class="list">
             <p>1</p>
                <p>777777777</p>
            </div>
            <div class="list">
             <p>1</p>
                <p>888888888</p>
            </div>
            <div class="list">
             <p>1</p>
                <p>9998999</p>
            </div>
            <div class="list">
             <p>1</p>
                <p>9999999999999999</p>
            </div>
        </div>
 </div>
</div>
<div id="footer"></div>
</body>
</html>

非常粗糙的基本结构就出来了!下拉显示刷新操作,其实应该清空重新载入,我没有去模拟

同样显示的刷新提示还可以做非常细致的修饰,我们是可以获取上一步的y值得,与当前值比较,我们在回弹的时候还可以二次修饰变化

上拉提示同下拉添加

同样在显示加载数据的时候我们可以利用css3的处理显示

 四.非常简单的模拟实例下载

 http://www.oschina.net/code/snippet_2352644_51591

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!