title: 《鋒利的jQuery》十歇式、jQuery插件的使用和寫法
date: 2017-07-24 06:20:00
tags: 鋒利的jQuery
編寫插件的目的是給已有的一系列方法或函數(shù)做一個(gè)封裝屁置,以便在其他地方重復(fù)使用疆虚,方便后期維護(hù)和提高開發(fā)效率搞监。
插件的種類
1.封裝對(duì)象方法的插件
這種插件是將對(duì)象方法封裝起來(lái)水孩,用于通過(guò)選擇器獲取jQuery對(duì)象進(jìn)行操作,是最常見(jiàn)的一種插件琐驴。比如parent()
俘种、appendTo()
秤标、addClass()
等。
2.封裝全局函數(shù)的插件
可以將獨(dú)立的函數(shù)加載到j(luò)Query的命名空間之下宙刘。例如$.ajax()
苍姜、$.trim()
等。
3.選擇器插件
個(gè)別情況下悬包,會(huì)需要使用到選擇器插件衙猪,雖然jQuery的選擇器十分強(qiáng)大,但還是會(huì)需要擴(kuò)充一些自己喜歡的選擇器布近。
插件的基本要點(diǎn)
插件的文件名推薦命名為jquery.[插件名].js
垫释。
所有的對(duì)象方法都應(yīng)該附加到j(luò)Query.fn對(duì)象上,而所有的全局函數(shù)都應(yīng)該附加到j(luò)Query對(duì)象本身上撑瞧。
在插件內(nèi)部饶号,this
只想的是當(dāng)前通過(guò)選擇器獲取的jQuery對(duì)象,例如click()
方法指向的是DOM元素季蚂∶4可以通過(guò)this.each來(lái)遍歷所有元素。
插件應(yīng)該返回一個(gè)jQuery對(duì)象扭屁,以保證插件的可鏈?zhǔn)讲僮魉闾浮3遣寮枰祷氐氖且恍┬枰@取的量,例如字符串或者數(shù)組料滥。
避免在插件內(nèi)部使用$作為jQuery對(duì)象的別名然眼,而應(yīng)該用完整的jQuery來(lái)表示。這樣可以避免沖突葵腹,如果使用$作為jQuery的別名高每,要用必報(bào)來(lái)避免沖突。
插件中的閉包
利用閉包的特性践宴,既可以避免內(nèi)部臨時(shí)變量影響全局空間鲸匿,又可以在插件內(nèi)部繼續(xù)使用$作為jQuery別名。
(function($){ // 將$作為匿名函數(shù)的形參
// 這里編寫插件的代碼
var foo;
var bar = function(){
// 在匿名函數(shù)內(nèi)部的函數(shù)都可以訪問(wèn)foo阻肩,即便是在匿名函數(shù)的外部調(diào)用bar()的時(shí)候带欢,也可以在bar()的內(nèi)部訪問(wèn)到foo,但在匿名函數(shù)的外部直接訪問(wèn)foo是做不到的烤惊。
}
// 下面的語(yǔ)句讓匿名函數(shù)內(nèi)部的函數(shù)bar()返回到全局可訪問(wèn)的范圍內(nèi)乔煞,這樣就可以在匿名函數(shù)的外部通過(guò)調(diào)用jQuery.BAR()來(lái)訪問(wèn)內(nèi)部定義的函數(shù)bar(),并且內(nèi)部函數(shù)bar()也能訪問(wèn)匿名函數(shù)內(nèi)的變量foo柒室。
$.BAR = bar;
})(jQuery) // jQuery作為實(shí)參傳遞給匿名函數(shù)
jQuery的插件機(jī)制
jQuery提供了兩個(gè)用于擴(kuò)展jQuery功能的方法渡贾,jQuery.fn.extend()
方法和jQuery.extend()
方法。第一個(gè)方法用于封裝對(duì)象方法的插件雄右,第二個(gè)適用于封裝全局函數(shù)插件和選擇器插件空骚。這兩個(gè)方法都接收一個(gè)參數(shù)纺讲,類型是Object。
jQuery.extend()
除了擴(kuò)展插件能用到府怯,還有一個(gè)用處是擴(kuò)展已有的對(duì)象刻诊,也就是傳遞兩個(gè)參數(shù),類型都是object牺丙,第二個(gè)對(duì)象會(huì)和第一個(gè)對(duì)象合并则涯,相同的屬性第二個(gè)會(huì)覆蓋第一個(gè)。
var settings = { validate: false , limit: 5 , name: 'foo' };
var options = { validate: true , name: 'bar' };
var newObj = jQuery.extend(settings,options);
console.log(newObj) // { validate: true , limit: 5 , name: 'bar' }
所以jQuery.extend()
方法經(jīng)常用于設(shè)置插件方法的一些默認(rèn)參數(shù)冲簿。
編寫jQuery插件
封裝jQuery對(duì)象插件
設(shè)置和獲取顏色的插件
首先編寫設(shè)置和獲取顏色的插件color粟判。該插件的功能是:
- 設(shè)置匹配元素的顏色
- 獲取匹配的元素(元素集合中的第一個(gè))的顏色。
由于是在jQuery對(duì)象上擴(kuò)展方法所以使用jQuery.fn.extend
峦剔,這里要注意的是插件擴(kuò)展內(nèi)部的this指的是jQuery對(duì)象而不是普通的dom對(duì)象档礁,然后插件如果不是返回字符串之類的特定值,應(yīng)當(dāng)使其具有可鏈接性吝沫,為此要直接返回這個(gè)this對(duì)象呻澜。
(function($){
$.fn.extend({
'color': function(value){
if(value == undefined){
return this.css('color'); // 獲取顏色。css方法本身就默認(rèn)返回第一個(gè)的顏色
}else{
return this.each(function(){
$(this).css('color',value); // 設(shè)置顏色惨险,由于this是jQuery對(duì)象羹幸,所以不需要each遍歷
})
}
}
});
})(jQuery)
表格隔行變色插件
(function($){
$.fn.extend({
'alterBgColor': function(options){
options = $.extend({
odd: 'odd', // 偶數(shù)行樣式
even: 'even', // 奇書行樣式
selected: 'selected' // 選中行樣式
},options);
$('tbody>tr:odd' , this).addClass(options.odd);
$('tbody>tr:even' , this).addClass(options.even);
$('tbody>tr' , this).click(function(){
// 判斷當(dāng)前是否選中
var hasSelected = $(this).hasClass(options.selected);
// 如果選中,則移出selected類辫愉,否則就加上selected類
$(this)[hasSelected ? 'removeClass' : 'addClass'](options.selected).find(':checkbox').prop('checked',!hasSelected);
});
// 如果單選框默認(rèn)情況下是選擇的栅受,則高亮
$('tbody>tr:has(:checked)' , this).addClass(options.selected);
return this; // 返回this,可以繼續(xù)鏈?zhǔn)讲僮? }
});
})(jQuery)
需要注意的是上面兩個(gè)插件內(nèi)部this都是可以匹配多個(gè)元素恭朗,但是如果遇到只能匹配一個(gè)元素的時(shí)候屏镊,要each遍歷匹配的jQuery對(duì)象,而在each內(nèi)部痰腮,this就是dom對(duì)象不是jQuery對(duì)象了而芥。
封裝全局函數(shù)
這類插件是在jQuery命名空間內(nèi)部添加一個(gè)函數(shù)。
增加兩個(gè)函數(shù)诽嘉,用于去除左側(cè)空格和右側(cè)空格蔚出。
(function($){
$.extend({
ltrim: function(text){
// 假如text是undefined等非正確參數(shù),就取空字符串虫腋,防止replace方法報(bào)錯(cuò)
return (text || '').replace(/^\s+/g,'');
},
rtrim: function(text){
return (text || '').replace(/\s+$/g,'');
}
})
})(jQuery)
由于是全局函數(shù),所以要由jQuery或者$調(diào)用稀余,不能用jQuery對(duì)象去調(diào)用悦冀。
$.ltrim(' text');
$.rtrim('text ');
自定義選擇器
jQuery提供了一套方法讓用戶客戶以通過(guò)制作選擇器插件來(lái)使用自定義選擇器。jQuery選擇器執(zhí)行的步驟如下:
jQuery的選擇符解析器首先會(huì)使用一組正則表達(dá)式來(lái)解析選擇器
針對(duì)解析出的每個(gè)選擇符執(zhí)行一個(gè)選擇器函數(shù)
根據(jù)這個(gè)函數(shù)返回的是
true
還是false
來(lái)決定是否保留這個(gè)元素睛琳。
按照上面的步驟盒蟆,以$('div:gt(1)')
來(lái)舉例:
選擇器首先獲取所有的
div
元素逐個(gè)將這些
div
元素作為參數(shù)踏烙,連同括號(hào)里的1等一些參數(shù)一起傳遞給gt
對(duì)應(yīng)的選擇器函數(shù)進(jìn)行判斷如果
gt
對(duì)應(yīng)的選擇器函數(shù)返回true
則這個(gè)div
元素保留,如果返回false
則不保留历等,這樣得到的結(jié)果就是一個(gè)符合要求的div
元素集合
現(xiàn)在來(lái)看一下最關(guān)鍵的gt
的選擇器函數(shù):
gt: function(a,i,m){
return i > m[3] - 0;
}
選擇器一共接受三個(gè)參數(shù):
第一個(gè)參數(shù)為a讨惩,指向的是當(dāng)前遍歷到的dom元素。
第二個(gè)參數(shù)為i寒屯,指的是當(dāng)前遍歷到的dom元素的索引值荐捻,從0開始。
第三個(gè)參數(shù)m最為特別寡夹,它是由jQuery正則解析引擎進(jìn)一步解析后的產(chǎn)物(用match匹配出來(lái)的)处面,m是一個(gè)數(shù)組。在這時(shí)m[3]的值就是'1'菩掏。
m[0]的值是:gt(1)
m[1]的值是:
m[2]的值是gt
m[4]在上面的例子沒(méi)有體現(xiàn)魂角,假如是div:l(ss(dd))
這樣一個(gè)選擇器,m[4]就指向了(dd)
這部分智绸,另外這里的m[3]的值就是ss(dd)
野揪。
編寫一個(gè)between選擇器
例如使用$('div:between(2,5)')
能實(shí)現(xiàn)獲取索引3、4元素的功能瞧栗。
選擇器僅僅是jQuery.expr[':']
對(duì)象的一部分斯稳,所以這里是將between
函數(shù)擴(kuò)展到jQuery.expr[':']
對(duì)象中。
(function($){
$.extend(jQuery.expr[':'],{
between: function(a,i,m){
var tmp = m[3].split(','); // 將m[3]'最小值,最大值'改為['最小值','最大值']
return tmp[0] - 0 < i && i < tmp[1] - 0; // 將索引與最小和最大值進(jìn)行比較沼溜,符合要求的返回true平挑,這里-0 是隱式轉(zhuǎn)換的意思
}
})
})(jQuery)