今天,先從最簡(jiǎn)單的開始,將已有的一個(gè)Tab選項(xiàng)卡切換功能改寫成javascript插件形式。
原生函數(shù)寫法
將一個(gè)javascript方法改寫為js插件最簡(jiǎn)單的方式就是將這個(gè)方法掛載到window全局對(duì)象下面
我們先來(lái)看看最原始的使用函數(shù)寫法的代碼:
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>內(nèi)容一</section><section>內(nèi)容二</section><section>內(nèi)容三</section><section>內(nèi)容四</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;} 上面兩份代碼為基本代碼,之后我們后一步步在這份代碼的基礎(chǔ)上進(jìn)行改進(jìn)。
原生插件寫法
好,現(xiàn)在,我們就來(lái)將這個(gè)方法改寫成掛載在window對(duì)象下的插件:
tab.html
……// 下面是第一次改動(dòng)<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";}}}; 但是,我們發(fā)現(xiàn)這樣的寫法雖然很簡(jiǎn)單,但也有問(wèn)題:window作為一個(gè)全局對(duì)象,如果我們把自己的方法都掛載到它下面作為插件使用的話,插件一多,就容易產(chǎn)生命名空間沖突,另一方面,使用原生js雖然可以減少對(duì)外部的依賴,但代碼量相對(duì)還是很大,寫法比較繁瑣。
jquery寫法
我們嘗試引入jquery庫(kù),將此插件改寫為jquery插件。
jquery插件有三種形式:類級(jí)別的形式,對(duì)象級(jí)別的形式,jquery UI組件的形式
jquery 類級(jí)別插件寫法–單個(gè)方法
我們先來(lái)看類級(jí)別插件的形式。
第一種類級(jí)別插件的形式,直接把該方法掛載到j(luò)query的根空間下,作為一個(gè)工具方法:
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類級(jí)別插件寫法-多個(gè)方法
如果你想要將多個(gè)方法綁定到j(luò)query根空間上面,那么像下面這樣寫:
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()工具方法將自己的功能函數(shù)直接掛載到j(luò)query根命名空間下,簡(jiǎn)單,省事兒,但很不幸的是,這樣的方式不能利用jquery強(qiáng)大的sizzle引擎,即你選擇到的DOM元素?zé)o法運(yùn)用這個(gè)方法。
所以我們要用到對(duì)象級(jí)別的插件開發(fā)方式。
jquery對(duì)象級(jí)別插件寫法
對(duì)象級(jí)別的插件開發(fā)方式是利用$.fn.extend()方法將自己的方法綁定到j(luò)query原型上去,這樣所有jquery對(duì)象隊(duì)可以應(yīng)用該方法來(lái)執(zhí)行相應(yīng)操作了
代碼如下:
tab.html
……<script src="../jquery.js" type="text/javascript"></script><script type="text/javascript" src="h_tabs.js"></script><script>//對(duì)象級(jí)別的插件引用方法,注意和上面類級(jí)別插件的寫法上的區(qū)分$('#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); 這里,我們利用一個(gè)閉包封裝了插件,避免了命名空間污染
在這里,還有一些問(wèn)題,就是我們的方法必須傳參數(shù)才可以運(yùn)行,這就導(dǎo)致調(diào)用的時(shí)候我們使用$(‘#tab')選擇了id為tab的div,然后在插件里我們又根據(jù)傳入的ID獲取了一遍該元素。
既然我們已經(jīng)使用了jquery的選擇器,那么我們就可以引入this來(lái)解決重復(fù)獲取元素的冗余問(wèn)題。
jquery對(duì)象級(jí)別插件寫法-引入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(){//在這里引入thisvar 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); 這里需要注意的是,我們調(diào)用該插件的元素對(duì)象是(′tab′),則此時(shí)直接使用this.find()就等價(jià)于(‘tab').find(),而不是$(this).find(),注意使用代入法來(lái)區(qū)分這兩種寫法的差別。
作為一款插件,它應(yīng)該是可以被開發(fā)者控制的,所以還應(yīng)該提供給使用者一些配置接口。
jquery對(duì)象級(jí)別插件寫法-加入配置項(xiàng)
tab.html
……<ul><!--對(duì)照文章開始的代碼, 注意這里的改動(dòng) --><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({//使得當(dāng)前選項(xiàng)卡標(biāo)簽的樣式名稱可自定義的配置curName:'current'});</script></body></html> 我們這里把一開始的”當(dāng)前選項(xiàng)卡標(biāo)簽樣式類名稱“由”cur“改為了”current“,并將其作為配置項(xiàng)傳入插件
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}/*注意下面一行與之前的樣式代碼的對(duì)比變化之處*/.tabs ul li a.current { border-bottom: 3px solid #f26123;}.tabCons section { display: none;}.tabCons section:nth-child(1) { display: block;} 我們?cè)跇邮奖碇凶龀隽讼鄳?yīng)的改動(dòng)。
h_tabs.js
(function($){$.fn.extend({//給方法傳入一個(gè)對(duì)象作為參數(shù)h_tab:function(opts){//定義默認(rèn)的配置var defaults ={curName : 'cur'};//將傳入的參數(shù)覆蓋默認(rèn)參數(shù)中的默認(rèn)項(xiàng),最終合并到一個(gè)新的參數(shù)對(duì)象上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";}//在這里使用配置項(xiàng)的值this.className = Opt['curName'];oCons[this.index].style.display ="block";}}}});})(jQuery); 在這里我們使用了jquery的$.extend()方法的合并對(duì)象的功能,使用用戶傳入的配置項(xiàng)覆蓋默認(rèn)配置項(xiàng)并最終合并到一個(gè)新的配置項(xiàng)供后面的程序使用。
以上所述是小編給大家介紹的JavaScript tab選項(xiàng)卡插件實(shí)例代碼,希望對(duì)大家有所幫助!



















