原文鏈接:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html
要說jQuery 最成功的地方,我認為是它的可擴展性吸引了眾多開發者為其開發插件,從而建立起了一個生態系統。這好比大公司們爭相做平臺一樣,得平臺者得天下。蘋果,微軟,谷歌等巨頭,都有各自的平臺及生態圈。
學會使用jQuery并不難,因為它簡單易學,并且相信你接觸jQuery后肯定也使用或熟悉了不少其插件。如果要將能力上升一個臺階,編寫一個屬于自己的插件是個不錯的選擇。
本教程可能不是最精品的,但一定是最細致的。
jQuery插件開發模式
軟件開發過程中是需要一定的設計模式來指導開發的,有了模式,我們就能更好地組織我們的代碼,并且從這些前人總結出來的模式中學到很多好的實踐。
根據《jQuery高級編程》的描述,jQuery插件開發方式主要有三種:
- 通過$.extend()來擴展jQuery
- 通過$.fn 向jQuery添加新的方法
- 通過$.widget()應用jQuery UI的部件工廠方式創建
通常我們使用第二種方法來進行簡單插件開發,說簡單是相對于第三種方式。第三種方式是用來開發更高級jQuery部件的,該模式開發出來的部件帶有很多jQuery內建的特性,比如插件的狀態信息自動保存,各種關于插件的常用方法等,非常貼心,這里不細說。
而第一種方式又太簡單,僅僅是在jQuery命名空間或者理解成jQuery身上添加了一個靜態方法而以。所以我們調用通過$.extend()添加的函數時直接通過$符號調用($.myfunction())而不需要選中DOM元素($('#example').myfunction())。
請看下面的例子:
$.extend({
sayHello: function(name) {
console.log('Hello,' + (name ? name : 'Dude') + '!');
}
})
$.sayHello(); //調用
$.sayHello('Wayou'); //帶參調用
運行結果:
上面代碼中,通過$.extend()
向jQuery添加了一個sayHello函數,然后通過$直接調用。到此你可以認為我們已經完成了一個簡單的jQuery插件了。
但如你所見,這種方式用來定義一些輔助方法是比較方便的。比如一個自定義的console,輸出特定格式的信息,定義一次后可以通過jQuery在程序中任何需要的地方調用它。
$.extend({
log: function(message) {
var now = new Date(),
y = now.getFullYear(),
m = now.getMonth() + 1, //!JavaScript中月分是從0開始的
d = now.getDate(),
h = now.getHours(),
min = now.getMinutes(),
s = now.getSeconds(),
time = y + '/' + m + '/' + d + ' ' + h + ':' + min + ':' + s;
console.log(time + ' My App: ' + message);
}
})
$.log('initializing...'); //調用
運行結果:
但這種方式無法利用jQuery強大的選擇器帶來的便利,要處理DOM元素以及將插件更好地運用于所選擇的元素身上,還是需要使用第二種開發方式。你所見到或使用的插件也大多是通過此種方式開發。
插件開發
下面我們就來看第二種方式的jQuery插件開發。
基本方法
先看一下它的基本格式:
$.fn.pluginName = function() {
//your code goes here
}
基本上就是往$.fn上面添加一個方法,名字是我們的插件名稱。然后我們的插件代碼在這個方法里面展開。
比如我們將頁面上所有鏈接顏色轉成紅色,則可以這樣寫這個插件:
$.fn.myPlugin = function() {
//在這里面,this指的是用jQuery選中的元素
//example :$('a'),則this=$('a')
this.css('color', 'red');
}
在插件名字定義的這個函數內部,this指代的是我們在調用該插件時,用jQuery選擇器選中的元素,一般是一個jQuery類型的集合。比如$('a')返回的是頁面上所有a標簽的集合,且這個集合已經是jQuery包裝類型了,也就是說,在對其進行操作的時候可以直接調用jQuery的其他方法而不需要再用美元符號來包裝一下。
所以在上面插件代碼中,我們在this身上調用jQuery的css()方法,也就相當于在調用 $('a').css()。
理解this在這個地方的含義很重要。這樣你才知道為什么可以直接商用jQuery方法同時在其他地方this指代不同時我們又需要用jQuery重新包裝才能調用,下面會講到。初學容易被this的值整暈,但理解了就不難。
現在就可以去頁面試試我們的代碼了,在頁面上放幾個鏈接,調用插件后鏈接字體變成紅色。
<ul>
<li><a >我的微博</a></li>
<li><a href="http://http://www.cnblogs.com/Wayou/">我的博客</a></li>
<li><a >我的小站</a></li>
</ul>
<p>這是p標簽不是a標簽,我不會受影響</p>
<script src="jquery-1.11.0.min.js"></script>
<script src="jquery.myplugin.js"></script>
<script type="text/javascript">
$(function(){
$('a').myPlugin();
})
</script>
運行結果:
下面進一步,在插件代碼里處理每個具體的元素,而不是對一個集合進行處理,這樣我們就可以針對每個元素進行相應操作。
我們已經知道this指代jQuery選擇器返回的集合,那么通過調用jQuery的.each()方法就可以處理合集中的每個元素了,但此刻要注意的是,在each方法內部,this指帶的是普通的DOM元素了,如果需要調用jQuery的方法那就需要用$來重新包裝一下。
比如現在我們要在每個鏈接顯示鏈接的真實地址,首先通過each遍歷所有a標簽,然后獲取href屬性的值再加到鏈接文本后面。
更改后我們的插件代碼為:
$.fn.myPlugin = function() {
//在這里面,this指的是用jQuery選中的元素
this.css('color', 'red');
this.each(function() {
//對每個元素進行操作
$(this).append(' ' + $(this).attr('href'));
}))
}
調用代碼還是一樣的,我們通過選中頁面所有的a標簽來調用這個插件
運行結果:
到此,你已經可以編寫功能簡單的jQuery插件了。是不是也沒那么難。
下面開始jQuery插件編寫中一個重要的部分,參數的接收。
支持鏈式調用
我們都知道jQuery一個時常優雅的特性是支持鏈式調用,選擇好DOM元素后可以不斷地調用其他方法。
要讓插件不打破這種鏈式調用,只需return一下即可。
$.fn.myPlugin = function() {
//在這里面,this指的是用jQuery選中的元素
this.css('color', 'red');
return this.each(function() {
//對每個元素進行操作
$(this).append(' ' + $(this).attr('href'));
}))
}
讓插件接收參數
一個強勁的插件是可以讓使用者隨意定制的,這要求我們提供在編寫插件時就要考慮得全面些,盡量提供合適的參數。
比如現在我們不想讓鏈接只變成紅色,我們讓插件的使用者自己定義顯示什么顏色,要做到這一點很方便,只需要使用者在調用的時候傳入一個參數即可。同時我們在插件的代碼里面接收。另一方面,為了靈活,使用者可以不傳遞參數,插件里面會給出參數的默認值。
在處理插件參數的接收上,通常使用jQuery的extend方法,上面也提到過,但那是給extend方法傳遞單個對象的情況下,這個對象會合并到jQuery身上,所以我們就可以在jQuery身上調用新合并對象里包含的方法了,像上面的例子。當給extend方法傳遞一個以上的參數時,它會將所有參數對象合并到第一個里。同時,如果對象中有同名屬性時,合并的時候后面的會覆蓋前面的。
利用這一點,我們可以在插件里定義一個保存插件參數默認值的對象,同時將接收來的參數對象合并到默認對象上,最后就實現了用戶指定了值的參數使用指定的值,未指定的參數使用插件默認值。
為了演示方便,再指定一個參數fontSize,允許調用插件的時候設置字體大小。
$.fn.myPlugin = function(options) {
var defaults = {
'color': 'red',
'fontSize': '12px'
};
var settings = $.extend(defaults, options);
return this.css({
'color': settings.color,
'fontSize': settings.fontSize
});
}
現在,我們調用的時候指定顏色,字體大小未指定,會運用插件里的默認值12px。
$('a').myPlugin({
'color': '#2C9929'
});
運行結果:
同時指定顏色與字體大小:
$('a').myPlugin({
'color': '#2C9929',
'fontSize': '20px'
});
運行結果:
保護好默認參數
注意到上面代碼調用extend時會將defaults的值改變,這樣不好,因為它作為插件因有的一些東西應該維持原樣,另外就是如果你在后續代碼中還要使用這些默認值的話,當你再次訪問它時它已經被用戶傳進來的參數更改了。
一個好的做法是將一個新的空對象做為$.extend的第一個參數,defaults和用戶傳遞的參數對象緊隨其后,這樣做的好處是所有值被合并到這個空對象上,保護了插件里面的默認值。
$.fn.myPlugin = function(options) {
var defaults = {
'color': 'red',
'fontSize': '12px'
};
var settings = $.extend({},defaults, options);//將一個空對象做為第一個參數
return this.css({
'color': settings.color,
'fontSize': settings.fontSize
});
}
到此,插件可以接收和處理參數后,就可以編寫出更健壯而靈活的插件了。若要編寫一個復雜的插件,代碼量會很大,如何組織代碼就成了一個需要面臨的問題,沒有一個好的方式來組織這些代碼,整體感覺會雜亂無章,同時也不好維護,所以將插件的所有方法屬性包裝到一個對象上,用面向對象的思維來進行開發,無疑會使工作輕松很多。
喜歡本文的可以點關注喲~