一.准备环节
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.二次封装处理
我们问题在哪里?拿下拉举例子,就是只要下拉就打印日志,这是不符合逻辑的,应该是
判断出下拉或者上拉 事件
在下拉或者上拉结束打印日志或者处理
我们删除开始事件,这个已经不用,
我们创建表示上拉和下拉的变量,然后在结束时间根据标志去做判断处理,代码修改如下:
<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
来源:oschina
链接:https://my.oschina.net/u/2352644/blog/519259