jquery插件的封裝過程。
使用過不少的jquery的插件,可是不瞭解它們究竟是怎樣作的,今天就來封裝一個最多見的tab插件,看看具體的封裝過程。
tip:完整代碼下載在最後面,須要的直接跳過去看
javascript
常見的tab支持自動切換,點擊切換,動畫切換,默認選擇等等,根據這些功能先來把html結構搭建起來:
css
//index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>tab選項卡封裝插件</title> </head> <body> <div class="tab js-tab"> <ul class="tab_nav"> <li class="active"><a href="javascript:;">新聞</a></li> <li><a href="javascript:;">娛樂</a></li> <li><a href="javascript:;">電影</a></li> <li><a href="javascript:;">科技</a></li> </ul> <div class="content_wrap"> <div class="content_item current">a</div> <div class="content_item">b</div> <div class="content_item">c</div> <div class="content_item">d</div> </div> </div> </body> </html>
它是長這個樣子,夠醜,下一步來美化一下:
html
引入個tab.css樣式,書寫一下樣式:
java
//tab.css *{margin: 0;padding: 0;} ul,li{list-style: none;} body{padding: 100px;background-color: #323232;font-size: 12px;font-family: "微軟雅黑";} p{color:#6ec;font-weight: bold; background: #fff;height:20px;line-height: 20px;border-radius: 5px;padding:5px;} .tab_view{ float: left; margin-right: 50px; } .tab_view p{ color: #999; margin: 20px 0; } .tab{ width: 300px; } .tab_nav{ height: 30px; } .tab_nav li{ float: left; margin-right: 5px; background-color: #767676; border-radius: 3px 3px 0 0; } .tab_nav li a{ display: block; height: 30px; line-height: 30px; padding: 0 20px; color: #fff; text-decoration: none; } .tab_nav li.active{ background-color: #fff; } .tab_nav li.active a{ color: #767676; } .content_wrap{ height: 200px; padding: 5px; background-color: #fff; } .content_item{ font-size: 60px; text-align: center; line-height: 200px; width: 290px; height: 200px; display: none; position: absolute; } .content_wrap div.current{ display: block; } .content_item:first-child{ background-color: gray; } .content_item:nth-child(2){ background-color: lightblue; } .content_item:nth-child(3){ background-color: pink; } .content_item:nth-child(4){ background-color: lightgreen; }
它就長成這個樣子了,看着舒服多了,立刻進行下一步,插件封裝:
jquery
在封裝插件前,先來引入jquery和tab.js,在tab.js中進行具體的開發:
1.在開發前想一下,須要怎麼來使用這個插件?確定是new Tab(選擇器),新建類後傳入選擇器,那若是想傳遞一些自定義的配置怎麼作呢?
能夠在html上加個data-config字段用於存放配置,而後使用getConfig()函數來得到
segmentfault
//index.html <div class="tab js-tab" data-config='{ "triggerType":"click", "effect":"fade", "invoke":1, "auto":3000 }'> //其餘內容 </div> <script> $(function(){ var tab = new Tab($(".js-tab").eq(0)) }); </script>
//tab.js ;(function($){ var Tab = function(tab){ //這裏寫屬性 }; Tab.prototype = { //這裏寫方法 } //把類掛載在全局 window.Tab = Tab; })(jQuery);
2.基礎的結構寫好了,接下來就是要處理配置,用戶可能會傳入參數也可能不會,因此默認參數是必需要提早來寫好的,而後得到用戶傳入的參數,對比一下,看哪些寫過哪些沒寫,把寫過的保存,沒寫的使用默認項
如何實現呢?
使用jQuery.extend(),它用於合併對象,若是隻爲$.extend()指定了一個參數,則之前的配置捨棄直接用新的。若是多個對象具備相同的屬性,則後者會覆蓋前者的屬性值
有了解決方法,能夠直接來寫了
jquery插件
;(function($){ var Tab = function(tab){ //這裏寫屬性 var _this = this; // 保存單個tab組件 this.tab = tab; // 默認配置參數 this.config = { "triggerType":"mouseover", // 用來定義鼠標的觸發類型,是click仍是mouseover "effect":"default", // 用來定義內容切換效果,是直接切換仍是淡入淡出效果 "invoke":1, // 默認展現第幾個tab "auto":false // 定義tab是否自動切換,及自動切換時間間隔 }; // 若是配置參數存在,就擴展掉默認配置參數 if(this.getConfig()){ $.extend(this.config,this.getConfig()); } }; Tab.prototype = { //這裏寫方法 // 獲取配置參數 getConfig: function(){ // 拿一下tab elem節點上的data-config var config = this.tab.attr("data-config"); // 確保有配置參數 if(config&&config!=""){ return $.parseJSON(config); }else{ return null; } } } //把類掛載在全局 window.Tab = Tab; })(jQuery);
測試一下,若是沒有傳參,會不會將默認配置寫上:
再測試一下,若是傳某幾項參數,會不會將配置混合:
svg
接着來開發,接下來就能夠來添加一些事件交互效果了,有哪些效果呢?點擊和鼠標滑過,先來看點擊,要想點擊確定得先獲取到點擊的內容,就是在html寫的li標籤,this.tab.find("ul.tab_nav li")
同時當點擊了li標籤中的分類後,應該對應的顯示不一樣的內容,因此這部份內容也要獲取到,this.tab.find("div.content_wrap div.content_item")
而後判斷屬於點擊事件仍是鼠標滑過事件,爲它添加上對應的樣式和修改對應的內容,這個在invoke中實現,有了思路,直接來寫:
函數
;(function($){ var Tab = function(tab){ //前面內容省略 // 保存tab標籤列表、對應的內容列表 this.tabItems = this.tab.find("ul.tab_nav li"); this.contentItems = this.tab.find("div.content_wrap div.content_item"); // 保存配置參數 var config = this.config; if(config.triggerType === "click"){ this.tabItems.bind(config.triggerType,function(){ _this.invoke($(this)); }) }else if(config.triggerType != "click"){ this.tabItems.bind("mouseover",function(){ _this.invoke($(this)); }) } }; Tab.prototype = { //這裏寫方法 //前面的省略 // 事件操做函數 invoke: function(currentTab){ var _this = this; var index = currentTab.index(); // tab選中狀態 currentTab.addClass('active').siblings().removeClass('active'); // 切換對應的內容區域 var effect = this.config.effect; var conItems = this.contentItems; if(effect === "default" || effect != "fade"){ conItems.eq(index).addClass('current').siblings().removeClass('current'); }else if(effect === "fade"){ conItems.eq(index).fadeIn().siblings().fadeOut(); }; // 注意:若是參數配置了自動切換時間,要把當前的loop的值設置成當前tab的index if(this.config.auto){ this.loop = index; } }, } //把類掛載在全局 window.Tab = Tab; })(jQuery);
至此,應該能實現點擊或鼠標滑過修改樣式和更改內容,測試一下:
oop
上面實現了手動的點擊或者鼠標滑過期切換的功能,但實際的tab插件是有自動切換的功能,如何來實現呢?可使用setInterval來實現,週期就是data-config中的auto,在回調函數中依次以點擊或者鼠標滑過的方式來觸發,如何實現依次調用?寫個循環的變量this.loop = 0;如何自動觸發呢?jquery有一個trigger方法,它就是用來自動觸發選中的事件的,思路有了,開寫:
;(function($){ var Tab = function(tab){ //前面內容省略 // 自動切換功能,若是配置了時間,咱們就根據時間間隔進行自動切換 if(config.auto){ // 定義一個全局的定時器 this.timer = null; // 計數器 this.loop = 0; this.autoPlay(); } }; Tab.prototype = { //這裏寫方法 //前面的省略 // 自動間隔時間切換 autoPlay: function(){ var _this = this, tabItems = this.tabItems, // 臨時保存tab列表 tabLength = tabItems.size(), // tab的個數 config = this.config; this.timer = window.setInterval(function(){ _this.loop ++; if(_this.loop >= tabLength){ _this.loop = 0; }; tabItems.eq(_this.loop).trigger(config.triggerType); },config.auto); }, } //把類掛載在全局 window.Tab = Tab; })(jQuery);
ok,測試一下,此時應該會自動的進行切換:
確實實現了自動切換,可是當鼠標放在上面的時候,它停不住,這個須要來解決一下,添加個hover,而後在懸浮的時候清除一下setInterval
this.tab.hover(function(){ window.clearInterval(_this.timer); },function(){ _this.autoPlay(); });
ok,搞定,在鼠標放上去的時候他會自動中止,移開後又自動的循環
終於到了最後一個功能,須要傳入某個默認選擇時,從該選擇開始循環,這個有了前面的鋪墊就好實現了,只須要簡單設置一下就好了this.tabItems.eq(config.invoke-1)
;(function($){ var Tab = function(tab){ //前面內容省略 // 設置默認顯示第幾個tab if(config.invoke > 1){ this.invoke(this.tabItems.eq(config.invoke-1)); } }; Tab.prototype = { //這裏寫方法 //前面的省略 } //把類掛載在全局 window.Tab = Tab; })(jQuery);
測試一下,看看它會不會從第二個開始循環:
ok,全部的功能都實現了,是時候考慮一下用戶使用的便捷性了,在上面使用這個插件的時候是經過 var tab = new Tab($(".js-tab").eq(0)) 這樣來實現的,可是實際的插件使用應該是 Tab.init($(".js-tab"));或者$(".js-tab").tab();這樣的來調用,就須要來把new的這個過程給封裝卡來,each方法把傳入的內容給都new一遍,或者$.fn.extend()直接把它加在jquery上,實現一下:
;(function($){ var Tab = function(tab){ //前面內容省略 }; Tab.prototype = { //前面的省略 } Tab.init = function(tabs){ var _this = this; tabs.each(function(){ new _this($(this)); }) } // 註冊成jq方法 $.fn.extend({ tab: function(){ this.each(function(){ new Tab($(this)); }); return this; } }) //把類掛載在全局 window.Tab = Tab; })(jQuery);
測試一下:
ok,整個插件就作好了,作這個關鍵瞭解了封裝jquery插件的流程,之後就能夠本身來封裝屬於本身的jquery插件了。
這個過程,是學習自這個教程:https://www.imooc.com/learn/825,你們能夠去看看。
完整代碼下載:http://zuitingliu.com/?p=163