zl程序教程

您现在的位置是:首页 >  后端

当前栏目

使用原生js封装webapp滑动效果(惯性滑动、滑动回弹)

JS封装 使用 效果 原生 滑动 惯性 webapp
2023-06-13 09:15:26 时间

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>