今天,先從最簡單的開始,將已有的一個Tab選項卡切換功能改寫成javascript插件形式。
原生函式寫法
將一個javascript方法改寫為js插件最簡單的方式就是將這個方法掛載到window全域物件下面
我們先來看看最原始的使用函數寫法的程式碼:
tab.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="renderer" content="webkit"> <title>jquery_hjb_tab插件demo</title> <link rel="stylesheet" href="h.css"/> </head> <body> <div id="tab"> <div class="tabs"> <ul> <li><a href="#">tab1</a></li> <li><a href="#">tab2</a></li> <li><a href="#">tab3</a></li> <li><a href="#">tab4</a></li> </ul> </div> <div class="tabCons"> <section>内容一</section> <section>内容二</section> <section>内容三</section> <section>内容四</section> </div> </div> <script> window.onload = h_tab('tab'); function h_tab(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName("a"); var oCons = document.getElementById(tabId).getElementsByTagName("section"); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } } </script>
h.css
@charset "utf-8"; /* //author:hjb2722404 //description: //date:2016/2/18 */ .tabs ul { width: 100%; list-style-type: none;} .tabs ul li { width: 48%; display: inline-block; margin: 0; padding: 0;} .tabs ul li a {border-bottom: 3px solid #cccccc; width: 100%; height: 100%; display: block; text-align: center; min-height: 40px; line-height: 40px; text-decoration: none; font-family: "微软雅黑"; color: #a94442} .tabs ul li a.cur { border-bottom: 3px solid #f26123;} .tabCons section { display: none;} .tabCons section:nth-child(1) { display: block;}
上面兩份程式碼為基本程式碼,之後我們後一步步在這份程式碼的基礎上進行改進。
原生外掛程式寫法
好,現在,我們就來將這個方法改寫成掛載在window物件下的插件:
tab.html
…… // 下面是第一次改动 <script type="text/javascript" src="h_tabs.js"></script> <script> H_tab("tab"); </script> </body> </html>
h_tabs.js
window.H_tab = function(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName("a"); var oCons = document.getElementById(tabId).getElementsByTagName("section"); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } };
但是,我們發現這樣的寫法雖然很簡單,但也有問題:window作為一個全局對象,如果我們把自己的方法都掛載到它下面作為插件使用的話,插件一多,就容易產生命名空間衝突,另一方面,使用原生js雖然可以減少對外部的依賴,但程式碼量相對還是很大,寫法比較繁瑣。
jquery寫法
我們嘗試引入jquery庫,將此插件改寫為jquery插件。
jquery外掛有三種形式:類別層級的形式,物件層級的形式,jquery UI元件的形式
jquery 類別層級外掛程式寫法–單一方法
我們先來看類別層級插件的形式。
第一種類層級插件的形式,直接把該方法掛載到jquery的根空間下,作為一個工具方法:
tab.html
…… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> $.h_tab('tab'); </script> </body> </html>
h_tabs.js
$.h_tab = function(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName("a"); var oCons = document.getElementById(tabId).getElementsByTagName("section"); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } };
jquery類別層級外掛程式寫法-多重方法
如果你想要將多個方法綁定到jquery根空間上面,那麼像下面這樣寫:
tab.html
…… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> $.h_tab('tab'); $.h_hello('hjb'); </script> </body> </html>
h_tabs.js
$.extend({ h_tab:function(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName("a"); var oCons = document.getElementById(tabId).getElementsByTagName("section"); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } }, h_hello :function(name){ console.log("hello,",name); } });
雖然使用$.extend()工具方法將自己的功能函數直接掛載到jquery根命名空間下,簡單,省事兒,但很不幸的是,這樣的方式不能利用jquery強大的sizzle引擎,即你所選到的DOM元素無法運用這個方法。
所以我們要用到物件層級的插件開發方式。
jquery物件層級外掛程式寫法
物件層級的插件開發方式是利用$.fn.extend()方法將自己的方法綁定到jquery原型上去,這樣所有jquery物件隊可以應用該方法來執行相應操作了
程式碼如下:
tab.html
…… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> //对象级别的插件引用方法,注意和上面类级别插件的写法上的区分 $('#tab').h_tab('tab'); </script> </body> </html>
h_tabs.js
(function($){ $.fn.extend({ h_tab:function(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName('a'); var oCons = document.getElementById(tabId).getElementsByTagName('section'); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } } }); })(jQuery);
這裡,我們利用一個閉包封裝了插件,避免了命名空間污染
在這裡,還有一些問題,就是我們的方法必須傳參數才可以運行,這就導致調用的時候我們使用$('#tab')選擇了id為tab的div,然後在插件裡我們又根據傳入的ID獲取了一遍該元素。
既然我們已經使用了jquery的選擇器,那麼我們就可以引入this來解決重複獲取元素的冗餘問題。
jquery物件層級外掛程式寫法-引入this
tab.html
…… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> $('#tab').h_tab(); </script> </body> </html>
h_tabs.js
(function($){ $.fn.extend({ h_tab:function(){ //在这里引入this var oLinks = this.find('a'); var oCons = this.find('section'); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } } }); })(jQuery);
這裡要注意的是,我們呼叫該插件的元素物件是(′tab′),則此時直接使用this.find()就等價於('tab').find(),而不是$ (this).find(),注意使用代入法來區分這兩種寫法的差別。
作為一款插件,它應該是可以被開發者控制的,所以也應該提供給使用者一些設定介面。
jquery物件層級外掛程式寫法-加入設定項
tab.html
…… <ul> <!--对照文章开始的代码, 注意这里的改动 --> <li><a href="#" class="current">tab1</a></li> <li><a href="#">tab2</a></li> …… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> $('#tab').h_tab({ //使得当前选项卡标签的样式名称可自定义的配置 curName:'current' }); </script> </body> </html>
我們這裡把一開始的”當前選項卡標籤樣式類名稱“由”cur“改為了”current“,並將其作為配置項傳入插件
h.css
.tabs ul { width: 100%; list-style-type: none;} .tabs ul li { width: 48%; display: inline-block; margin: 0; padding: 0;} .tabs ul li a {border-bottom: 3px solid #cccccc; width: 100%; height: 100%; display: block; text-align: center; min-height: 40px; line-height: 40px; text-decoration: none; font-family: "微软雅黑"; color: #a94442} /*注意下面一行与之前的样式代码的对比变化之处*/ .tabs ul li a.current { border-bottom: 3px solid #f26123;} .tabCons section { display: none;} .tabCons section:nth-child(1) { display: block;}
我們在樣式表中做了對應的改變。
h_tabs.js
(function($){ $.fn.extend({ //给方法传入一个对象作为参数 h_tab:function(opts){ //定义默认的配置 var defaults ={ curName : 'cur' }; //将传入的参数覆盖默认参数中的默认项,最终合并到一个新的参数对象上 var Opt = $.extend({},defaults,opts); var oLinks = this.find('a'); var oCons = this.find('section'); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } //在这里使用配置项的值 this.className = Opt['curName']; oCons[this.index].style.display ="block"; } } } }); })(jQuery);
在這裡我們使用了jquery的$.extend()方法的合併物件的功能,使用使用者傳入的配置項覆蓋預設配置項並最終合併到一個新的配置項供後面的程式使用。
以上所述是小編給大家介紹的JavaScript tab選項卡外掛程式實例程式碼,希望對大家有幫助!