jQuery UI 通過(guò)部件庫(kù)擴(kuò)展小部件

2021-10-18 17:30 更新

jQuery UI 通過(guò)部件庫(kù)(Widget Factory)擴(kuò)展小部件

jQuery UI的部件庫(kù)(Widget Factory)使得創(chuàng)建小部件變得更加容易,這些小部件擴(kuò)展了已有小部件的功能。這樣子您就能在已有的基礎(chǔ)上創(chuàng)建出功能強(qiáng)大的小部件,也可以在已有的小部件功能上做細(xì)微的調(diào)整。

注意:在學(xué)習(xí)本章節(jié)之前,需要明白什么是部件庫(kù)(Widget Factory),及它是怎么工作的。如果您對(duì)這些知識(shí)還不熟悉,那么請(qǐng)先查看如何使用部件庫(kù)(Widget Factory)章節(jié)。

創(chuàng)建小部件擴(kuò)展

通過(guò)部件庫(kù)(Widget Factory)創(chuàng)建小部件是通過(guò)向$.widget()傳遞小部件名稱和一個(gè)原型對(duì)象來(lái)完成的。下面的實(shí)例是在"custom"命名空間中創(chuàng)建一個(gè) "superDialog"小部件。

$.widget( "custom.superDialog", {} );

為了支持?jǐn)U展,$.widget()可選性地接受作為父部件使用的小部件的構(gòu)造函數(shù)。當(dāng)指定一個(gè)父部件時(shí),把它作為第二個(gè)參數(shù)進(jìn)行傳遞,放在小部件名稱后面,在小部件原型對(duì)象前面。

就像上面的實(shí)例,下面也要在"custom"命名空間中創(chuàng)建一個(gè)"superDialog"小部件。但是這次傳遞的是jQuery UI 的 dialog(對(duì)話框)小部件的構(gòu)造函數(shù)($.ui.dialog),表示superDialog小部件應(yīng)該使用jQuery UI的dialog(對(duì)話框)小部件作為父部件。

$.widget( "custom.superDialog", $.ui.dialog, {} );

在這里,superDialog和dialog兩個(gè)小部件實(shí)質(zhì)上是等價(jià)的,只是名稱和命名空間不同而已。為了讓我們新的小部件更具特點(diǎn),我們可以添加一些方法到它的原型對(duì)象上。

小部件的原型對(duì)象是傳遞給$.widget()的最后一個(gè)參數(shù)。到目前為止,我們的實(shí)例使用的是一個(gè)空的對(duì)象?,F(xiàn)在讓我們給這個(gè)對(duì)象添加一個(gè)方法:

$.widget( "custom.superDialog", $.ui.dialog, {
    red: function() {
        this.element.css( "color", "red" );
    }
});
 
// Create a new <div>, convert it into a superDialog, and call the red() method.
$( "<div>I am red</div>" )
    .superDialog()
    .superDialog( "red" );

現(xiàn)在superDialog有一個(gè)red()方法,這會(huì)把它的文本顏色改為紅色。請(qǐng)注意,部件庫(kù)(Widget Factory)是如何自動(dòng)設(shè)置this為小部件的實(shí)例對(duì)象。如需了解實(shí)例上所有可用的方法和屬性列表,請(qǐng)?jiān)L問(wèn)部件庫(kù)(Widget Factory) API 文檔

擴(kuò)展已有的方法

有時(shí)候,您需要調(diào)整或添加已有部件方法的行為。您可以把方法名稱指定為原型對(duì)象上需要重載的方法名稱。下面的實(shí)例重載了 dialog(對(duì)話框)的open()方法。由于對(duì)話框默認(rèn)是打開(kāi)的,當(dāng)運(yùn)行這段代碼時(shí),"open"將會(huì)被記錄。

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
    }
});
 
// Create a new <div>, and convert it into a superDialog.
$( "<div>" ).superDialog();

當(dāng)運(yùn)行這段代碼時(shí),有一個(gè)問(wèn)題。由于我們重載了open()的默認(rèn)行為,所以dialog(對(duì)話框)不再顯示在屏幕上。

當(dāng)我們?cè)谠蛯?duì)象上使用方法,我們實(shí)際上是重載了原始的方法,在原型鏈中使用了一個(gè)新的方法。

