在前端頁面開發過程中,頁面中的輪播圖特效很常見,因此我就想封裝一個自己的原生JS的輪播圖組件。之前自己寫pc端的比較多,也沒有用面向對象的方式來寫,沒寫過移動端,因為要考慮很多,最近花了三天才完成了移動端輪播,都快寫瘋了。
主要的功能有:自動輪播,點擊某一張圖片對應的小圓點就跳轉到指定圖片,還可以自定義每張圖輪播的延時,不過延時參數不是必須的參數,可以不指定延時,使用默認延時。
/** * Created by shentao on 2018/2/10. */ (function(){ //定義一個公共函數,方便獲取dom元素 function $_(name){ return document.querySelectorAll(name); } var mslider=function(option){ //設置默認參數 this.defaultopt={ slideCell:".wrap", mainCell:".box", interTime:1000, autoPlay:false//自動播放 } //判斷傳入的opts是否有默認參數中的值,如果默認參數值不存在opts中 //就把默認參數加進opts中,這樣就不會把默認參數修改了 option=option||this.defaultopt; for(var k in this.defaultopt){ if(!option[k]){ option[k]=this.defaultopt[k]; } } this.option=option; this.timer=null;//定義一個定時器變量 this.wrap=$_(this.option.slideCell)[0];//最外層容易,顯示當前的圖片 this.box=$_(this.option.mainCell)[0];//輪播圖片的包裹層 this.ali=$_(this.option.mainCell+" li");//輪播圖片集合 this.len=this.ali.length;//輪播圖片的數目 this.aliWidth=parseInt(getComputedStyle(this.wrap).width);//每個圖片的寬度 this.aliHeight=parseInt(getComputedStyle(this.ali[0]).height);//每個圖片的告訴 this.iNow=0;//當前顯示第幾張圖片 this.int();//執行初始化函數 } mslider.prototype={ constructor:mslider, int:function(){ var _this=this; this.createNode(); this.addEvent(); if(this.option.autoPlay==true){ this.timer=setInterval(_this.auto_play(),this.option.interTime) } this.create_page();//自動分頁 }, //包裹曾頭部尾部增加一個節點,方便實現無縫切換,做一些初始化樣式設置 createNode:function(){ var _this=this; var nodeBefore=this.ali[0].cloneNode(true); var nodeAfter=this.ali[this.len-1].cloneNode(true); _this.box.appendChild(nodeBefore); _this.box.insertBefore(nodeAfter,this.ali[0]); this.newLen=$_(this.option.slideCell+" >ul li").length; this.box.style.cssText="width:"+this.newLen*this.aliWidth+"px;"+"position:absolute;"+" left:"+(-this.aliWidth)+"px"; this.wrap.style.cssText="height:"+this.aliHeight+"px"; for(var i=0;i<this.newLen;i++){ var oli=$_(this.option.mainCell)[0].children[i]; oli.style.cssText="float:left;"+"width:"+this.aliWidth+"px"; } }, //創建 create_page:function(){ var _this=this; //生成自動分頁的導航 if(this.option. autoPage==true){ var ali=""; for(var i=0;i<this.len;i++){ ali+="<li>"+(i+1)+"</li>"; } var oul=$_(this.option.titCell)[0]; oul.innerHTML=ali; } this.tit=$_(this.option.titCell+" li"); this.tit[_this.iNow].className="on"; for(var i=0;i<this.tit.length;i++){ this.tit[i].pos=i; this.tit[i].onclick=function(){ clearInterval(_this.timer); var currNum=this.pos; var dir=currNum-_this.iNow; if(_this.state==true){ _this.handle(); } else{ _this.startOffset=_this.box.offsetLeft; } _this.animate(-_this.aliWidth*dir); _this.iNow=currNum; } } }, //處理動畫沒有結束滑動的bug handle:function(){ var _this=this; clearInterval(_this.transition); _this.endX=_this.endX<=-(_this.newLen-1)*_this.aliWidth?-(_this.aliWidth):_this.endX; _this.endX=_this.endX>=0?-(_this.newLen-2)*_this.aliWidth:_this.endX; _this.startOffset=_this.endX; } , //添加滑動事件 addEvent:function(){ var _this=this;var startX=0;this.startOffset=-_this.aliWidth;var movex=0;this.endX=0;this.state=false; _this.wrap.addEventListener("touchstart",start,false); _this.wrap.addEventListener("touchmove",move,false); _this.wrap.addEventListener("touchend",end,false); function start(e){ var e=e||window.event; clearInterval(_this.timer); if(_this.state==true){ _this.handle(); } else{ clearInterval(_this.transition); startX= e.touches[0].clientX; _this.startOffset=_this.box.offsetLeft; } } function move(e){ var e=e||window.event; _this.movex= e.touches[0].clientX-startX; _this.box.style.left=_this.startOffset+_this.movex+"px"; } function end(e){ var left = _this.box.offsetLeft; var currNum = left/_this.aliWidth; var pointX=left%_this.aliWidth; if(_this.movex<0){ if(Math.abs(_this.movex)<30){ _this.animate(0) } else{ _this.animate(-_this.aliWidth) } } else{ if(Math.abs(_this.movex)<30){ _this.animate(0) } else{ _this.animate(_this.aliWidth) } } } }, //封裝一個動畫函數 animate:function(offset){ var _this=this;var interval=10;_this.state=true;_this.endX=_this.startOffset+offset; var offsetX=(_this.endX-_this.startOffset)/this.aliWidth; _this.tit[_this.iNow].className=""; _this.iNow-=offsetX; _this.iNow=_this.iNow>=this.len?0:_this.iNow; _this.iNow=_this.iNow<0?4:_this.iNow; _this.tit[_this.iNow].className="on"; _this.transition=setInterval(move,10); function move(){ var speed=(_this.endX-_this.box.offsetLeft)/20; speed=speed>0?Math.ceil(speed):Math.floor(speed); if(parseInt(_this.box.style.left)==-(_this.newLen-1)*_this.aliWidth){ _this.box.style.left=-(_this.aliWidth)+"px"; _this.endX=-(_this.aliWidth); } if(parseInt(_this.box.style.left)==0){ _this.box.style.left=-(_this.newLen-2)*_this.aliWidth+"px"; _this.endX=-(_this.newLen-2)*_this.aliWidth; } _this.box.style.left=_this.box.offsetLeft+speed+"px"; if(speed==0){ clearInterval(_this.transition); if(_this.option.autoPlay==true){ clearInterval(_this.timer); _this.timer=setInterval(_this.auto_play(),_this.option.interTime) } _this.box.style.left=_this.endX+"px"; _this.state=false; } } }, //設置自動播放 auto_play:function(){ var _this=this; return function(){ clearInterval(_this.timer); _this.startOffset=_this.box.offsetLeft; _this.animate(-_this.aliWidth); } } } window.mslider=mslider;//暴露給全局,方便調用 })();
下面是html結構
<div> <h2 class="title">手機端輪播實現</h2> <div class="wrap"> <ul class="clearfix box"> <li><img src="image/f1.jpg" alt=""></li> <li><img src="image/f2.jpg" alt=""></li> <li><img src="image/f3.jpg" alt=""></li> <li><img src="image/f4.jpg" alt=""></li> <li><img src="image/f5.jpg" alt=""></li> </ul> </div> <div class="hd"> <ul> </ul> </div> </div> <script> new mslider({ slideCell:".wrap", titCell:".hd ul", mainCell:".box", interTime:3000, autoPlay:false, //自動播放 autoPage:true,//自動分頁 }); </script>
附上我的demo github地址,https://github.com/shentaochok/mslider.git,並沒有css,我都寫在了js里面,可以直接調用。
