老规矩~ 上DEMO,过过瘾先:纵向图片滚动(不过这个demo须要你在手机中查看啦~)node
再上源码:纵向滚动图片git
DEMO很简单,左侧有个纵向的图片数量以及当前图片索引的展现,而后整个是一个纵向可触摸滑动的列表,能够自定义滑动回调函数。github
首先图片确定是纵向排列的了app
就像下边这张图同样dom
灰色方块就是一堆纵向排列的图片ide
红色方框中的是显示区域,溢出隐藏函数
而后在动态改变方框内部的div的top值来切换显示在方框中的不一样图片~ui
首先初始化容器高度,以及添加纵向的控制条this
LONG_DISTANCE = nelsonVS.minHeight / 2; for(var i = 0 ; i < nelsonVS.lis.length ; i++){ nelsonVS.lis[i].style.height = nelsonVS.minHeight + "px"; } nelsonVS.ul.style.height = nelsonVS.num * nelsonVS.minHeight + "px"; var prograssBarDom = document.createElement("ul"); prograssBarDom.className = "prograssBar"; var fragment = document.createDocumentFragment(); for(var i = 0,linode = "" ; i < nelsonVS.num ; i ++){ linode = document.createElement("li"); linode.className = "prograssBarItem" + (i==0?" active":""); fragment.appendChild(linode); } prograssBarDom.appendChild(fragment); nelsonVS.dom.appendChild(prograssBarDom); nelsonVS.prograssBar = prograssBarDom.children; prograssBarDom = null;fragment = null; this.slide(); return this; }
而后,绑定滚动的事件spa
绑定touchstart记录手指开始触摸的位置
绑定touchmove实时更新手指触摸点位于屏幕的位置,并使图片容器随着手指滚动
绑定touchend更新手指离开时候的位置,并根据位置来判断是是将图片归位不进行滚动,仍是滚动到下一张/上一张图片(触发临界值可自行设定)
var STARTY,ENDY,EVENT_TYPE,START_POS,that = this,TIMESTAMP,TIMESTAMP_END; nelsonVS.dom.addEventListener("touchstart",function(e){ e.preventDefault(); TIMESTAMP = (new Date()).valueOf(); START_POS = nelsonVS.ul.offsetTop; STARTY = e.touches[0].clientY; if(that.moveInterval){ clearInterval(that.moveInterval); } }) nelsonVS.dom.addEventListener("touchmove",function(e){ e.preventDefault(); ENDY = e.targetTouches[0].clientY; nelsonVS.ul.style.top = START_POS + ENDY - STARTY + "px"; }) nelsonVS.dom.addEventListener("touchend",function(e){ e.preventDefault(); TIMESTAMP_END = (new Date()).valueOf(); var DIS = ENDY - STARTY; if(DIS > DISTANCE){ EVENT_TYPE = "DOWN"; }else if(DIS < -DISTANCE){ EVENT_TYPE = "UP"; } if(Math.abs(DIS) > DISTANCE){ if(TIMESTAMP_END - TIMESTAMP < SENSIBILITY){ that.checkAction(EVENT_TYPE); }else{ if(Math.abs(DIS) > LONG_DISTANCE){ that.checkAction(EVENT_TYPE); }else{ that.action(EVENT_TYPE); } } }else{ that.action(); } })
检测滑动方向以及临界值判断
if((et == "UP" && (nelsonVS.index - 1) <= -nelsonVS.num) || (et == "DOWN" && (nelsonVS.index + 1) > 0)){ this.action(); return; } switch(et){ case 'UP': nelsonVS.isSliding = true; nelsonVS.index--; this.action(et); break; case 'DOWN': nelsonVS.index++; nelsonVS.isSliding = true; this.action(et); break; default: this.action(); } }
进行滚动处理
var AIM_POS = nelsonVS.minHeight * nelsonVS.index; var DIS = AIM_POS - nelsonVS.ul.offsetTop; var speed = (DIS) / 3; var that = this; that.moveInterval = setInterval(function(){ nelsonVS.ul.style.top = nelsonVS.ul.offsetTop + speed + "px"; if(Math.abs(AIM_POS - nelsonVS.ul.offsetTop) < speed || Math.abs(speed) <= 0.5){ nelsonVS.ul.style.top = AIM_POS + "px"; speed = (DIS) / 3; if(et){ var para = {}; para.index = -nelsonVS.index; para.item = nelsonVS.lis[para.index]; if(that.onSlideCallBack){ that.onSlideCallBack(para); if(that.onSlideUpCallBack||that.onSlideDownCallBack){ console.error("在设置滚动回调的时候不可同时设置单向滚动回调") } }else{ if(that.onSlideUpCallBack && et == "UP"){ that.onSlideUpCallBack(para); } if(that.onSlideDownCallBack && et == "DOWN"){ that.onSlideDownCallBack(para); } } } that.changePrograssBar(); clearInterval(that.moveInterval); nelsonVS.isSliding = false; }else{ speed = (AIM_POS - nelsonVS.ul.offsetTop) / 5; } },10)
更新控制条的当前索引值位置
for(var i = 0 ; i < nelsonVS.prograssBar.length ; i++){ if(nelsonVS.prograssBar[i].classList.contains("active")){ nelsonVS.prograssBar[i].classList.remove("active"); break; } } nelsonVS.prograssBar[-nelsonVS.index].classList.add("active");
其余就是一些回调函数啦~