# jQuery UI 如何使用部件庫(Widget Factory)
我們將創建一個進度條。正如下面實例所示,這可以通過調用 `jQuery.widget()` 來完成,它帶有兩個參數:一個是要創建的插件名稱,一個是包含支持插件的函數的對象文字。當插件被調用時,它將創建一個新的插件實例,所有的函數都將在該實例的語境中被執行。這與兩種重要方式的標準 jQuery 插件不同。首先,語境是一個對象,不是 DOM 元素。其次,語境總是一個單一的對象,不是一個集合。
```
$.widget( "custom.progressbar", {
_create: function() {
var progress = this.options.value + "%";
this.element
.addClass( "progressbar" )
.text( progress );
}
});
```
插件的名稱必須包含命名空間,在這個實例中,我們使用了 `custom` 命名空間。您只能創建一層深的命名空間,因此,`custom.progressbar` 是一個有效的插件名稱,而 `very.custom.progressbar` 不是一個有效的插件名稱。
我們看到部件庫(Widget Factory)為我們提供了兩個屬性。`this.element` 是一個包含一個元素的 jQuery 對象。如果我們的插件在包含多個元素的 jQuery 對象上調用,則會為每個元素創建一個單獨的插件實例,且每個實例都會有自己的 `this.element`。第二個屬性,`this.options`,是一個包含所有插件選項的鍵名/鍵值對的哈希(hash)。這些選項可以被傳給插件,如下所示:
```
$( "<div></div>" )
.appendTo( "body" )
.progressbar({ value: 20 });
```
當我們調用 `jQuery.widget()`,它通過給 `jQuery.fn`(用于創建標準插件的系統) 添加函數來擴展 jQuery。所添加的函數名稱是基于您傳給 `jQuery.widget()` 的名稱,不帶命名空間 - "progressbar"。傳給插件的選項是在插件實例中獲取設置的值。如下面的實例所示,我們可以為任意一個選項指定默認值。當設計您的 API 時,您應該清楚你的插件的最常見的使用情況,以便您可以設置適當的默認值,且確保使所有的選項真正可選。
```
$.widget( "custom.progressbar", {
// Default options.
options: {
value: 0
},
_create: function() {
var progress = this.options.value + "%";
this.element
.addClass( "progressbar" )
.text( progress );
}
});
```
### 調用插件方法
現在我們可以初始化我們的進度條,我們將通過在插件實例上調用方法來執行動作。為了定義一個插件方法,我們只在我們傳給 `jQuery.widget()` 的對象中引用函數。我們也可以通過給函數名加下劃線前綴來定義 "private" 方法。
```
$.widget( "custom.progressbar", {
options: {
value: 0
},
_create: function() {
var progress = this.options.value + "%";
this.element
.addClass( "progressbar" )
.text( progress );
},
// Create a public method.
value: function( value ) {
// No value passed, act as a getter.
if ( value === undefined ) {
return this.options.value;
}
// Value passed, act as a setter.
this.options.value = this._constrain( value );
var progress = this.options.value + "%";
this.element.text( progress );
},
// Create a private method.
_constrain: function( value ) {
if ( value > 100 ) {
value = 100;
}
if ( value < 0 ) {
value = 0;
}
return value;
}
});
```
為了在插件實例上調用方法,您可以向 jQuery 插件傳遞方法的名稱。如果您調用的方法接受參數,您只需簡單地在方法名后面傳遞這些參數即可。
**注意:**通過向同一個用于初始化插件的 jQuery 函數傳遞方法名來執行方法。這樣做是為了在保持鏈方法調用時防止 jQuery 命名空間污染。在本章節的后續,我們將看到看起來更自然的其他用法。
```
var bar = $( "<div></div>" )
.appendTo( "body" )
.progressbar({ value: 20 });
// Get the current value.
alert( bar.progressbar( "value" ) );
// Update the value.
bar.progressbar( "value", 50 );
// Get the current value again.
alert( bar.progressbar( "value" ) );
```
### 使用選項
`option()` 方法是自動提供給插件的。`option()` 方法允許您在初始化后獲取并設置選項。該方法像 jQuery 的 `.css()` 和 `.attr()` 方法:您可以只傳遞一個名稱作為取值器來使用,也可以傳遞一個名稱和值作為設置器使用,或者傳遞一個鍵名/鍵值對的哈希來設置多個值。當作為取值器使用時,插件將返回與傳入名稱相對應的選項的當前值。當作為設置器使用時,插件的 `_setOption` 方法將被每個被設置的選項調用。我們可以在我們的插件中指定一個 `_setOption` 方法來反應選項更改。對于更改選項要獨立執行的動作,我們可以重載 `_setOptions`。
```
$.widget( "custom.progressbar", {
options: {
value: 0
},
_create: function() {
this.options.value = this._constrain(this.options.value);
this.element.addClass( "progressbar" );
this.refresh();
},
_setOption: function( key, value ) {
if ( key === "value" ) {
value = this._constrain( value );
}
this._super( key, value );
},
_setOptions: function( options ) {
this._super( options );
this.refresh();
},
refresh: function() {
var progress = this.options.value + "%";
this.element.text( progress );
},
_constrain: function( value ) {
if ( value > 100 ) {
value = 100;
}
if ( value < 0 ) {
value = 0;
}
return value;
}
});
```
### 添加回調
最簡單的擴展插件的方法是添加回調,這樣用戶就可以在插件狀態發生變化時做出反應。我們可以看下面的實例如何在進度達到 100% 時添加回調到進度條。`_trigger()` 方法有三個參數:回調名稱,一個啟動回調的 jQuery 事件對象,以及一個與事件相關的數據哈希。回調名稱是唯一一個必需的參數,但是對于想要在插件上實現自定義功能的用戶,其他的參數是非常有用的。例如,如果我們創建一個可拖拽插件,我們可以在觸發拖拽回調時傳遞 mousemove 事件,這將允許用戶對基于由事件對象提供的 x/y 坐標上的拖拽做出反應。請注意,傳遞到 `_trigger()` 的原始的事件必須是一個 jQuery 事件,而不是一個原生的瀏覽器事件。
```
$.widget( "custom.progressbar", {
options: {
value: 0
},
_create: function() {
this.options.value = this._constrain(this.options.value);
this.element.addClass( "progressbar" );
this.refresh();
},
_setOption: function( key, value ) {
if ( key === "value" ) {
value = this._constrain( value );
}
this._super( key, value );
},
_setOptions: function( options ) {
this._super( options );
this.refresh();
},
refresh: function() {
var progress = this.options.value + "%";
this.element.text( progress );
if ( this.options.value == 100 ) {
this._trigger( "complete", null, { value: 100 } );
}
},
_constrain: function( value ) {
if ( value > 100 ) {
value = 100;
}
if ( value < 0 ) {
value = 0;
}
return value;
}
});
```
回調函數本質上只是附加選項,所以您可以像其他選項一樣獲取并設置它們。無論何時執行回調,都會有一個相對應的事件被觸發。事件類型是通過連接插件的名稱和回調函數名稱確定的。回調和事件都接受兩個相同的參數:一個事件對象和一個與事件相關的數據哈希,具體如下面實例所示。您的插件可能需要包含防止用戶使用的功能,為了做到這點,最好的方法就是創建愛你可撤銷的回調。用戶可以撤銷回調或者相關的事件,與他們撤銷任何一個原生事件一樣,都是通過調用 `event.preventDefault()` 或返回 `false` 來實現的。如果用戶撤銷回調,`_trigger()` 方法將返回 `false`,這樣您就能在插件內實現合適的功能。
```
var bar = $( "<div></div>" )
.appendTo( "body" )
.progressbar({
complete: function( event, data ) {
alert( "Callbacks are great!" );
}
})
.bind( "progressbarcomplete", function( event, data ) {
alert( "Events bubble and support many handlers for extreme flexibility." );
alert( "The progress bar value is " + data.value );
});
bar.progressbar( "option", "value", 100 );
```
## 本質
現在我們已經看到如何使用部件庫(Widget Factory)創建一個插件,接下來讓我們看看它實際上是如何工作的。當您調用 `jQuery.widget()` 時,它將為插件創建一個構造函數,并設置您為插件實例傳入的作為原型的對象。所有自動添加到插件的功能都來自一個基本的小部件原型,該原型定義為 `jQuery.Widget.prototype`。當創建插件實例時,會使用 `jQuery.data` 把它存儲在原始的 DOM 元素上,插件名作為鍵名。
由于插件實例直接鏈接到 DOM 元素上,您可以直接訪問插件實例,而不需要遍歷插件方法。這將允許您直接在插件實例上調用方法,而不需要傳遞字符串形式的方法名,同時您也可以直接訪問插件的屬性。
```
var bar = $( "<div></div>" )
.appendTo( "body" )
.progressbar()
.data( "progressbar" );
// Call a method directly on the plugin instance.
bar.option( "value", 50 );
// Access properties on the plugin instance.
alert( bar.options.value );
```
您也可以在不遍歷插件方法的情況下創建一個實例,通過選項和元素直接調用構造函數即可:
```
var bar = $.custom.progressbar( {}, $( "<div></div>" ).appendTo( "body") );
// Same result as before.
alert( bar.options.value );
```
### 擴展插件的原型
插件有構造函數和原型的最大好處是易于擴展插件。通過添加或修改插件原型上的方法,我們可以修改插件所有實例的行為。例如,如果我們想要向進度條添加一個方法來重置進度為 0%,我們可以向原型添加這個方法,它將在所有插件實例上可調用。
```
$.custom.progressbar.prototype.reset = function() {
this._setOption( "value", 0 );
};
```
如需了解擴展小部件的更多細節,以及如何在一個已有的小部件上創建一個全新的小部件的更多細節,請查看 [通過部件庫(Widget Factory)擴展小部件(Widget)](jqueryui-widget-extend.html)。
### 清理
在某些情況下,允許用戶應用插件,然后再取消應用。您可以通過 `_destroy()` 方法做到這一點。在 `_destroy()` 方法內,您應該撤銷在初始化和后期使用期間插件所做的一切動作。`_destroy()` 是通過 `.destroy()` 方法被調用的,`.destroy()` 方法是在插件實例綁定的元素從 DOM 上移除時被自動調用的,所以這可被用于垃圾回收。基本的 `.destroy()` 方法也處理一些常用的清理操作,比如從小部件的 DOM 元素上移除實例引用,從元素上解除綁定小部件命名空間中的所有事件,解除綁定所有使用 `_bind()` 添加的事件。
```
$.widget( "custom.progressbar", {
options: {
value: 0
},
_create: function() {
this.options.value = this._constrain(this.options.value);
this.element.addClass( "progressbar" );
this.refresh();
},
_setOption: function( key, value ) {
if ( key === "value" ) {
value = this._constrain( value );
}
this._super( key, value );
},
_setOptions: function( options ) {
this._super( options );
this.refresh();
},
refresh: function() {
var progress = this.options.value + "%";
this.element.text( progress );
if ( this.options.value == 100 ) {
this._trigger( "complete", null, { value: 100 } );
}
},
_constrain: function( value ) {
if ( value > 100 ) {
value = 100;
}
if ( value < 0 ) {
value = 0;
}
return value;
},
_destroy: function() {
this.element
.removeClass( "progressbar" )
.text( "" );
}
});
```
## 關閉注釋
部件庫(Widget Factory)只是創建有狀態插件的一種方式。這里還有一些其他不同的模型可以使用,且每個都有各自的優勢和劣勢。部件庫(Widget Factory)解決了很多常見的問題,且大大提高了效率,同時也大大提高了代碼的重用性,使它適合于 jQuery UI 及其他有狀態的插件。
請注意,在本章節中我們使用了 `custom` 命名空間。`ui` 命名空間被官方的 jQuery UI 插件保留。當創建您自己的插件時,您應該創建自己的命名空間。這樣才能更清楚插件來自哪里,屬于哪個范圍。
- jQuery UI 基礎
- jQuery UI 簡介
- jQuery UI 下載
- jQuery UI 使用
- jQuery UI 定制
- jQuery UI 工作原理
- jQuery UI 主題
- jQuery UI 主題
- jQuery UI ThemeRoller
- jQuery UI CSS 框架 API
- jQuery UI 設計主題
- jQuery UI 部件庫
- jQuery UI 部件庫(Widget Factory)
- jQuery UI 通過部件庫(Widget Factory)擴展小部件
- jQuery UI 小部件(Widget)方法調用
- jQuery UI 為什么使用部件庫(Widget Factory)
- jQuery UI 如何使用部件庫(Widget Factory)
- jQuery UI 實例
- jQuery UI 實例
- jQuery UI 實例 - 拖動(Draggable)
- jQuery UI 實例 - 放置(Droppable)
- jQuery UI 實例 - 縮放(Resizable)
- jQuery UI 實例 - 選擇(Selectable)
- jQuery UI 實例 - 排序(Sortable)
- jQuery UI 實例 - 折疊面板(Accordion)
- jQuery UI 實例 - 自動完成(Autocomplete)
- jQuery UI 實例 - 按鈕(Button)
- jQuery UI 實例 - 日期選擇器(Datepicker)
- jQuery UI 實例 - 對話框(Dialog)
- jQuery UI 實例 - 菜單(Menu)
- jQuery UI 實例 - 進度條(Progressbar)
- jQuery UI 實例 - 滑塊(Slider)
- jQuery UI 實例 - 旋轉器(Spinner)
- jQuery UI 實例 - 標簽頁(Tabs)
- jQuery UI 實例 - 工具提示框(Tooltip)
- jQuery UI 實例 - 特效(Effect)
- jQuery UI 實例 - 顯示(Show)
- jQuery UI 實例 - 隱藏(Hide)
- jQuery UI 實例 - 切換(Toggle)
- jQuery UI 實例 - 添加 Class(Add Class)
- jQuery UI 實例 - 移除 Class(Remove Class)
- jQuery UI 實例 - 切換 Class(Toggle Class)
- jQuery UI 實例 - 轉換 Class(Switch Class)
- jQuery UI 實例 - 顏色動畫(Color Animation)
- jQuery UI 實例 - 定位(Position)
- jQuery UI 實例 - 部件庫(Widget Factory)
- jQuery UI API 參考
- jQuery UI API 類別 - 特效(Effects)
- jQuery UI API - .addClass()
- jQuery UI API - 百葉窗特效(Blind Effect)
- jQuery UI API - 反彈特效(Bounce Effect)
- jQuery UI API - 剪輯特效(Clip Effect)
- jQuery UI API - 顏色動畫(Color Animation)
- jQuery UI API - 降落特效(Drop Effect)
- jQuery UI API - Easings
- jQuery UI API - .effect()
- jQuery UI API - 爆炸特效(Explode Effect)
- jQuery UI API - 淡入淡出特效(Fade Effect)
- jQuery UI API - 折疊特效(Fold Effect)
- jQuery UI API - .hide()
- jQuery UI API - 突出特效(Highlight Effect)
- jQuery UI API - 膨脹特效(Puff Effect)
- jQuery UI API - 跳動特效(Pulsate Effect)
- jQuery UI API - .removeClass()
- jQuery UI API - 縮放特效(Scale Effect)
- jQuery UI API - 震動特效(Shake Effect)
- jQuery UI API - .show()
- jQuery UI API - 尺寸特效(Size Effect)
- jQuery UI API - 滑動特效(Slide Effect)
- jQuery UI API - .switchClass()
- jQuery UI API - .toggle()
- jQuery UI API - .toggleClass()
- jQuery UI API - 轉移特效(Transfer Effect)
- jQuery UI API 類別 - 特效核心(Effects Core)
- jQuery UI API - 顏色動畫(Color Animation)
- jQuery UI API 類別 - 交互(Interactions)
- jQuery UI API - 可拖拽小部件(Draggable Widget)
- jQuery UI API - 可放置小部件(Droppable Widget)
- jQuery UI API - 鼠標交互(Mouse Interaction)
- jQuery UI API - 可調整尺寸小部件(Resizable Widget)
- jQuery UI API - 可選擇小部件(Selectable Widget)
- jQuery UI API - 可排序小部件(Sortable Widget)
- jQuery UI API 類別 - 方法重載(Method Overrides)
- jQuery UI API - .focus()
- jQuery UI API - .position()
- jQuery UI API 類別 - 方法(Methods)
- jQuery UI API - .disableSelection()
- jQuery UI API - .enableSelection()
- jQuery UI API - .removeUniqueId()
- jQuery UI API - .scrollParent()
- jQuery UI API - .uniqueId()
- jQuery UI API - .zIndex()
- jQuery UI API 類別 - 選擇器(Selectors)
- jQuery UI API - :data() Selector
- jQuery UI API - :focusable Selector
- jQuery UI API - :tabbable Selector
- jQuery UI API 類別 - 主題(Theming)
- jQuery UI API - CSS 框架(CSS Framework)
- jQuery UI API - 圖標(Icons)
- jQuery UI API - 堆疊元素(Stacking Elements)
- jQuery UI API 類別 - UI 核心(UI Core)
- jQuery UI API 類別 - 實用工具(Utilities)
- jQuery UI API - 部件庫(Widget Factory)
- jQuery UI API - 插件橋(Widget Plugin Bridge)
- jQuery UI API 類別 - 小部件(Widgets)
- jQuery UI API - 折疊面板部件(Accordion Widget)
- jQuery UI API - 自動完成部件(Autocomplete Widget)
- jQuery UI API - 按鈕部件(Button Widget)
- jQuery UI API - 日期選擇器部件(Datepicker Widget)
- jQuery UI API - 對話框部件(Dialog Widget)
- jQuery UI API - 菜單部件(Menu Widget)
- jQuery UI API - 進度條部件(Progressbar Widget)
- jQuery UI API - 滑塊部件(Slider Widget)
- jQuery UI API - 旋轉器部件(Spinner Widget)
- jQuery UI API - 標簽頁部件(Tabs Widget)
- jQuery UI API - 工具提示框部件(Tooltip Widget)
- jQuery EasyUI 簡介
- jQuery EasyUI 應用
- jQuery EasyUI 應用 - 創建 CRUD 應用
- jQuery EasyUI 應用 - 創建 CRUD 數據網格(DataGrid)
- jQuery EasyUI 應用 - 創建展開行明細編輯表單的 CRUD 應用
- jQuery EasyUI 應用 - 創建 RSS Feed 閱讀器
- jQuery EasyUI 拖放
- jQuery EasyUI 拖放 - 基本的拖動和放置
- jQuery EasyUI 拖放 - 創建拖放的購物車
- jQuery EasyUI 拖放 - 創建學校課程表
- jQuery EasyUI 菜單與按鈕
- jQuery EasyUI 菜單與按鈕 - 創建簡單的菜單
- jQuery EasyUI 菜單與按鈕 - 創建鏈接按鈕(Link Button)
- jQuery EasyUI 菜單與按鈕 - 創建菜單按鈕(Menu Button)
- jQuery EasyUI 菜單與按鈕 - 創建分割按鈕(Split Button)
- jQuery EasyUI 布局
- jQuery EasyUI 布局 - 為網頁創建邊框布局
- jQuery EasyUI 布局 - 在面板中創建復雜布局
- jQuery EasyUI 布局 - 創建折疊面板
- jQuery EasyUI 布局 - 創建標簽頁(Tabs)
- jQuery EasyUI 布局 - 動態添加標簽頁(Tabs)
- jQuery EasyUI 布局 - 添加自動播放標簽頁(Tabs)
- jQuery EasyUI 布局 - 創建 XP 風格左側面板
- jQuery EasyUI 數據網格
- jQuery EasyUI 數據網格 - 轉換 HTML 表格為數據網格
- jQuery EasyUI 數據網格 - 取得選中行數據
- jQuery EasyUI 數據網格 - 添加查詢功能
- jQuery EasyUI 數據網格 - 添加工具欄
- jQuery EasyUI 數據網格 - 創建復雜工具欄
- jQuery EasyUI 數據網格 - 設置凍結列
- jQuery EasyUI 數據網格 - 動態改變列
- jQuery EasyUI 數據網格 - 格式化列
- jQuery EasyUI 數據網格 - 設置排序
- jQuery EasyUI 數據網格 - 自定義排序
- jQuery EasyUI 數據網格 - 創建列組合
- jQuery EasyUI 數據網格 - 添加復選框
- jQuery EasyUI 數據網格 - 自定義分頁
- jQuery EasyUI 數據網格 - 啟用行內編輯
- jQuery EasyUI 數據網格 - 擴展編輯器
- jQuery EasyUI 數據網格 - 列運算
- jQuery EasyUI 數據網格 - 合并單元格
- jQuery EasyUI 數據網格 - 創建自定義視圖
- jQuery EasyUI 數據網格 - 創建頁腳摘要
- jQuery EasyUI 數據網格 - 條件設置行背景顏色
- jQuery EasyUI 數據網格 - 創建屬性網格
- jQuery EasyUI 數據網格 - 擴展行顯示細節
- jQuery EasyUI 數據網格 - 創建子網格
- jQuery EasyUI 數據網格 - 使用虛擬滾動視圖顯示海量數據
- jQuery EasyUI 數據網格 - 添加分頁組件
- jQuery EasyUI 窗口
- jQuery EasyUI 窗口 - 創建簡單窗口
- jQuery EasyUI 窗口 - 自定義窗口工具欄
- jQuery EasyUI 窗口 - 窗口與布局
- jQuery EasyUI 窗口 - 創建對話框
- jQuery EasyUI 窗口 - 自定義帶有工具條和按鈕的對話框
- jQuery EasyUI 樹形菜單
- jQuery EasyUI 樹形菜單 - 使用標記創建樹形菜單
- jQuery EasyUI 樹形菜單 - 創建異步樹形菜單
- jQuery EasyUI 樹形菜單 - 樹形菜單添加節點
- jQuery EasyUI 樹形菜單 - 創建帶復選框的樹形菜單
- jQuery EasyUI 樹形菜單 - 樹形菜單拖放控制
- jQuery EasyUI 樹形菜單 - 樹形菜單加載父/子節點
- jQuery EasyUI 樹形菜單 - 創建基礎樹形網格
- jQuery EasyUI 樹形菜單 - 創建復雜樹形網格
- jQuery EasyUI 樹形菜單 - 樹形網格動態加載
- jQuery EasyUI 樹形菜單 - 樹形網格添加分頁
- jQuery EasyUI 樹形菜單 - 樹形網格惰性加載節點
- jQuery EasyUI 表單
- jQuery EasyUI 表單 - 創建異步提交表單
- jQuery EasyUI 表單 - 表單驗證
- jQuery EasyUI 表單 - 創建樹形下拉框
- jQuery EasyUI 表單 - 格式化下拉框
- jQuery EasyUI 表單 - 過濾下拉數據網格
- jQuery EasyUI 插件
- jQuery EasyUI 擴展
- 免責聲明