使用原生js封装webapp滑动效果(惯性滑动、滑动回弹)
PC移动端兼容 IE6.0+,FF1.5+,Safari2.0+,Opera9.0+惯性助动,滑动回弹
门面模式
window.onload=function(){
/*测试数据*/
varinsert="";
for(vari=0;i<80;i++){
insert+="<divstyle="width:100%;text-align:center;">滑动测试"+i+"</div>";
}
document.getElementById("moveArea").innerHTML=insert;
/*测试数据 */
varat=newappTouch({
tContain:"appArea",//必选:滑动区域id
tMove:"moveArea",//必选:移动区域id
tScroller:"scroller",//必选:自定义滚动条
tScrollerArea:"scrollerArea"//必选:滚动条区域
},onmoveend);
//到顶/底回调
functiononmoveend(m){
//console.log(m);
}
}
/*=====================
*名称:appTouch
*功能:webapp滑动模拟组件
*参数:相关配置
======================*/
varappTouch=function(config,callback){
this.touchContain=config.tContain;
this.touchMove=config.tMove;
this.touchScroller=config.tScroller;
this.touchScrollerArea=config.tScrollerArea;
this.callbackfn=callback;
this.move();
}
appTouch.prototype={
move:function(e){
varmonitor=document.getElementById(this.touchContain),//监听容器
target=document.getElementById(this.touchMove),//移动目标
scroller=document.getElementById(this.touchScroller),//自定义滚动条
scrollerArea=document.getElementById(this.touchScrollerArea),//滚动条区域
sheight=monitor.offsetHeight/target.offsetHeight*monitor.offsetHeight,//自定义滚动条的长度
st=(target.offsetHeight-monitor.offsetHeight)/(monitor.offsetHeight-sheight),//移动块对应滚轮单位长度
tslow=4,//到顶/底减基数
tMove=0,//滑块到顶top值
tMoveL=tMove+140,//到顶允许下拉范围
bMove=monitor.offsetHeight-target.offsetHeight,//滑块到底top值
bMoveL=bMove-140,//到底允许上滑范围
callbackfn=this.callbackfn,//回调函数
flg=false,//标记是否滑动
startY,//标记起始位置
startTop,//标记滑动起始时的高度值
move=0;
//移动距离
//鼠标事件注册
addEvent(monitor,"mousedown",moveStart);
addEvent(monitor,"mousemove",moveIn);
addEvent(monitor,"mouseup",moveEnd);
addEvent(window,"mousemove",moveIn);
addEvent(window,"mouseup",moveEnd);
//移动设备触摸事件注册
addEvent(monitor,"touchstart",moveStart);
addEvent(monitor,"touchmove",moveIn);
addEvent(monitor,"touchend",moveEnd);
/**
*外观/门面模式包装
*/
/*事件监听*/
functionaddEvent(el,type,fn){
if(el.addEventListener){
el.addEventListener(type,fn,false);
}elseif(el.attachEvent){
el.attachEvent("on"+type,fn);
}else{
el["on"+type]=fn;
}
}
//取消浏览器默认行为
functionstop(e){
//Opera/Chrome/FF
if(e.preventDefault)
e.preventDefault();
//IE
e.returnValue=false;
}
//包装结束
/**
*操作函数
*/
//惯性缓动参数
varlastMoveTime=0;
varlastMoveStart=0;
varstopInertiaMove=false;
/*移动触发*/
functionmoveStart(e){
stop(e);
flg=true;
if(e.touches)
e=e.touches[0];
startY=e.clientY;
startTop=target.style.top||0;
//惯性缓动
lastMoveStart=startY;
lastMoveTime=newDate().getTime();
stopInertiaMove=true;
scrollerArea.style.visibility="visible";
}
/*移动过程中*/
functionmoveIn(e){
if(flg){
stop(e);
if(e.touches)
e=e.touches[0];
move=e.clientY-startY+parseInt(startTop);
if(move>tMove){
(move-tMove)/tslow+tMove>tMoveL?move=tMoveL:move=(move-tMove)/tslow+tMove
}elseif(move<bMove)
(move-bMove)/tslow+bMove<bMoveL?move=bMoveL:move=(move-bMove)/tslow+bMove;
target.style.top=move+"px";
scroller.style.top=-move/st+"px";
//惯性缓动
varnowTime=newDate().getTime();
stopInertiaMove=true;
if(nowTime-lastMoveTime>300){
lastMoveTime=nowTime;
lastMoveStart=e.clientY;
}
}
}
/*移动结束*/
functionmoveEnd(e){
stop(e);
if(e.touches)
e=e.touches[0];
//惯性缓动
varcontentTop=target.style.top.replace("px","");
varcontentY=(parseInt(contentTop)+e.clientY-lastMoveStart);
varnowTime=newDate().getTime();
varv=(e.clientY-lastMoveStart)/(nowTime-lastMoveTime);
//最后一段时间手指划动速度
stopInertiaMove=false;
(function(v,startTime,contentY){
vardir=v>0?-1:1;
//加速度方向
vardeceleration=dir*0.005;
functioninertiaMove(){
if(stopInertiaMove)
return;
varnowTime=newDate().getTime();
vart=nowTime-startTime;
varnowV=v+t*deceleration;
varmoveY=(v+nowV)/2*t;
//速度方向变化表示速度达到0了
if(dir*nowV>0){
if(move>tMove){
callbackfn("到顶了");
target.style.top=tMove+"px";
scroller.style.top=tMove+"px";
}elseif(move<bMove){
callbackfn("到底了");
target.style.top=bMove+"px";
scroller.style.top=-bMove/st+"px";
}
setTimeout(function(){
if(!stopInertiaMove)
scrollerArea.style.visibility="hidden";
},4000);
return;
}
move=contentY+moveY;
if(move>tMove){
t/=20;
move=(move-tMove)/10+tMove;
}elseif(move<bMove){
t/=20;
move=(move-bMove)/10+bMove;
}
target.style.top=move+"px";
scroller.style.top=-move/st+"px";
setTimeout(inertiaMove,10);
}
inertiaMove();
})(v,nowTime,contentY);
move=0;
flg=false;
}
//操作结束
/**
*相关初始化
*/
//滚动条长度初始化
scroller.style.height=sheight+"px";
//初始化结束
},
otherInteract:function(){
//其他功能扩充
}
}
IEhackcss
body,html{background-color:#333;margin:0;height:100%;line-height:2.0;font-family:"MicrosoftYaHei";overflow-y:hidden;}
#contain{margin:0auto;position:relative;width:100%;max-width:480px;_width:480px;height:100%;cursor:pointer!important;}
#appArea{position:absolute;width:100%;height:100%;overflow:hidden; background-color:#fff;}
#topInfo{position:absolute;top:60px;width:100%;height:60px;text-align:center;font-size:18px;}
#bottomInfo{position:absolute;bottom:0;width:100%;}
#scrollerArea{position:absolute;right:0;width:1.5%;height:100%;visibility:hidden;}
#scroller{position:absolute;top:0;width:100%; background-color:#aaa;}
#moveArea{position:absolute;top:0px;width:100%;background-color:#ddd;}
HTML代码
<!DOCTYPEhtml>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/>
<metaname="viewport"content="width=device-width,initial-scale=1.0,user-scalable=no">
<linktype="text/css"href="css/main.css"rel="stylesheet">
<title>滑动回弹</title>
<!--[ifltIE9]> <![endif]-->
<noscript></noscript>
</head>
<body>
<divid="contain">
<divid="appArea">
<divid="topInfo">
logooranimate
</div>
<divid="bottomInfo">
someimformation 2014-4-28
</div>
<divid="moveArea"></div>
<divid="scrollerArea">
<divid="scroller"></div>
</div>
</div>
</div>
<scriptsrc="js/main.js"></script>
</body>
</html>
相关文章
- 使用 Dapr JS SDK 让 Nest.js 集成 Dapr(微软开源的分布式应用程序运行时)
- html如何只刷新页面指定,js控制页面刷新 JS刷新当前页面的几种方法总结
- JS面试题-js新增基本数据类型BigInt
- 将JS嵌入C++ ————Spidermonkey引擎的使用「建议收藏」
- 牛客网js题库正解 (21-40题)
- 如何使用jscythe并通过Node.js的Inspector机制执行任意JS代码
- JS循环练习-简易银行ATM
- 【源码】PDF.js批注注释插件库(纯JS). 创建和保存PDF批注(PDF 高亮/签名/插图/截屏/文本框/画笔/多边形)-pdf.js
- JS中的 async 和 await 使用技巧
- JS动态引入js、CSS动态创建script/link/style标签详解编程语言
- 创建JS文件:在Linux下实现自动化任务(linux创建js文件)
- 快速掌握JS操作MySQL数据库技巧(js操作mysql数据库)
- 使用 JS 操作 Redis:实现强大数据存储.(js调用redis)
- 使用JS在网页中连接Oracle数据库(js网页链接oracle)
- 使用JS操作Oracle数据库探索潜在可能性(js和oracle数据库)
- Oracle中使用JS变量管理数据(oracle使用js变量)
- 动态样式类封装JS代码
- js数据验证集合、jsemail验证、jsurl验证、js长度验证、js数字验证等简单封装
- js截取函数(indexOf,join等)
- JS函数验证总结(方便js客户端输入验证)
- js判断上传文件的类型和大小示例代码
- js判断数据类型如判断是否为数组是否为字符串等等
- js中arguments,caller,callee,apply的用法小结
- js函数模拟显示桌面.scf程序示例
- js实现遮罩层弹出框的方法
- js封装可使用的构造函数继承用法分析