js原生选项卡(包含移动端无缝选项卡)三
今天分享下移动端原生js的无缝轮播图;
移动端尽量减少使用DOM操作来频繁的浪费移动端设备的性能,所以这个无缝轮播图更多的使用了transition和transform,无缝的思想和昨天分享的PC端的无缝轮播的思想是一样的,分别在正常的图片的前面插入了最后一张图片和在正常图片的最后插入了第一张图片,在运动到这两张图片时候瞬间清除transition并把整个图片链拉回到正常图片流的位置,从而从产生了无缝
这个移动端轮播图中还阐述了一个思路:为了更好的考虑用户的体验,当用户滑动屏幕的距离小于一定的值得时候我们图片并不会更换到下一张,这个效果的产生得益于流程控制if判断用户按下手指和抬起手指的坐标差的值
相同的今天的例子中也使用了开关的概念,具体思路昨天的文章中已经阐述
今天的例子以640的分辨率为基准,并在js动态的改变onresize时候值,使我们的代码满足不同手机的尺寸
The best preparation for tomorrow is doing your best today.
过好今天,是对明天最好的准备
html代码:
<div id="tabs"> <ul> <li style="background:pink;">3</li> <li style="background:red;">0</li> <li style="background:green;">1</li> <li style="background:yellow;">2</li> <li style="background:pink;">3</li> <li style="background:red;">0</li> </ul> </div>
css代码:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="format-detection" content="telephone=no,email=no"> <style> *{ padding: 0; margin: 0; list-style:none; } html{ font-size:20px; } #tabs ul{ width: 96rem; height: 100%; overflow:hidden; transform:translateX(-16rem); } #tabs ul li{ width: 16rem; height: 7.5rem; float:left; font-size:3rem; color:#fff; text-align:center; line-height:7.5rem; }
js代码:
//以640的分辨率为基准分辨率设置的css模型尺寸,闭包中的代码为实时改变单位尺寸 (function(window,document){ function change(){ var oHTML=document.getElementsByTagName('html')[0]; oHTML.style.fontSize=20*document.documentElement.clientWidth/320+'px'; } change(); window.addEventListener('resize',change,false); })(window,document); document.addEventListener('DOMContentLoaded',function(){ var oTab=document.getElementById('tabs'); var oUl=oTab.getElementsByTagName('ul')[0]; var aLi=oUl.children; var iNow=1; var x=-aLi[0].offsetWidth*iNow; //设置开关 var bReady=false; oUl.addEventListener('touchstart',function(ev){ if(bReady){return;} bReady=true; oUl.style.transition='none'; //当开始触摸的时候记录按下的坐标 var downX=ev.targetTouches[0].pageX; var disX=downX-x; function fnMove(ev){ //在move的时候重新计算位移,并给ul赋值 x=ev.targetTouches[0].pageX-disX; oUl.style.transform='translateX('+x+'px)'; } function fnEnd(ev){ document.removeEventListener('touchmove',fnMove,false); document.removeEventListener('touchend',fnEnd,false); //在抬起的时候记录抬起的位置,注意抬起的位置是changedTouches[0] var upX=ev.changedTouches[0].pageX; //开启transition oUl.style.transition='0.4s all ease'; //这里为了用户体验,判断了一个最小移动距离,当移动距离小于这个值得时候并不发生运动 if((Math.abs(upX-downX))>50){ //判断移动方向,是向右还是向左 if(downX>upX){ iNow++; //设置移动范围 if(iNow==aLi.length) iNow=aLi.length-1; }else{ //和右面是相反的 iNow--; if(iNow==-1) iNow=0; } } //进行赋值 x=-aLi[0].offsetWidth*iNow; oUl.style.transform='translateX('+x+'px)'; //设置ul的变化 function tEnd(){ //为了不让瞬间拉回被发现,首先要清除transition oUl.style.transition='none'; //进行无缝判断,当图片到右面倒数第二张的时候拉回到第二张 if(iNow==aLi.length-1){ iNow=1; }else if(iNow==0){ //当图片运动到第一张的时候瞬间拉回到倒数第三张 iNow=aLi.length-2; } x=-aLi[0].offsetWidth*iNow; oUl.style.transform='translateX('+x+'px)'; bReady=false; } oUl.addEventListener('transitionend',tEnd,false); } document.addEventListener('touchmove',fnMove,false); document.addEventListener('touchend',fnEnd,false); ev.preventDefault(); },false); },false); </script>