為了讓父部件方法可用,部件庫(kù)(Widget Factory)提供了兩個(gè)方法:_super()_superApply()。

使用 _super()_superApply() 來(lái)訪問(wèn)父部件

_super()_superApply()在父部件中調(diào)用了同樣的方法。請(qǐng)看下面的實(shí)例。就像上一個(gè)實(shí)例,這個(gè)實(shí)例也重載了open()方法來(lái)記錄"open"。然而,這次運(yùn)行_super()是調(diào)用了dialog(對(duì)話框)的open(),并打開(kāi)對(duì)話框。

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
 
        // Invoke the parent widget's open().
        return this._super();
    }
});
 
$( "<div>" ).superDialog();

_super()_superApply()實(shí)際上等同于最初的Function.prototype.call()Function.prototype.apply()方法。因此,_super()接受一個(gè)參數(shù)列表,_superApply()接受一個(gè)數(shù)組作為參數(shù)。下面的實(shí)例演示了這二者之間的不同。

$.widget( "custom.superDialog", $.ui.dialog, {
    _setOption: function( key, value ) {
 
        // Both invoke dialog's setOption() method. _super() requires the arguments
        // be passed as an argument list, _superApply() as a single array.
        this._super( key, value );
        this._superApply( arguments );
    }
});

重定義小部件

jQuery UI 1.9添加了重定義小部件的功能。因此,可以不用創(chuàng)建一個(gè)新的小部件,我們只需要傳遞$.widget()這樣一個(gè)已有的小部件名稱和構(gòu)造函數(shù)即可。下面的實(shí)例在open()中添加了相同的記錄,但不是通過(guò)創(chuàng)建一個(gè)新的小部件來(lái)完成的。

$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
$( "<div>" ).dialog();

通過(guò)這個(gè)方法,我們可以擴(kuò)展一個(gè)已有的小部件方法,但是仍然可以使用_super()來(lái)訪問(wèn)原始的方法 - 這些都不是通過(guò)創(chuàng)建一個(gè)新的小部件來(lái)完成的,而是直接重定義小部件即可。

小部件(Widgets)和多態(tài)性(Polymorphism)

當(dāng)在小部件擴(kuò)展及它們的插件之間進(jìn)行交互時(shí)候,有一點(diǎn)值得注意,父部件的插件不能用來(lái)調(diào)用子部件元素上的方法。下面的實(shí)例演示了這一點(diǎn)。

$.widget( "custom.superDialog", $.ui.dialog, {} );
 
var dialog = $( "<div>" ).superDialog();
 
// This works.
dialog.superDialog( "close" );
 
// This doesn't.
dialog.dialog( "close" );

上面的實(shí)例中,父部件的插件,dialog(),不能調(diào)用superDialog元素上的close()方法。如需了解更多調(diào)用小部件方法的知識(shí),請(qǐng)查看小部件(Widget)方法調(diào)用。

定制個(gè)性化實(shí)例

目前為止,我們看到的實(shí)例都有在小部件原型上擴(kuò)展的方法。在原型上重載的方法影響了小部件的所有實(shí)例。

為了演示這一點(diǎn),請(qǐng)看下面的實(shí)例。dialog(對(duì)話框)的兩個(gè)勢(shì)力都使用了相同的open()方法。

$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
// Create two dialogs, both use the same open(), therefore "open" is logged twice.
$( "<div>" ).dialog();
$( "<div>" ).dialog();

有時(shí)候,您只需要改變小部件的某個(gè)實(shí)例的行為。為了做到這點(diǎn),您需要使用正常的JavaScript屬性分配,獲得對(duì)實(shí)例的引用,并重載該方法。具體如下面實(shí)例所示。

var dialogInstance = $( "<div>" )
    .dialog()
    // Retrieve the dialog's instance and store it.
    .data( "ui-dialog" );
 
// Override the close() method for this dialog
dialogInstance.close = function() {
    console.log( "close" );
};
 
// Create a second dialog
$( "<div>" ).dialog();
 
// Select both dialogs and call close() on each of them.
// "close" will only be logged once.
$( ":data(ui-dialog)" ).dialog( "close" );

個(gè)性化實(shí)例的重載方法技術(shù)是完美的一次性定制。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)