三大UI框架Dijit、ExtJS、jQuery UI全方位对比_编程语言综合教程-查字典教程网
三大UI框架Dijit、ExtJS、jQuery UI全方位对比
三大UI框架Dijit、ExtJS、jQuery UI全方位对比
发布时间:2015-10-28 来源:查字典编辑
摘要:Dijit、ExtJS、jQueryUI简介Dojo是开源javascript库中起步较早的先行者之一。由AlexRussell,David...

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 控件

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

button id=buttonNode

/button

/body

/html

上述代码将会创建一个 Button 控件,并将 id 为 buttonNode 的 button 标签元素替换为实例化的控件的 DOM 树。而 button 变量则指向该控件实例的引用。此外还可以先创建控件实例,再将其插入到页面的 DOM 树中。

清单 5. Dijit 使用 new 关键字创建 Button 控件

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

p id=buttonContainer

/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 属性,自动创建控件

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

true

/head

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 属性,手动创建控件

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

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 属性。而后,在控件创建的过程中,ponentMgr 的 create() 方法会根据描述的 xtype 属性寻找在 Ext.reg 中注册过的控件类,通过反射的方式创建一个对应的控件实例。

jQuery UI 篇:jQuery UI 控件的使用方式秉承了 jQuery 一贯简洁的风格。它并不提供类似于 dojo.parser 这样的工具类来扫描页面并根据 HTML 标签自动生成控件实例,也不像传统的面向对象语言那样使用 new 关键字来创建控件,而是通过 jQuery 插件常用的链式书写方式来创建控件。

清单 12. jQuery UI 创建 Button 控件

sc ript type=text/ja vasc ript

$(function){

$(#buttonNode).button({

label: button

});

});

/sc ript

/head

button id=buttonNode/button

/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 控件方法调用

sc ript type=text/ja vasc ript

$(function){

// 为 button 标签创建 Button 控件

$(#buttonNode).button({

label: button

});

// 调用 Button 控件的 disable 方法

$(#buttonNode).button(disable

});

/sc ript

/head

button id=buttonNode/button

/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 控件,因此不会再次创建控件对象,而是取出已创建的控件对象,并设置其对应的属性。

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新编程语言综合学习
    热门编程语言综合学习
    编程开发子分类