自己用原生javascript写的轮播图,面向对象思路,支持移动端手指触屏滑动。分页器圆点可以选择click点击或mouseover鼠标移入时触发。图片滚动用的setInterval,感觉setInterval不太适合做动画、图片滚动这类,不平滑。还是setTimeout或requestAnimateFrame函数做动画效果好。
文档做了移动端兼容,按照7.5rem的视口宽。HTML这个元素的font-size是document.documentElement.clientWidth / 7.5 得出来的,所以rem是动态的。
菜鸟一枚,高手看了别笑话,请多多指正哈。上源码:
先JavaScript:
function carouselFunc(obj){ var list=obj.listPar.getElementsByTagName(obj.btnName); var len=list.length,lim=len-1,i=0; var oriTarget=list[0]; var jg=obj.globalT/obj.step; var timer,autoTimer,timerTo,outWaitT; var t=4000; var luoji=true,flag=false; var startX,startY,endX,endY,nowX,nowY; var offX,offY; if(obj.bow>0){ obj.bow=-obj.bow; } function onceScrollFunc(target){ var j=Number(target.getAttribute("data-index")); var k=Number(oriTarget.getAttribute("data-index")); if(target.className!="active"){ oriTarget.className=""; target.className="active"; oriTarget=target; i=j-1; var oriLoc=obj.parent.offsetLeft; var targetLoc=obj.bow*j; clearInterval(timer); clearInterval(autoTimer); if(targetLoc<oriLoc){ var py=(targetLoc-oriLoc)/obj.step; timer=setInterval(function(){ if(oriLoc>targetLoc){ oriLoc+=py; obj.parent.style.left=oriLoc+"px"; } else{ clearInterval(timer); obj.parent.style.left=targetLoc+"px"; } },jg); }else if(targetLoc>oriLoc){ var py=(targetLoc-oriLoc)/obj.step; timer=setInterval(function(){ if(oriLoc<targetLoc){ oriLoc+=py; obj.parent.style.left=oriLoc+"px"; } else{ clearInterval(timer); obj.parent.style.left=targetLoc+"px"; } },jg); } } } if(obj.c_Or_Mo=="mouseover"){ obj.listPar.onmouseover=function(event){ timerTo=setTimeout(function(){ var e=event||window.event; var target=e.target||e.srcElement; if(target.tagName.toLowerCase()==obj.btnName){ onceScrollFunc(target); } },120); }; obj.listPar.onmouseout=function(event){ var e=event||window.event; var target=e.target||e.srcElement; if(target.tagName.toLowerCase()==obj.btnName){ clearTimeout(timerTo); } }; } else if(obj.c_Or_Mo=="click"){ obj.listPar.onclick=function(event){ var e=event||window.event; var target=e.target||e.srcElement; if(target.tagName.toLowerCase()==obj.btnName){ onceScrollFunc(target); } } } obj.prev.onclick=function(){ if(luoji&&!flag){ luoji=false; clearInterval(autoTimer); clearInterval(timer); clearTimeout(outWaitT); ScrollWidthFunc(0); } } obj.next.onclick=function(){ if(luoji&&!flag){ luoji=false; clearInterval(autoTimer); clearInterval(timer); clearTimeout(outWaitT); ScrollWidthFunc(1); } } function ScrollWidthFunc(dir){ if(dir==1){ list[i].className=""; if(i<lim){ i+=1; }else{ i=0; obj.parent.style.left="0px"; } list[i].className="active"; oriTarget=list[i]; var nowScroll=obj.parent.offsetLeft; var objScroll=nowScroll+obj.bow; var py=obj.bow/obj.step; timer=setInterval(function(){ if(nowScroll>objScroll){ nowScroll+=py; obj.parent.style.left=nowScroll+"px"; } else{ clearInterval(timer); obj.parent.style.left=objScroll+"px"; luoji=true; } },jg); } else{ list[i].className=""; if(i>0){ i-=1; }else{ i=lim; obj.parent.style.left=obj.bow*(len+1)+"px"; } list[i].className="active"; oriTarget=list[i]; var nowScroll=obj.parent.offsetLeft; var objScroll=nowScroll-obj.bow; var py=obj.bow/obj.step; timer=setInterval(function(){ if(nowScroll<objScroll){ nowScroll-=py; obj.parent.style.left=nowScroll+"px"; } else{ clearInterval(timer); obj.parent.style.left=objScroll+"px"; luoji=true; } },jg); } } if(document.documentElement.clientWidth<751){ obj.parent.addEventListener('touchstart',function(event){ if(!flag){ flag=true; clearInterval(autoTimer); clearInterval(timer); clearTimeout(outWaitT); var e=event||window.event; tStart(e); } },false); obj.parent.addEventListener('touchmove',function(event){ var e=event||window.event; e.preventDefault(); tMove(e); },false); obj.parent.addEventListener('touchend',function(event){ var e=event||window.event; tEnd(e); },false); } else{ if(obj.parent.addEventListener){ obj.parent.addEventListener('mousedown',function(event){ if(!flag){ flag=true; clearInterval(autoTimer); clearInterval(timer); clearTimeout(outWaitT); var e=event||window.event; tStart(e); } },false); obj.parent.addEventListener('mousemove',function(event){ var e=event||window.event; e.preventDefault(); tMove(e); },false); obj.parent.addEventListener('mouseup',function(event){ var e=event||window.event; tEnd(e); },false); }else{ obj.parent.attachEvent('onmousedown',function(event){ if(!flag){ flag=true; clearInterval(autoTimer); clearInterval(timer); clearTimeout(outWaitT); var e=event||window.event; tStart(e); } }); obj.parent.attachEvent('onmousemove',function(event){ var e=event||window.event; e.preventDefault(); tMove(e); }); obj.parent.attachEvent('onmouseup',function(event){ var e=event||window.event; tEnd(e); }); } } function tStart(e){ var touch; if(e.type=='touchstart'){ touch=e.targetTouches[0]; }else{ touch=e; } startX=touch.pageX; startY=touch.pageY; offX=obj.parent.offsetLeft; offY=obj.parent.offsetTop; } function tMove(e){ if(flag){ var touch; if(e.type=='touchmove'){ touch=e.targetTouches[0]; }else{ touch=e; } nowX=touch.pageX-startX; nowY=touch.pageY-startY; obj.parent.style.left=(offX+nowX)+"px"; } } function tEnd(e){ var touch; if(e.type=='touchend'){ touch=e.changedTouches[0]; }else{ touch=e; } endX=touch.pageX; var distance=obj.parent.offsetLeft; var s=Math.abs(endX-startX); var judge=Math.abs(obj.bow*0.2); var lu=Math.abs(obj.bow)-s; var py=Math.abs(obj.bow/obj.step); if(luoji){ luoji=false; if(s>judge){ if(distance<offX){ list[i].className=""; if(i<lim){ i+=1; var objDis=obj.bow*(Math.floor(Math.abs(distance)/Math.abs(obj.bow))+1); }else{ obj.parent.style.left=-s+"px"; distance=-s; var objDis=obj.bow; i=0; } list[i].className="active"; oriTarget=list[i]; flag=false; timer=setInterval(function(){ if(distance>objDis){ distance-=py; obj.parent.style.left=distance+"px"; }else{ clearInterval(timer); obj.parent.style.left=objDis+"px"; luoji=true; if(e.type=='touchend'){ clearInterval(autoTimer); play(4000,1); } } },jg); }else{ list[i].className=""; if(i>0){ i-=1; var objDis=obj.bow*(Math.floor(Math.abs(distance)/Math.abs(obj.bow))); }else{ obj.parent.style.left=(obj.bow*(len+1)+s)+"px"; distance=obj.bow*(len+1)+s; var objDis=obj.bow*len; i=lim; } list[i].className="active"; oriTarget=list[i]; flag=false; timer=setInterval(function(){ if(distance<objDis){ distance+=py; obj.parent.style.left=distance+"px"; }else{ clearInterval(timer); obj.parent.style.left=objDis+"px"; luoji=true; if(e.type=='touchend'){ clearInterval(autoTimer); play(4000,0); } } },jg); } }else{ var targetP=obj.bow*(Math.floor(Math.abs(offX)/Math.abs(obj.bow))); if(distance<targetP){ timer=setInterval(function(){ if(distance<targetP){ distance+=py; obj.parent.style.left=distance+"px"; }else{ clearInterval(timer); obj.parent.style.left=targetP+"px"; luoji=true; if(e.type=='touchend'){ clearInterval(autoTimer); play(4000,1); } } },jg); }else{ timer=setInterval(function(){ if(distance>targetP){ distance-=py; obj.parent.style.left=distance+"px"; }else{ clearInterval(timer); obj.parent.style.left=targetP+"px"; luoji=true; if(e.type=='touchend'){ clearInterval(autoTimer); play(4000,1); } } },jg); } } } else{ var targetP2=(i+1)*obj.bow; flag=false; if(targetP2<distance){ timer=setInterval(function(){ if(distance>targetP2){ distance-=py; obj.parent.style.left=distance+"px"; }else{ clearInterval(timer); obj.parent.style.left=targetP2+"px"; luoji=true; if(e.type=='touchend'){ clearInterval(autoTimer); play(4000,1); } } },jg) }else{ timer=setInterval(function(){ if(targetP2>distance){ distance+=py; obj.parent.style.left=distance+"px"; }else{ clearInterval(timer); obj.parent.style.left=targetP2+"px"; luoji=true; if(e.type=='touchend'){ clearInterval(autoTimer); play(4000,0); } } },jg) } } } obj.viewport.onmouseover=function(){ clearInterval(autoTimer); clearTimeout(outWaitT); } obj.viewport.onmouseout=function(event){ outWaitT=setTimeout(function(){ play(4000,1); },1000); }; function play(t,i){ autoTimer=setInterval(function(){ if(luoji){ luoji=false; ScrollWidthFunc(i); } },t); } play(4000,1); }
然后上HTML:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"> <script type="text/javascript"> var viWidth=document.documentElement.clientWidth; if(viWidth<750){ document.documentElement.style.fontSize=viWidth/7.5+"px"; }else{ document.documentElement.style.fontSize="100px"; } </script> <title>轮播图移动端试验</title> <style type="text/css"> html{ height:100%; text-align: center; } body{ width:7.5rem; height:100%; margin:0 auto; text-align: center; } .clearfix:after{ content:""; display: block; clear: both; height:0px; } .clearfix{ zoom:1; } .myTitle{ margin:0px; line-height:0.6rem; height:0.6rem; padding-top:0.2rem; padding-bottom:0.2rem; text-align:center; } .carousel1{ width:7rem; height:3.5rem; margin-left:auto; margin-right:auto; position: relative; overflow:hidden; } .viewportA{ width:7rem; height:3.5rem; position: relative; overflow: hidden; z-index: 1; } .parentA{ width:1000%; position: absolute; } .parentA .item{ float:left; position: relative; width:7rem; height:3.5rem; margin:0px; display:inline; cursor: pointer; } .parentA .item img{ display: block; width:7rem; height:3.5rem; } .carousel1 .prevA{ position:absolute; height:10%; width:auto; left:0; top:45%; z-index:3; opacity:0.4; cursor: pointer; } .carousel1 .nextA{ position:absolute; height:10%; width:auto; right:0; top:45%; z-index:3; opacity:0.4; cursor: pointer; } .carousel1 .prevA:hover { opacity:0.9; } .carousel1 .nextA:hover { opacity:0.9; } .circleListA{ position:absolute; z-index: 3; bottom:0.2rem; width:1.05rem; height:0.15rem; left:50%; margin-left:-0.525rem; padding-top:0.03rem; padding-bottom:0.03rem; zoom:1; background-color:rgba(255,255,255,0.5); border-radius:0.1rem; } .circleListA span{ float:left; height:0.15rem; width:0.15rem; border-radius:70%; margin-right:0.05rem; background-color:white; cursor: pointer; } .circleListA span:hover{ background:#ffd700; } .circleListA .active{ background:#ff4500!important; } </style> </head> <body> <h1 class="myTitle"></h1> <div class="carousel1" id="carousel1"> <div class="viewportA" id="viewportA"> <div id="parentA" class="parentA clearfix" style="left:-7rem"> <div class="item"><img src="image/5.jpg" width="100%"></div> <div class="item"><img src="image/1.jpg" width="100%"></div> <div class="item"><img src="image/2.jpg" width="100%"></div> <div class="item"><img src="image/3.jpg" width="100%"></div> <div class="item"><img src="image/4.jpg" width="100%"></div> <div class="item"><img src="image/5.jpg" width="100%"></div> <div class="item"><img src="image/1.jpg" width="100%"></div> </div> </div> <img src="image/btn-left.png" id="prevA" class="prevA" alt="点击->上一张"> <img src="image/btn-right.png" id="nextA" class="nextA" alt="点击->下一张"> <div id="circleListA" class="circleListA clearfix"> <span data-index="1" class="active" style="margin-left:0.05rem"></span> <span data-index="2" class=""></span> <span data-index="3" class=""></span> <span data-index="4" class=""></span> <span data-index="5" class=""></span> </div> </div> <script type="text/javascript" src="carousel-oop.js" charset="UTF-8"></script> <script type="text/javascript"> if(window.addEventListener){ window.addEventListener("load",function(){ var carouselObj1={}; carouselObj1.carouselCon=document.getElementById("carousel1"); carouselObj1.viewport=document.getElementById("viewportA"); carouselObj1.parent=document.getElementById("parentA"); carouselObj1.listPar=document.getElementById("circleListA"); carouselObj1.btnName="span"; carouselObj1.prev=document.getElementById("prevA"); carouselObj1.next=document.getElementById("nextA"); carouselObj1.globalT=500; carouselObj1.step=50; carouselObj1.c_Or_Mo='mouseover'; carouselObj1.bow=-viewportA.clientWidth; carouselFunc(carouselObj1); },false); }else if(window.attachEvent){ window.attachEvent("onload",function(){ var carouselObj1={}; carouselObj1.carouselCon=document.getElementById("carousel1"); carouselObj1.viewport=document.getElementById("viewportA"); carouselObj1.parent=document.getElementById("parentA"); carouselObj1.listPar=document.getElementById("circleListA"); carouselObj1.btnName="span"; carouselObj1.prev=document.getElementById("prevA"); carouselObj1.next=document.getElementById("nextA"); carouselObj1.globalT=500; carouselObj1.step=50; carouselObj1.c_Or_Mo='mouseover'; carouselObj1.bow=-viewportA.clientWidth; carouselFunc(carouselObj1); }); } </script> </body> </html>