最近在這裏看了一篇關於面試的文章《回顧本身三次失敗的面試經歷》,做者三次倒在了輪播圖上。囧,因此我也寫個輪播圖看看。
此次是用jQuery寫的,由於最近一直在研究jQuery插件的寫法,因此用jQuery寫的,並且我發現,我vue用太多,徹底不熟悉dom操做,之後仍是要多多用用jQuery和原生jscss
獻給小白們:jQuery插件開發精品教程,讓你的jQuery提高一個臺階html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>slide</title> <script src="http://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js"></script> <script src="jquery.js"></script> <style> *{ margin:0; padding: 0; } li{ list-style: none; } ul{ display: flex; position: relative; } .contain{ width: 600px; overflow: hidden; position: relative; } ol{ position: absolute; bottom:10px; display: flex; justify-content: center; width: 100%; } ol li{ width: 10px; height: 10px; border-radius: 50%; background-color: #f60; margin:0 2px; } .conActive{ background-color: #fff; } </style> </head> <body> <div id="slide"> <div class="contain"> <ul> <li><img src="img/img11.jpg" alt=""></li> <li><img src="img/img21.jpg" alt=""></li> <li><img src="img/img33.jpg" alt=""></li> <li><img src="img/img39.jpg" alt=""></li> <li><img src="img/img55.jpg" alt=""></li> </ul> </div> </div> <style> $(function() { $(".contain").Slide() }) </style> </body> </html>
首先的插件的大致結構以下vue
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = { }; function Slide(element, options) { this.element = element; this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { } }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
接下來就是輪播圖的大體邏輯了。jquery
由簡入繁的寫,第一步是考慮怎麼讓輪播圖動起來
git
輪播圖在網頁上大體是這個樣子的,只有一張暴露在視野內,其餘的在視野外,用overflow:hidden隱藏就行。
那動起來就很是簡單github
$(element).animate({right:index*this.width+'px'}, 1000)//jQuery中animate方法
初始化的話,咱們須要計算整個ul的長度,獲取單個li的長度。面試
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = { }; function Slide(element, options) { this.element = element; this.width = $(this.element).find('ul li img')[0].width;//圖片寬度 this.length = $(this.element).find('ul li').length//輪播數量 this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { let index=1//索引 const content = $(this.element).find('ul');//獲取ul content.css('width',this.width*this.length);//計算長度 this.autoplay(content,index) }, autoplay: function(content,index) { const _this=this; timer=setInterval(function(){ $(content).animate({right:index*this.width+'px'}, 1000) index++ },2000) } }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
到這裏,輪播圖已經在一張圖一張圖的往右跑了,輪播圖的邏輯就這麼多。可是別人的輪播圖都會回頭啊,這個輪播圖跑着跑着白屏了。接下來就讓他回頭,利用聲明的index實現。app
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = { }; function Slide(element, options) { this.element = element; this.width = $(this.element).find('ul li img')[0].width;//圖片寬度 this.length = $(this.element).find('ul li').length//輪播數量 this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { let index=1//索引 const content = $(this.element).find('ul');//獲取ul content.css('width',this.width*this.length);//計算長度 this.autoplay(content,index) }, autoplay: function(content,index) { const _this=this; timer=setInterval(function(){ $(content).animate({right:index*this.width+'px'}, 1000) index===this.length-1?index=0:index++//若是索引到了this.length-1,說明到了最後一張圖片,咱們將index調爲0,下一次運行時,ul的樣式就會歸位,這樣就成功回頭 },2000) } }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
這邊已經實現了一個像模像樣的輪播圖了,但在尾->首切換的時候違和感太嚴重了,咱們須要的是平滑過渡,曾經我絞盡腦汁想不出辦法,而後花了半分鐘上網搜索到了答案,下次不再瞎想了。
dom
如上圖,在輪播圖最後複製一個輪播圖第一張,當劃到最後一個slide1時,再當即將ul位置復原,切換到第一個slide1,咱們覺得劃到了第一個slide1,這樣就能實現平滑的過渡。jquery插件
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = { }; function Slide(element, options) { this.element = element; this.width = $(this.element).find('ul li img')[0].width;//圖片寬度 this.length = $(this.element).find('ul li').length//輪播數量 this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { let index=1//索引 const content = $(this.element).find('ul');//獲取ul content.css('width',this.width*this.length);//計算長度 this.autoplay(content,index) }, autoplay: function(content,index) { const _this=this; timer=setInterval(function(){ $(content).animate({right:index*_this.width+'px'}, 1000) if(index===_this.length){ $(content).animate({right:0+'px'}, 0)//將ul回覆到原位 index=1//index重置爲1(這裏是1,恢復到函數剛開始的索引) }else{ index++ } },2000) }, creat: function(){ $($(this.element).find('ul li')[0]).clone().appendTo($(this.element).find('ul')) },//克隆第一個li再添加到ul }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
好的,完整版的輪播圖就完成了,若是對輪播圖沒有任何須要,大體就是這樣了。但咱們網站中的輪播圖多種多樣,用過插件的小夥伴也知道,不少輪播圖能自定義參數來開啓不一樣的功能,例如強大的swiper插件。接下來咱們就來實現一些自定義的功能。
自定義參數:輪播間隔時間,輪播分頁小點
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = {//默認參數 pagination:true,//默認開啓輪播分頁小點 interval:2000//默認間隔時間2s };//這裏不明白的小白朋友們麻煩去通讀上面推薦的jquery插件的寫法,就會明白 function Slide(element, options) { this.element = element; this.width = $(this.element).find('ul li img')[0].width;//圖片寬度 this.length = $(this.element).find('ul li').length//輪播數量 this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { let index=1; this.creat(); this.settings.pagination?this.pagination():''//若是設置了pagination:true,建立小點 this.addStyle(0)//給第一個小點添加樣式 const content = $(this.element).find('ul');//獲取ul content.css('width',this.width*this.length);//計算長度 this.autoplay(content,index) }, autoplay: function(content,index) { const _this=this timer=setInterval(function(){ console.log(index*this.width) $(content).animate({right:index*_this.width+'px'}, 1000) if(index===_this.length){ $(content).animate({right:0+'px'}, 0) index=1 }else{ index++ } _this.addStyle(index-1)//index變化,致使小點樣式變化 },this.settings.ininterval)//將自定義時間傳入 }, creat: function(){ $($(this.element).find('ul li')[0]).clone().appendTo($(this.element).find('ul')) }, pagination: function(index){ let ol="<ol></ol>" $(this.element).append(ol) let li="<li></li>" for(i=1;i<this.length;i++){ $(this.element).find('ol').append(li) }//建立分頁小點 }, addStyle: function(index){ let active=$(this.element).find('ul li')[index] $(active).addClass('active').siblings().removeClass('active') if(this.settings.pagination){ let conActive=$(this.element).find('ol li')[index] $(conActive).addClass('conActive').siblings().removeClass('conActive') } }//給活動的輪播圖和小點添加樣式 }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
接下來就是改變下調用
$(function() { $(".contain").Slide({ pagination:false, interval:5000 }) })
這裏就起做用了。
若是再有其餘的功能,只須要往裏面一步一步添加函數就能夠了,好比前進後退按鈕,好比一次滾動多張圖片。
之因此要本身寫一寫這些小demo,是爲了有助於咱們更好的使用別人的代碼。並非全部人寫的代碼或者插件都適合小白使用,好比better-scroll,這是一個vue的滾動插件,大多數人使用了以後發現滾動不了,去做者github提issue,實際上是他們並不懂滾動的原理。我以前也是摸索了做者的實例才成功使用的,但這個插件並不僅是滾動,還有其餘應用,好比手機端聯繫人列表插件,我徹底搞不懂這是怎麼實現的,天然也使用不起來。最近我就用vue本身實現了一個手機端聯繫人列表,很是很是之簡單,一個函數搞定,難點在於html的合理佈局,因此沒有發到這裏,有興趣的小夥伴能夠去github看下。
知其然,更要知其因此然。這樣才能慢慢進步,不然只能靠搬運插件混生活了。