程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> 三大UI框架Dijit、ExtJS、jQuery UI全方位對比

三大UI框架Dijit、ExtJS、jQuery UI全方位對比

編輯:更多關於編程

     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. 關閉 parseon load 屬性,手動創建控件

      <html>

      <head>

      <sc ript type="text/ja vasc ript" src="lib/dojo/dojo.js" data-dojo-config="parseon load:

      false"/>

      <sc ript type="text/ja vasc ript">

      dojo.addon load(function(){

      dojo.parser.parse();

      });

      </sc ript>

      </head>

      <body>

      <button data-dojo-type="dijit.form.Button"

      data-dojo-props= 'id: "declarative"; label: "This is a button"’ />

      </body>

      </html>

      無論是否啟用 parseon load 選項,其本質都是使用 dojo.parser 這個對象對頁面進行掃描,解析 HTML 標簽中的屬性,並根據這些屬性內容實例化控件。需要注意的是,dojo.parser 並不是 Dojo base 的一部分,也就是說之前導入的 Dojo 核心文件 dojo.js 並不包含 dojo.parser 模塊,因此通常情況下使用 dojo.parser 的話需要額外添加代碼導入 dojo.parser 模塊。

     

      清單 8. 導入 dojo.parser 模塊

      dojo.require("dojo.parser");

      然而在使用 Button 控件時,由於我們已經導入了 dijit.form.Button 模塊 ,Dojo 會為我們自動加載所有該模塊依賴的資源,其中就包括 dojo.parser 模塊對應的 JS 文件。

      ExtJS 篇:ExtJS 控件的生成方式基於使用 new 關鍵字創建一個 ExtJS 控件對象,將其放入需要渲染的 DOM 節點中。例如:

      清單 9. ExtJS 使用 new 關鍵字創建 Button 控件

      <sc ript type="text/ja vasc ript">

      var button = new Ext.Button({

      id: 'button',

      text: 'button',

      renderTo: Ext.getBody()

      });

      </sc ript>

      上述代碼中,通過賦予 renderTo 參數一個頁面的 DOM 節點,將一個 Ext.Button 對象添加到 body 元素中,至此一個簡單的 ExtJS 控件完成了。

      此外 ,ExtJS 還允許用戶通過 add() 和 doLayout() 方法,向容器控件(繼承自 Ext.Container 類的控件)中添加缺省 renderTo 屬性的子控件。

     

      清單 10. ExtJS 向容器控件添加子控件

      <sc ript type="text/ja vasc ript">

      var mainPanel = new Ext.Panel({

      renderTo: Ext.getBody()

      });

      var button = new Ext.Button({

      id:'button'

      });

      mainPanel.add(button);

      mainPanel.doLayout();

      </sc ript>

      上述代碼首先將 mainPanel 對象渲染到 body 元素中,之後通過 add() 和 doLayout() 方法將缺省 renderTo 屬性的 button 對象添加到 mainPanel 對象中,並重新渲染 mainPanel 對象,此時 button 對象也會被渲染到頁面上。

      ExtJS 沒有像 Dijit 那樣提供通過解析 HTML 標簽的方式創建控件,但是提供了簡單的反射機制,使用戶可通過描述符來生成控件。

     

      清單 11. ExtJS 通過描述符生成控件

      <sc ript type="text/ja vasc ript">

      var mainPanel = new Ext.Panel({

      items: [{

      xtype: 'button',

      id: 'button'

      }],

      renderTo: Ext.getBody()

      });

      </sc ript>

      上述代碼首先實例化一個 ExtJS 的 Panel 控件並在其 items 屬性中添加了一段關於 button 控件的描述符,在 mainPanel 對象渲染的過程中,會遍歷 items 數組中的每一個對象,如果對象沒有被實例化,則會尋找描述符對象中的 xtype 屬性。而後,在控件創建的過程中,Ext.ComponentMgr 的 create() 方法會根據描述的 xtype 屬性尋找在 Ext.reg 中注冊過的控件類,通過反射的方式創建一個對應的控件實例。

     

      jQuery UI 篇:jQuery UI 控件的使用方式秉承了 jQuery 一貫簡潔的風格。它並不提供類似於 dojo.parser 這樣的工具類來掃描頁面並根據 HTML 標簽自動生成控件實例,也不像傳統的面向對象語言那樣使用 new 關鍵字來創建控件,而是通過 jQuery 插件常用的鏈式書寫方式來創建控件。

     

      清單 12. jQuery UI 創建 Button 控件

      <html>

      <head>

      <sc ript type="text/ja vasc ript">

      $(function){

      $("#buttonNode").button({

      label: "button"

      });

      });

      </sc ript>

      </head>

      <body>

      <div>

      <button id="buttonNode"></button>

      </div>

      </body>

      </html>

      上述代碼首先使用 jQuery 核心方法 $() 獲取頁面中所有符合查詢條件的 HTML DOM 節點(本例中只有一個 id 為 buttonNode 的 DOM 節點符合條件),並將返回的 DOM 節點數組包裝成一個 jQuery 對象。之後調用 $.ui.button 插件為 jQuery 對象提供的 button 方法根據傳入的散列參數表為這些節點創建 $.ui.button 控件。

     

      控件操作

      Dijit 篇:在創建 Dijit 控件之後,用戶可以通過 dijit.byId、dijit.findWidgets、dijit.byNode、dijit.getEnclosingWidget 等方法獲取控件實例。

      清單 13. 獲取 Dijit 控件對象

      // 獲取 widget id 為 programmatic 的控件

      var widget = dijit.byId("programmatic");

      // 獲取 body 標簽下的所有控件

      var widgets = dijit.findWidgets(dojo.body());

      // 獲取 DOM 樹根節點為以 node 的控件

      var widget = dijit.byNode(node);

      // 獲取 DOM 樹中包含 node 節點的控件

      var widget = dijit.getEnclosingWidget(node);

      獲取控件實例之後可以像使用 Java 類那樣調用控件方法。並使用 get、set 方法來獲取/設置控件的屬性。

     

      清單 14. Dijit 控件屬性獲取/設置及方法調用

      // 調用控件方法

      widget.someMethod();

      // 使用 get 獲取控件屬性

      var value = widget.get(attributeName);

      // 使用 set 設置控件屬性

      widget.set(attributeName, value);

      ExtJS 篇:ExtJS 並沒有像 Dijit 一樣提供了通過 DOM 節點查找控件的方法,而是只提供通過控件 id 號獲取控件對象的方法。

     

      清單 15. 獲取 ExtJS 控件對象

      // 獲取控件對象

      var button = Ext.getCmp("button");

      Ext.getCmp 方法返回的就是一個完整的 ExtJS 的控件對象,包含了控件對象的所有變量及方法。與 Dijit 不同的是,ExtJS 的成員變量大多是通過使用變量名去獲取/設置的,僅對部分屬性提供了對應的 get/set 方法(其原因和內容將在後文的“屬性獲取/配置方法”章節中具體闡述), 而 ExtJS 的控件方法調用還是與 Java 的方法調用類似的。

     

      清單 16. ExtJS 控件屬性屬性獲取 / 設置及方法調用

      // 獲取控件成員變量,直接訪問成員變量

      var buttonText = button.text;

      //button 控件為 width 屬性添加了 setWidth 方法,以便 width 屬性改變後,對 DOM 節點進行處理。

      button.setWidth(100);

      // 調用控件成員函數,類似 Java 的對象方法調用方式

      button.focus();

      jQuery UI 篇:操作 jQuery UI 控件的方式與創建 jQuery UI 控件的方式非常相似。

     

      清單 17. jQuery UI 控件方法調用

      <html>

      <head>

      <sc ript type="text/ja vasc ript">

      $(function){

      // 為 button 標簽創建 Button 控件

      $("#buttonNode").button({

      label: "button"

      });

      // 調用 Button 控件的 disable 方法

      $("#buttonNode").button("disable");

      });

      </sc ript>

      </head>

      <body>

      <div>

      <button id="buttonNode"></button>

      </div>

      </body>

      </html>

      上述代碼中,先後調用了兩次 button 方法,但其含義完全不同。第一次調用 button 方法時,傳入了一個散列參數表,為對應節點創建了 $.ui.button 控件。第二次調用 button 方法時,參數為一個字符串,此時 jQuery 調用了與字符串同名的控件成員方法。

     

      jQuery UI 並沒有為控件屬性提供默認的 get/set 方法,但用戶可以通過如下方式獲取/設置控件屬性:

      清單 18. jQuery UI 控件屬性獲取 / 設置

      // 調用 option 方法獲取 $.ui.button 控件的屬性表

      var options = $("#buttonNode").button("option");

      // 設置 buttonNode 節點對應的 $.ui.button 控件的 label 屬性

      $("#buttonNode").button({

      label: "changed label"

      });

      上述代碼中第二次調用 button 方法時雖然傳入的是一個散列參數表,但由於之前已經為 id 號為 buttonNode 的 DOM 節點創建過 $.ui.button 控件,因此不會再次創建控件對象,而是取出已創建的控件對象,並設置其對應的屬性。

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved