jQuery UI 通過部件庫(Widget Factory)擴展小部件
jQuery UI的部件庫(Widget Factory)使得創(chuàng)建小部件變得更加容易,這些小部件擴展了已有小部件的功能。這樣子您就能在已有的基礎(chǔ)上創(chuàng)建出功能強大的小部件,也可以在已有的小部件功能上做細微的調(diào)整。
注意:在學(xué)習(xí)本章節(jié)之前,需要明白什么是部件庫(Widget Factory),及它是怎么工作的。如果您對這些知識還不熟悉,那么請先查看如何使用部件庫(Widget Factory)章節(jié)。
創(chuàng)建小部件擴展
通過部件庫(Widget Factory)創(chuàng)建小部件是通過向$.widget()
傳遞小部件名稱和一個原型對象來完成的。下面的實例是在"custom"命名空間中創(chuàng)建一個 "superDialog"小部件。
$.widget( "custom.superDialog", {} );
為了支持擴展,$.widget()
可選性地接受作為父部件使用的小部件的構(gòu)造函數(shù)。當指定一個父部件時,把它作為第二個參數(shù)進行傳遞,放在小部件名稱后面,在小部件原型對象前面。
就像上面的實例,下面也要在"custom"命名空間中創(chuàng)建一個"superDialog"小部件。但是這次傳遞的是jQuery UI 的 dialog(對話框)小部件的構(gòu)造函數(shù)($.ui.dialog
),表示superDialog小部件應(yīng)該使用jQuery UI的dialog(對話框)小部件作為父部件。
$.widget( "custom.superDialog", $.ui.dialog, {} );
在這里,superDialog和dialog兩個小部件實質(zhì)上是等價的,只是名稱和命名空間不同而已。為了讓我們新的小部件更具特點,我們可以添加一些方法到它的原型對象上。
小部件的原型對象是傳遞給$.widget()
的最后一個參數(shù)。到目前為止,我們的實例使用的是一個空的對象?,F(xiàn)在讓我們給這個對象添加一個方法:
$.widget( "custom.superDialog", $.ui.dialog, {
red: function() {
this.element.css( "color", "red" );
}
});
$( "<div>I am red</div>" )
.superDialog()
.superDialog( "red" );
現(xiàn)在superDialog
有一個red()
方法,這會把它的文本顏色改為紅色。請注意,部件庫(Widget Factory)是如何自動設(shè)置this
為小部件的實例對象。如需了解實例上所有可用的方法和屬性列表,請訪問部件庫(Widget Factory) API 文檔。
擴展已有的方法
有時候,您需要調(diào)整或添加已有部件方法的行為。您可以把方法名稱指定為原型對象上需要重載的方法名稱。下面的實例重載了 dialog(對話框)的open()
方法。由于對話框默認是打開的,當運行這段代碼時,"open"
將會被記錄。
$.widget( "custom.superDialog", $.ui.dialog, {
open: function() {
console.log( "open" );
}
});
$( "<div>" ).superDialog();
當運行這段代碼時,有一個問題。由于我們重載了open()
的默認行為,所以dialog(對話框)不再顯示在屏幕上。
當我們在原型對象上使用方法,我們實際上是重載了原始的方法,在原型鏈中使用了一個新的方法。
為了讓父部件方法可用,部件庫(Widget Factory)提供了兩個方法:_super()
和_superApply()
。
使用 _super()
和 _superApply()
來訪問父部件
_super()
和_superApply()
在父部件中調(diào)用了同樣的方法。請看下面的實例。就像上一個實例,這個實例也重載了open()
方法來記錄"open"
。然而,這次運行_super()
是調(diào)用了dialog(對話框)的open()
,并打開對話框。
$.widget( "custom.superDialog", $.ui.dialog, {
open: function() {
console.log( "open" );
return this._super();
}
});
$( "<div>" ).superDialog();
_super()
和_superApply()
實際上等同于最初的Function.prototype.call()
和Function.prototype.apply()
方法。因此,_super()
接受一個參數(shù)列表,_superApply()
接受一個數(shù)組作為參數(shù)。下面的實例演示了這二者之間的不同。
$.widget( "custom.superDialog", $.ui.dialog, {
_setOption: function( key, value ) {
this._super( key, value );
this._superApply( arguments );
}
});
重定義小部件
jQuery UI 1.9添加了重定義小部件的功能。因此,可以不用創(chuàng)建一個新的小部件,我們只需要傳遞$.widget()
這樣一個已有的小部件名稱和構(gòu)造函數(shù)即可。下面的實例在open()
中添加了相同的記錄,但不是通過創(chuàng)建一個新的小部件來完成的。
$.widget( "ui.dialog", $.ui.dialog, {
open: function() {
console.log( "open" );
return this._super();
}
});
$( "<div>" ).dialog();
通過這個方法,我們可以擴展一個已有的小部件方法,但是仍然可以使用_super()
來訪問原始的方法 - 這些都不是通過創(chuàng)建一個新的小部件來完成的,而是直接重定義小部件即可。
小部件(Widgets)和多態(tài)性(Polymorphism)
當在小部件擴展及它們的插件之間進行交互時候,有一點值得注意,父部件的插件不能用來調(diào)用子部件元素上的方法。下面的實例演示了這一點。
$.widget( "custom.superDialog", $.ui.dialog, {} );
var dialog = $( "<div>" ).superDialog();
dialog.superDialog( "close" );
dialog.dialog( "close" );
上面的實例中,父部件的插件,dialog()
,不能調(diào)用superDialog元素上的close()
方法。如需了解更多調(diào)用小部件方法的知識,請查看小部件(Widget)方法調(diào)用。
定制個性化實例
目前為止,我們看到的實例都有在小部件原型上擴展的方法。在原型上重載的方法影響了小部件的所有實例。
為了演示這一點,請看下面的實例。dialog(對話框)的兩個勢力都使用了相同的open()
方法。
$.widget( "ui.dialog", $.ui.dialog, {
open: function() {
console.log( "open" );
return this._super();
}
});
$( "<div>" ).dialog();
$( "<div>" ).dialog();
有時候,您只需要改變小部件的某個實例的行為。為了做到這點,您需要使用正常的JavaScript屬性分配,獲得對實例的引用,并重載該方法。具體如下面實例所示。
var dialogInstance = $( "<div>" )
.dialog()
.data( "ui-dialog" );
dialogInstance.close = function() {
console.log( "close" );
};
$( "<div>" ).dialog();
$( ":data(ui-dialog)" ).dialog( "close" );
個性化實例的重載方法技術(shù)是完美的一次性定制。