輪播圖實現的效果為,鼠標移入左右箭頭會出現,可以點擊切換圖片,下面的小圓點會跟隨,可以循環播放(為了方便理解,沒有補2張圖做無縫輪播)。本篇文章的主要目的是分享封裝插件的思路。
輪播圖我一開始是寫成非插件形式實現的效果,后來才改成了封裝成插件的形式。
首先要明白輪播圖的實現原理和基本布局,大概就是外面有一個容器包裹着(通常是div),容器設置寬高,以及overflow為hidden,超出寬高部分隱藏,
容器里面又包含着另一個容器,包裹着所有的圖片,寬為所有圖片的總寬度,ul的position為absolute,通過改變ul的left值的變化來實現圖片輪播的效果
所以寫好的css樣式和html代碼如下
*{margin:0; padding:0; text-decoration: none;} #container{height: 400px; width: 600px; overflow: hidden; position:relative;} #list{height:400px; width:4200px; position: absolute; z-index:1;} img{display:inline-block; float:left;} #buttons{position: absolute; width:100px; height:10px; z-index:2; bottom:25px; left: 250px;} #buttons span{float: left; border:1px solid #fff; width:10px; height:10px; border-radius:50%; margin-right:5px; color:#333; cursor:pointer;} #buttons .on { background: orangered;} .arrow{cursor: pointer; display: none; line-height: 39px; text-align: center; font-size: 36px; font-weight: bold; width: 40px; height: 40px; position: absolute; z-index: 2; top: 180px; background-color: RGBA(0,0,0,.3); color: #fff;} .arrow:hover { background-color: RGBA(0,0,0,.7);} #container:hover .arrow{display:block;} #prev{left:20px;} #next{right:20px;}
<div id="container"> <div id="list"> <img src="img/1.jpg" alt=""> <img src="img/2.jpg" alt=""> <img src="img/3.jpg" alt=""> <img src="img/4.jpg" alt=""> <img src="img/5.jpg" alt=""> </div> <div id="buttons"> <span index="1" class="on"></span> <span index="2"></span> <span index="3"></span> <span index="4"></span> <span index="5"></span> </div> <a href="javascript:;" class="arrow" id="prev"><</a> <a href="javascript:;" class="arrow" id="next">></a> </div>
接下來要開始封裝插件了!!!
封裝插件的基本思想就是:把要寫的代碼,封閉到一個自執行函數里面,防止跟外部變量沖突,然后將這個構造函數暴露給window對象,方便我們在外部去訪問這個構造函數。
第一:先寫好基礎的js結構
;(function(window, document){ // 使用一個立即執行函數,把window和document對象傳進去 function Carousel(options){ // 創建構造函數,采用大寫駝峰寫法的函數是構造函數,跟普通方法區分開來 } Carousel.prototype = { // 重寫原型 } window.Carousel = Carousel; // 把構造函數暴露出去,全局可調用 })(window, document)
第二步:寫好默認配置,以及完善構造函數,代碼成這樣
(function(window, document){ let defaultSetting = { // 默認設置 "width":"500", "height":"300" } function Carousel(options){ // var self = this; // 在構造函數中使用,this指向新創建的對象Carousel{},常把this保存在self里,因為在不同層級,this的指向可能不同 self.setting = Object.assign(defaultSetting, options); //合並參數,把默認設置和new對象的時候傳進來的options進行合並,options里面設置了的項會覆蓋默認設置的 self.container = document.querySelector(self.setting.container); // 獲取最外層的容器 self.list = document.querySelector("#list"); // 獲取包裹img的列表 self.sliderItems = self.list.getElementsByTagName('img'); // 獲取圖片集合 self.buttons = document.querySelector("#buttons").getElementsByTagName('span'); // 獲取左右按鈕集合 self.prev = document.querySelector("#prev"); // 前進按鈕 self.next = document.querySelector("#next"); // 后退按鈕 self.index = 1; // 焦點index初始值是1,指示第一張圖片 } Carousel.prototype = { } window.Carousel = Carousel; })(window, document)
第三步,給原型添加方法,這樣new出來的對象就默認可以使用這些方法了,完善后的代碼長這樣
(function(window, document){ let defaultSetting = { "width":"500", "height":"300" } function Carousel(options){ // var self = this; self.setting = Object.assign(defaultSetting, options); self.container = document.querySelector(self.setting.container); self.list = document.querySelector("#list"); self.sliderItems = self.list.getElementsByTagName('img'); self.buttons = document.querySelector("#buttons").getElementsByTagName('span'); self.prev = document.querySelector("#prev"); self.next = document.querySelector("#next"); self.index = 1; self.prev.onclick = function(){ // 點擊按鈕調用rotate方法切換到上一張 self.rotate('left'); } self.next.onclick = function(){ // 點擊按鈕調用rotate方法切換到下一張 self.rotate('right'); } } Carousel.prototype = { rotate: function(dir){ // 定義rotate方法 let self = this; let newLeft; // 變化后的left值 let selfLeft = self.list.style.left; // 原left值 let sliderWidth = parseInt(self.setting.width); // 可見視口寬度,這里也是一張圖片寬度 let len = self.sliderItems.length; // 圖片總張數 let totalWidth = len * sliderWidth if(dir === 'left'){ // 點擊左按鈕,往前一張 if(!selfLeft){ newLeft = selfLeft + sliderWidth; }else{ newLeft = parseInt(selfLeft) + sliderWidth self.index--; } if(newLeft > 0){ // 如果是第一張圖片往前切換,則切換到最后一張 newLeft = -totalWidth + sliderWidth; self.index = len; } self.list.style.left = newLeft + 'px' // 改變left值 showButtons(); } if(dir === 'right'){ // 點擊右按鈕,往后一張, 則left值增加一個負sliderWidth if(!selfLeft){ newLeft = selfLeft - sliderWidth self.index++; }else{ newLeft = parseInt(selfLeft) - sliderWidth self.index++; } if(newLeft <= -totalWidth){ // newLeft = 0; self.index = 1; } self.list.style.left = newLeft + 'px' // 改變left值 showButtons(); } function showButtons(){ // rotate方法里面又定義了showButtons方法 for(let i=0; i< self.buttons.length; i++){ if(self.buttons[i].className === 'on'){ self.buttons[i].className = ''; // 清除原圓點高亮狀態 break; } } self.buttons[self.index-1].className ='on'; } } } window.Carousel = Carousel; // 暴露出去,供全局對象使用 })(window, document)
最后一步就是利用構造函數創建對象了,
var Carousel = new Carousel({ container:"#container", width:"600", height:"400" });
然后我們就能看到上面說的效果。
原生js封裝輪播圖插件就完成了,插件不是非常的完善,主要是為了分享自己一步步封裝插件的過程,歡迎留言交流,晚點會放上github鏈接,可以下載源碼~