原生js面向對象實現簡單輪播
平時中我習慣用jquery寫輪播效果,實現過程不是很難,也很方便,為了加深對js面向對象的理解,我打算用面向對象實現一個簡單的輪播,這裏采用了字面量的方式實現。為了實現這個過程,我們要自己動手封裝一個運動函數animate,在這裏我采用的是勻速運動的方式,這種方式可能體驗不是很好,後面分析js代碼我在詳細解釋。廢話不多說,先上代碼。頁面布局可以根據自己的習慣來。
html代碼:
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="./css/slide .css"> <script src="./js/slide.js"></script> </head> <body> <div class="slide"> <ul class="img-box"> <li> <img src="./img/1.jpg" > </li> <li> <img src="./img/2.jpg" > </li> <li> <img src="./img/3.jpg" > </li> <li> <img src="./img/4.jpg" > </li> <li> <img src="./img/5.jpg" > </li> <div class="clear"></div> </ul> <div class="icon"> <span class="on"></span> <span></span> <span></span> <span></span> <span></span> </div> </div> </body> </html>
css代碼:
*{ padding:0; margin: 0; list-style-type: none; text-decoration: none; } .clear{ clear: both; } a:hover{ text-decoration: none; } .slide{ position: relative; width: 500px; height: 300px; margin:20px auto; overflow: hidden; } .slide .img-box{ width: 10000px; position: absolute; left: 0; top: 0; } .slide .img-box li{ float: left; width: 500px; height: 300px; } .slide .img-box li img{ width:100%; height: 100%; } .icon{ position: absolute; right:8%; bottom: 6%; } .icon span{ display: block; float: left; width: 15px; height: 15px; border-radius: 50%; background: white; opacity: 0.7; margin-left: 5px; } .icon .on{ background: orange; opacity: 0.7; }
js代碼:
window.onload = function () { function animate(ele, xTarget, time) { var xPos = ele.offsetLeft, //每次執行一次運動得到ele元素相對於父容器左邊界偏移的距離。 speed = 25; //勻速運動的速度 if (Math.abs(xTarget - xPos) <= speed) {//接近目標位置時候進行矯正,因為移動的距離不一定是speed的整數倍,矯正後終止animate的執行。 xPos = xTarget; ele.style.left = xPos + ‘px‘; return false; } xPos = xPos > xTarget ? xPos - speed : xPos + speed; //輪播方向向左或者向右時的處理 if (ele.movement) { //保證每次只有一個定時器運行 clearTimeout(ele.movement); } ele.style.left = xPos + ‘px‘; ele.movement = setTimeout(function () { //采用遞歸執行animate函數直到滿足程序終止條件Math.abs(Xtarget - xPos)<=speed才停止。 animate(ele, xTarget, time); },time); } function moveIndex(spanList,index) { //根據索引讓右下方對應的索引加上名稱為on的class,實現高亮。 for(var i = 0,len = spanList.length;i < len;i++){ spanList[i].className = ‘‘; } spanList[index].className = ‘on‘; } function autoPlay(obj){ //自動輪播函數 if(++obj.index >= obj.aSpan.length){ obj.index = 0; } moveIndex(obj.aSpan,obj.index); animate(obj.oUl,-obj.index * 500,10); } var slide = {//將輪播的方法的實現封裝在slide的對象中。 init:function(){ //初始化方法 this.oUl = document.querySelector(‘.img-box‘); this.aSpan = document.querySelectorAll(‘.icon span‘); this.index = 0;//為輪播定義一個總索引 this.timer = null; //頁面加載自動輪播的定時器 }, play:function(){//通過選取右下角的小圖標展示對應索引的圖片。 var that = this; for(var i = 0;i < this.aSpan.length;i++){ (function(j){ that.aSpan[j].onmouseover = function(){ that.index = j; moveIndex(that.aSpan,that.index); animate(that.oUl,-that.index * 500,10); } })(i) } }, autoSlide:function(){ //頁面加載完即開始自動輪播 var that = this; this.timer = setInterval(function(){ autoPlay(that); },3000); }, hover:function(){ //該方法主要為了實現箭頭放在輪播區域停止自動輪播,移開繼續自動輪播的功能。 var that = this; var oSlide = document.querySelector(‘.slide‘); oSlide.onmouseover = function(){ clearInterval(that.timer); } oSlide.onmouseout = function(){ that.timer = setInterval(function(){ autoPlay(that); },3000); } } } //通過對象調用對象上的函數 slide.init(); slide.play(); slide.autoSlide(); slide.hover(); }
1.animat函數
該函數有三個參數:
ele:要移動的目標元素,我這裏是ul。
xTarget:目標位置,是指ele要移動到的目標位置。
time:指animate函數中的定時器的時間間隔,這裏我用的是20ms。
animate函數中采用了遞歸,每次執行animate函數,ele都會相對於原來的位置移動speed的距離,speed我上面給定的是25,所以整個移動過程是一個勻速運動過程,但這樣會有一個不好的體驗,就是目前位置和目標位置距離過大時,整個滑動過程耗時較長,因為勻速嘛,距離越長耗時越多,所以這裏還給出一種算法,
speed =Math.ceil(Math.abs(xTarget - xPos) / 10),這是速度逐漸遞減的,由快到慢,距離越長,前面滑動的速度越快,這種體驗會更好一些,這裏我就不給出具體寫法了。
2.moveIndex函數
這個函數應該很好理解,就是根據輸入的index參數改變對應索引的元素class名稱。
3.var that = this
這樣的做的目的其實是用that變量保存調用對象中函數的那個對象本身,因為在後續的處理中,可能會用到對象slide的屬性和方法,而在事件處理程序和定時器處理程序中this的指向又發生了改變,所以就率先用that變量保存好對象,以便需要的時候使用。
這樣就基本實現了一個面向對象的簡單輪播效果。
原生js面向對象實現簡單輪播