Dijit、ExtJS、jQuery UI 簡介
Dojo 是開源 ja vasc ript 庫中起步較早的先行者之一。由 Alex Russell, David Schontzler, Dylan Schiemann 等人於 2004 年創立。Dojo 具有類似 Java 的包機制 (packaging system), 將 JS 代碼根據功能進行了模塊化。主要包含 Dojo、Dijit 以及 Dojox 三個包。其中 Dojo 包提供穩定的內核 API,Dijit 包提供各類 UI 控件,Dojox 包則囊括了一系列實驗性的 API 及控件(其中不乏一些得到長期維護、穩定性已相當高的包,如 dojox.charting 包和 dojox.grid 包等)。在 Dojo 1.7 版本中,Dijit 包的內部結構被進行了更細的模塊拆分和重構,但由於撰寫本文時其尚未發布,本文中的 Dijit 相關內容仍將基於 Dojo 1.6.1 版本。
ExtJS 是當今一套被廣泛應用於前端開發的 Ajax 以及控件框架,其歷史可以追溯到 Yahoo! User Interface。在 Jack Slocum 的耕耘下,ExtJS 逐漸成長。自從 ExtJS 的 2.0 版本發布後,其使用范圍逐漸擴展到世界各地。3.X 版本中推出了更多易用的控件,ExtJS 的優勢在於其強大的控件庫,以及其對於各種前台功能的封裝,形成了完整的一套面向對象風格的 JS 控件庫。隨著和 Sencha 合並,ExtJS 也向觸摸屏發展,不過其 Ext JS 庫的發展從未停止。如今的 ExtJS 4.0 提供了更完整的 ja vasc ript API 庫,減少對 Array、Function、String 等底層類的重寫,大大的減少了不同的 JS 庫之間的沖突問題。由於 4.0 版本不向下兼容,對升級造成了一定的影響,筆者還沒有機會去深入使用 ExtJS 4.0 版本,因此本文著重介紹的是 ExtJS 3.X 版本。
jQuery UI 是 jQuery 的官方 UI 控件庫。jQuery 的大名在業內可謂是無人不知無人不曉。自 2006 年發布了其第一個穩定版之後,其輕量、易用的特點使其深入人心。jQuery UI 於 2007 年發布,它完全基於 jQuery 提供的插件機制,提供了底層交互及動畫功能以及一些可定制樣式的 UI 控件。雖然提供的控件數量不多,但它們都具備了 jQuery 小巧的特點,其使用風格也與 jQuery 核心 API 一致。撰寫本文時,其最新的穩定版本為 1.8.16,本文中關於 jQuery UI 的內容都基於該版本。
控件的使用方式
在討論各個控件庫的架構實現之前,首先讓我們從用戶的角度來看看 Dijit、ExtJS、jQuery UI 控件的的使用方式,對它們有一個直觀的了解。
控件的使用無外乎創建控件、操作控件,而在創建控件之前,我們往往需要先加載控件資源。下面就讓我們從控件資源加載開始聊起(控件 CSS 文件編寫與加載不在本文范圍內)。
控件資源加載
Dijit 篇:借助於 Dojo 提供的自動加載模塊依賴項的機制,加載 Dijit 控件所需資源非常簡單,用戶並不需要了解一個控件究竟需要哪些 JS 文件的支持,只需向頁面添加 Dojo 核心文件 dojo.js 並使用 dojo.require 函數導入控件對應模塊即可。
清單 1. Dijit 資源加載
<sc ript type="text/ja vasc ript" src="lib/dojo/dojo.js"></sc ript>
<sc ript type="text/ja vasc ript">
dojo.require("dijit.form.Button");
</sc ript>
上述代碼將自動加載 Button 控件所依賴的所有 JS 文件。
ExtJS 篇:ExtJS 本身沒有一套完整的自動加載依賴資源的機制,在大多數情況下,用戶都是使用完整的 ExtJS 庫,只需要導入 /ExtJS/adapter/ext/ext-base.js 和 /ExtJS/ext-all.js 這 2 個文件即可。一般情況下為了方便調試,會使用 ext-base-bug.js 和 ext-all-debug.js 這 2 個文件。
清單 2. ExtJS 資源加載
<sc ript type="text/ja vasc ript" src="JsLib/ExtJS/adapter/ext/ext-base-debug.js"></sc ript>
<sc ript type="text/ja vasc ript" src="JsLib/ExtJS/ext-all-debug.js"></sc ript>
當然為了節省資源也可以只加載部分的 ExtJS 資源庫,ExtJS 提供了一個名為 ext.jsb2 的文件(該文件描述了各個 JS 文件之間的依賴情況), 讓用戶查詢各個文件之間的依賴情況,方便用戶進行 ExtJS 控件的單個導入。
jQuery UI 篇:由於 jQuery 也沒有提供一套完整的自動加載依賴資源的機制,因此用戶需要手動將所使用控件的依賴資源逐一導入頁面。以 jQuery UI 中的 button 控件為例,需要通過手動為頁面添加如下代碼導入所需 js 文件。
清單 3. jQuery UI 資源加載
<!- - 導入 jquery core -->
<sc ript type="text/ja vasc ript" src="lib/jquery/jquery-1.6.2.js"></sc ript>
<!- - 導入 Button 控件所依賴的 JS 資源 -->
<sc ript type="text/ja vasc ript" src="lib/jquery/ui/jquery.ui.core.js"></sc ript>
<sc ript type="text/ja vasc ript" src="lib/jquery/ui/jquery.ui.widget.js"></sc ript>
<sc ript type="text/ja vasc ript" src="lib/jquery/ui/jquery.ui.button.js"></sc ript>
這樣手動加載資源的方式需要用戶清楚了解一個控件依賴哪些資源項,這在使用某些依賴項較多的控件,如 dialog 時會帶來困擾。雖然在最終發布的產品中,往往會將頁面中所有使用到的 JS 代碼進行合並壓縮,用戶僅需要在頁面中導入合並壓縮過的 JS 文件即可,但用戶仍需要在了解頁面需要哪些資源之後再對其進行合並壓縮(當然用戶也可以選擇一次性將所有 jQuery UI 的代碼合並壓縮到一個文件中)。
控件創建
Dijit 篇:Dijit 控件的創建方式有兩種,編程式(programmatic)以及聲明式(declarative)。
使用編程方式使用 Dijit 控件與使用傳統面向對象語言進行 UI 編程非常類似。通常只需要提供一個 DOM 節點、一個散列參數表並使用 new 關鍵字創建一個所需的 dijit 控件對象即可。
清單 4. Dijit 使用 new 關鍵字創建 Button 控件
<html>
<head>
<sc ript type="text/ja vasc ript">
dojo.addon load(function(){
var button = new dijit.form.Button({
id: "programmatic",
label: "This is a button"
}, "buttonNode");
});
</sc ript>
</head>
<body>
<div>
<button id="buttonNode">
</button>
</div>
</body>
</html>
上述代碼將會創建一個 Button 控件,並將 id 為 buttonNode 的 button 標簽元素替換為實例化的控件的 DOM 樹。而 button 變量則指向該控件實例的引用。此外還可以先創建控件實例,再將其插入到頁面的 DOM 樹中。
清單 5. Dijit 使用 new 關鍵字創建 Button 控件
<html>
<head>
<sc ript type="text/ja vasc ript">
dojo.addon load(function(){
var button = new dijit.form.Button({
id: "programmatic",
label: "This is a button"
});
button.placeAt("buttonContainer");
});
</sc ript>
</head>
<body>
<div>
<p id="buttonContainer">
</p>
</div>
</body>
</html>
上述代碼會創建一個 Button 控件實例並將其 DOM 樹其插入到 id 為 buttonContainer 的 p 標簽元素之下。
使用聲明方式使用 Dijit 控件時,需要為 HTML 標簽添加 data-dojo-type 以及 data-dojo-props 屬性,其中 data-dojo-type 表示所要生成控件的名稱,data-dojo-props 包含生成控件所需的構造參數。使用此種方法創建 Dijit 控件時,可以在導入 Dojo 核心文件時通過 parseon load 屬性配置是否自動實例化頁面上所有控件。
清單 6. 開啟 parseon load 屬性,自動創建控件
<html>
<head>
<sc ript type="text/ja vasc ript" src="lib/dojo/dojo.js" data-dojo-config="parseon load:
true"/>
</head>
<body>
<button data-dojo-type="dijit.form.Button"
data-dojo-props= 'id: "declarative"; label: "This is a button"’ />
</body>
</html>
上述代碼將會在頁面加載完畢後自動實例化一個 Button 控件。當用戶選擇關閉 parseon load 選項時,可以通過手動方式實例化所需要的控件。
清單 7. 關閉