jQuery插件開發兩個底層方法
jQuery.extend([deep ], target [, object1 ] [, objectN ] )
將兩個或更多對象的內容合並到第一個對象。
- deep 如果是true,合並成為遞歸(又叫做深拷貝)
- target 一個對象,如果附加的對象被傳遞給這個方法將那么它將接收新的屬性,如果它是唯一的參數則將擴展jQuery的命名空間,這對於插件開發者希望向 jQuery 中添加新函數時是很有用的。
- object1 一個對象,它包含額外的屬性合並到第一個參數
- 包含額外的屬性合並到第一個參數
當我們提供兩個或多個對象給$.extend()
,對象的所有屬性都添加到目標對象(target參數)
目標對象(第一個參數)將被修改,並且將通過$.extend()
返回。然而,如果我們想保留原對象,我們可以通過傳遞一個空對象作為目標對象:
var settings = $.extend({}, defaults, options);
在默認情況下,通過$.extend()合並操作是不遞歸的;
var object1 = {apple: 0,banana: {weight: 52, price: 100},cherry: 97};
var object2 = {banana: {price: 200},durian: 100};
$.extend(object1, object2);
//{apple: 0, banana: {price:200}, cherry: 97, durian: 100}
$.extend(true, object1, object2);
//{apple: 0, banana: {weight: 52, price:200}, cherry: 97, durian: 100}
jQuery.fn.extend()
在jQuery源碼中有jQuery.fn = jQuery.prototype = function(){……}
即指向jQuery對象的原型鏈,對其它進行的擴展,作用在jQuery對象上面;
總結
- jQuery.extend()能夠創建全局函數或選擇器,在實際開發中常使用jQuery.extend()方法作為插件方法傳遞系列選項結構的參數
- jQuery.fn.extend()能夠創建jQuery對象方法,一般用此方法來擴展jQuery的對象插件
jQuery插件開發通用框架
;(function($, window, document, undefined){
//Plugin code here
})(jQuery, window, document);
使用分號是為了防止因前面的代碼沒有使用分號而導致插件函數不能正確解析
傳入jQuery是為了確保在匿名函數中正確的使用jQuery對象,防止多庫共存時$沖突
傳入window、document並非必須,只不過為了更快的訪問window和document
傳入undefined是為了防止undefined變量被更改,確保undefined的准確性
jQuery插件開發的3種形式
1、類級別開發(封裝全局函數的插件)
類級別寫法:
//方式1
;(function($, window, document, undefined){
$.pluginName = function(){
//Plugin implementation code here
};
})(jQuery, window, document);
//方式2 當全局函數較多時
;(function($, window, document, undefined){
$.extend({
pluginName = function(){
//Plugin code here
};
})
})(jQuery, window, document);
調用方法:$.pluginName();
2、對象級別的插件開發
對象級別插件寫法:
//方式1
;(function($, window, document, undefined){
$.fn.pluginName = function(options) {
return this.each(function() {
//this關鍵字代表了這個插件將要執行的jQuery對象
//return this.each()使得插件能夠形成鏈式調用
var defaults = {
//pro : value
};
var settings = $.extend({}, defaults, options);
// plugin implementationcode here
});
}
})(jQuery, window, document);
//方式2
;(function($, window, document, undefined){
$.fn.extend({
pluginName : function(){
return this.each(function(){
// plugin code here
});
};
})
})(jQuery, window, document);
//方式3 這種類型的插件架構允許您封裝所有的方法在父包中,通過傳遞該方法的字符串名稱和額外的此方法需要的參數來調用它們。
;(function($, window, document, undefined){
// 在我們插件容器內,創造一個公共變量來構建一個私有方法
var privateFunction = function() {
// code here
}
// 通過字面量創造一個對象,存儲我們需要的公有方法
var methods = {
// 在字面量對象中定義每個單獨的方法
init: function() {
// 為了更好的靈活性,對來自主函數,並進入每個方法中的選擇器其中的每個單獨的元素都執行代碼
return this.each(function() {
// 為每個獨立的元素創建一個jQuery對象
var $this = $(this);
// 創建一個默認設置對象
var defaults = {
propertyName: 'value',
onSomeEvent: function() {}
}
// 使用extend方法從options和defaults對象中構造出一個settings對象
var settings = $.extend({}, defaults, options);
// 執行代碼
// 例如: privateFunction();
});
},
destroy: function() {
// 對選擇器每個元素都執行方法
return this.each(function() {
// 執行代碼
});
}
};
$.fn.pluginName = function() {
// 獲取我們的方法,遺憾的是,如果我們用function(method){}來實現,這樣會毀掉一切的
var method = arguments[0];
// 檢驗方法是否存在
if(methods[method]) {
// 如果方法存在,存儲起來以便使用
// 注意:我這樣做是為了等下更方便地使用each()
method = methods[method];
// 如果方法不存在,檢驗對象是否為一個對象(JSON對象)或者method方法沒有被傳入
} else if( typeof(method) == 'object' || !method ) {
// 如果我們傳入的是一個對象參數,或者根本沒有參數,init方法會被調用
method = methods.init;
} else {
// 如果方法不存在或者參數沒傳入,則報出錯誤。需要調用的方法沒有被正確調用
$.error( 'Method ' + method + ' does not exist on jQuery.pluginName' );
return this;
}
// 調用我們選中的方法
// 再一次注意我們是如何將each()從這里轉移到每個單獨的方法上的
return method.call(this);
}
})(jQuery, window, document);
//方式4 面向對象的插件開發 將原型和構造函數組合使用,使得通過構造函數創建的每個實例都能繼承相關屬性與方法
;(function($, window, document, undefined){
//定義Beautifier的構造函數
var Beautifier = function(ele, opt) {
this.$element = ele;
this.defaults = {
'color': 'red',
'fontSize': '12px',
'textDecoration':'none'
};
this.options = $.extend({}, this.defaults, opt);
}
//定義Beautifier的原型方法
Beautifier.prototype = {
beautify: function() {
return this.$element.css({
'color': this.options.color,
'fontSize': this.options.fontSize,
'textDecoration': this.options.textDecoration
});
}
}
//在插件中使用Beautifier對象
$.fn.myPlugin = function(options) {
//創建Beautifier的實體
var beautifier = new Beautifier(this, options);
//調用其方法
return beautifier.beautify();
}
})(jQuery, window, document);
調用方法:$.fn.pluginName();
3、通過$.widget()應用jQuery UI的部件工廠方式創建
用來開發更高級jQuery部件的,該模式開發出來的部件帶有很多jQuery內建的特性,比如插件的狀態信息自動保存,各種關於插件的常用方法等
編寫JQuery插件需要注意的地方:
- 插件的推薦命名方法為:jquery.[插件名].js
- 所有的對象方法都應當附加到JQuery.fn對象上面,而所有的全局函數都應當附加到JQuery對象本身上。
- 可以通過this.each() 來遍歷所有的元素
- 在jQuery開發中,this關鍵詞通常引用的是當前正在操作的DOM元素,但在當前的jQuery插件上下文中,this關鍵詞引用的是當前jQuery實例自身,唯一的例外是在當前jQuery集合中遍歷所有元素時,$.each循環體內的this引用的是這一輪遍歷所暴露的DOM元素
- 所有方法或函數插件,都應當以分號結尾,否則壓縮的時候可能會出現問題。為了更加保險寫,可以在插件頭部添加一個分號(;),以免他們的不規范代碼給插件帶來 影響。
- 插件應該返回一個JQuery對象,以便保證插件的可鏈式操作。