YUI
技术简单介绍
什么是
YUI?
按照官方解释就是
“The Yahoo! User Interface Library (YUI)”
,中文就是
“
雅虎
用户接口库
(
简称
YUI)”
,它是一个使用
JavaScript
编写的工具和控件库。它利用
DOM
脚本
,DHTML
和
AJAX
来构造具有丰富交互功能的
Web
程序。
yui
也包含几个核心的
CSS
文件
:
一个是
css page grids
,用它可以很方便的布局你的网页。另外两个是
standard css fonts
和
standard css reset,
利用这两个
css
可以对字体等在不同浏览器中获得一致的效果
.
为什么要使用
YUI?
1)YUI
是免费的,同时授权给商业和非利益团体或个人使用。
YUI
是由
Yahoo!
的工程师所开发和支援的。
2)
方便布局网页、减少不同浏览器之间的差异:
a)CSS Page Grids :
网页版面工具,有了这个工具之后,不论是两栏、三栏或多栏的版面都不用担心了!
b)CSS Fonts :
字体工具,替不同的浏览器统一了字体、间距等样式,用来避免不同浏览器之间的差异性。
c)CSS Reset :
这也是用来统一不同浏览器之间的差异性,但是针对所有的网页元素样式。
3)
方便参考学习:在
YUI
的官方网站
(http://developer.yahoo.com/yui/)
可以下载全部的套件,也有详细的说明档案。
怎么使用
YUI?
使用
yui
的基本步骤:
在使用的
UI
控件的页面组成有
3
大块:
第一块导入依赖的
JS
文件和
CSS
文件;
第二块控件实现的
JS
代码;
第三块插入到
<body>
当中的控件,实际就是
<div>
。
把开发需要用的包全部放到项目中去,把
build
文件整个
copy
过来了,也可以根据自己的需要选择,基本上都会用到
yahoo
、
event
、
dom
这
3
个包。在自己的项目中新建一个页面,
htm
、
jsp
、
asp
等
第一块在
<head>
内插入:
<script type=”text/javascript” src=”build/yahoo/yahoo.js”></script>
<script type=”text/javascript” src=”build/event/event.js”></script>
<script type=”text/javascript” src=”build/dom/dom.js”></script>
<script type=”text/javascript” src=”build/calendar/calendar.js”></script>
<link type=”text/css” rel=”stylesheet” href=”build/calendar/assets/calendar.css” />
第二块写实现控件的
JS
代码了:
<script>
YAHOO.namespace(“example.calendar”);
function init() {
YAHOO.example.calendar.cal = new YAHOO.widget.Calendar(“cal”,”caler”);
YAHOO.example.calendar.cal.render();
}
YAHOO.util.Event.addListener(window, “load”, init);
</script>
第三块,在
<body>
里面写一个
div,
注意
id
属性就是初始化
Calendar
对象的第二个参数。
<body>
<div id=”caler”></div>
</body>
YUI
工具库提供的常用的方法、工具包和控件介绍:
较为常用的方法:
namespace
,
log
namespace :
用于创建一个全局的命名空间,使用
YUI
时,首先会自动创建
widget,util,example
三个命名空间,使用时也可以自定义命名空间。类似于在程序中建了了一个
static
变量。
例如:
YAHOO.namespace(“example.calendar”);
注意
:如有创建了一个控件或者变量并且使用了非
YUI
默认的命名空间(例如:
YAHOO.example.calendar.cal = new YAHOO.widget.Calendar(“cal”,”caler”);
)
此时必须用
namespace
方法来声明这个命名空间,否则会出错误。
log
:
用来调试的一个工具,将信息显示到
log
控件。
例如:
YAHOO.log(
“log msg”,”log type”,src
);
注意
:要看到
log
方法的效果,需要结合
Logger
控件的使用即:导入相关的
css
和
js
文件,并且新建一个
LogReader
控件(
var
myLogReader =
new
YAHOO.widget.LogReader();
)
较为常用的工具包:
dom, event, connection
dom
特点:对于大部分
DOM
操作提供了批量操作的功能,而对用户只需使用统一的函数接口就能完成单个或批量的操作,主要得益于
DOM
内部的
batch
方法。
作用
1
:
element
的查找
a) YAHOO.util.Dom.get(element)
调用
document.getElementById(element)
,获取指定的页面元素。
b) YAHOO.util.Dom.getElementsByClassName(className, tagName, rootNode)
返回指定根节点下所有标签为
tagName,class
为
className
的
DOM
节点数组。根节点为可选参数,不指定时在整个页面中查找
c) YAHOO.util.Dom.inDocument(el)
判断元素
el
是否在当前的
DOM
中,支持批量操作。
作用
2
:样式控制和访问
a) YAHOO.util.Dom.hasClass(element, className)
判断
element
标签上是否指明了
className
的
class
,支持批量操作
b) YAHOO.util.Dom.addClass(element, className)
给指定标签增加名为
className
的
class
,支持批量操作
.
c) YAHOO.util.Dom.removeClass(element, className)
删除
element
上的名为
className
的
class
,支持批量操作
作用
3
:
位置控制和访问
位置控制的相关函数
YAHOO.util.Dom.setX
YAHOO.util.Dom.setY
YAHOO.util.Dom.setXY
YAHOO.util.Dom.getX
YAHOO.util.Dom.getXY
返回元素坐标
[ left,top ]
YAHOO.util.Dom.getRegion
获取元素的坐标
Region
对象
{left,top,right,bottom}
可支持批量操作
简单的例子:
(
前提是导入了相关的
css
和
js
文件
)
</script>
<script type=”text/javascript”>
YAHOO.namespace(‘example.dom’);
YAHOO.example.dom.init = function() {
var move = function(e) {
var xy = [YAHOO.util.Event.getPageX(e), YAHOO.util.Event.getPageY(e)];
YAHOO.util.Dom.setXY(‘test’, xy);
};
YAHOO.util.Event.addListener(document, ‘click’, move);
};
YAHOO.util.Event.addListener(window, ‘load’, YAHOO.example.dom.init);
</script>
<body>
<div id=”test”></div>
</body>
event
YUI
提供的
Event
工具集简化了浏览器中事件驱动程序的编写,提供了一种简单的接口来定制事件和检查浏览器中的
event
对象。
YUI
事件工具集提供了自定义事件对象
(Custom Event)
,通过自定义事件对象可以
“
发布
”
自己感兴趣的时刻或事件,页面中的
YUI
组件能够响应这些自定义的事件并做出回应。
YUI
对事件响应的顺序:通过
YUI Event
工具集添加的事件,默认是在冒泡过程中执行事件处理函数的。从
DOM
节点上来说,是从子节点向根节点响应事件。
Event
工具集提供的方法
YAHOO.util.Event.addListener(element,eventType,fn,obj,override)
参数:
element
:为绑定事件的元素
id
,可以是一个数组,以支持批量操作
eventType
:为事件类型
fn
:为事件响应的回调函数
obj
:当
override
为
true
时,为回调函数传入的参数对象;当
override
为
false
时,该参数被忽略。
override
:
返回值类型:
Boolean
功能:给指定的
element
绑定事件响应函数
该函数是
yui
中比较常用并且较为重要的一个函数
使用方法说明:
function init() {……}
//
需要执行的函数
YAHOO.util.Event.addListener(window,
“load”
, init);
表示当
window
装载的时候调用
init
这个函数,执行函数中的内容。
connection
提供了访问
XMLHttpRequest
对象的一个简单接口
1.
创建对象
var transaction = YAHOO.util.Connect.asyncRequest(‘GET’, sUrl, callback, null);
第一个参数:指明
http
请求的方式,可用的方式包括
GET
、
POST
等
第二个参数:请求的
URL
第三个参数:回调函数,用于服务器返回数据时调用的客户端处理程序
第四个参数:
POST
方式时,提供给
URL
的
POST
参数信息。
2.
定义回调函数
在异步事物中,可以创建回调函数处理服务器的响应和相关数据,如果你不关心服务器的返回信息,也可以忽略这些回调函数,所有这些回调函数对象都是可选的,然而在大多数情况下,应该至少提供以下三个回调函数:
success
:服务器做出有效响应时的回调函数
failure
:服务器响应了但提供了错误信息时的回调函数
argument
:
success
和
failure
为了处理返回信息需要的参数,可以是对象、字符串、数字或者包含了数据的数组。
示意代码以及说明
var
postDataCallback =
//
定义请求执行后的回调函数
{
success:
function
(o)
{
hideWaitingLayer();
showDialog(
‘Information’
,
‘Submit Successful.’
);
showWorkflowDef(_submitWorkflowName);
}
,
failure:
function
(o)
{
hideWaitingLayer();
alert(
‘error:’
+o.responseText);
}
,
argument:[
‘foo’
,
‘bar’
]
}
;
var sUrl = “../WorkflowService”;
//
被请求的
URL
var postData = “method=editWorkflow&workflow_data”;//Post
方式提交请求时传递的数据
var request = YAHOO.util.Connect.asyncRequest(‘POST’, sUrl, postDataCallback, postData);
常用的控件:
Button,Datatable, Container(Dialog)
Button
控件
:
对象定义:
YAHOO.widget.Button
与传统
HTML Form
的按钮类似,不同的是它的
label
可以与
value
不一致。还可以创建带菜单的按钮,或者
radio button
、
checkbox
举例说明:
(
前提导入了相关的
css
和
js
文件
)
<script>
var oSubmitButton = new YAHOO.widget.Button({ type: “submit”,onclick: { fn: showWorkflowDef },
label: “Load”, id: “submitbutton5”, name: “submitbutton5”, value:
“search”, container: “btnLoad” });
</script>
<body>
<span id=”btnLoad”></span> //
这里也可以是
<input id = “btnLoad”></input>
</body>
Datatable
控件:
1.
定义表头
var myColumnHeaders = [
{key:”name”, text:”
姓名
“},
{key:”stdno”, text:”
学号
“},
{key:”age”, text:”
年龄
“, type:”number”}
];
YAHOO.widget.ColumnSet
的属性说明
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2. DataTable
的数据源
DS_JSArray
以对象数组的方式使用,可以是在客户端定义对象数组,也可以通过
DWR
的方式调用
JAVA
的方法获取一个
JAVA
类的
List
列表,在回调函数中以数组方式使用。
var commonDataSource = new YAHOO.util.DataSource(data);
//data
可以为用
javascript
定义的对象数组,也可以是
DWR
方式下回调函数的参数
commonDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
JSON :
JavaScript Object Notation
使用
JSON(
JavaScript Object Notation
)
对象时
var myDataSource = new YAHOO.util.DataSource(“query.action”);
myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
myDataSource.responseSchema = {
resultsList: “result.data”,//
结果集所在的
JSON
结构中的对象
fields: [“id”,”username”,”email”,”monicker”,”edit”,”
del
“]
};
XML
var myDataSource = new YAHOO.util.DataSource(“query.action”);
myDataSource.responseType = YAHOO.util.DataSource.TYPE_XML;
myDataSource.responseSchema = {
resultNode: “Item”, //
结果集所在的
XML
结构中的结点
fields: [“Company”,”Title”,”Name”,”Phone”,”Email”] //
表格的列
};
Plain Text Data(
纯文本
)
var myDataSource = new YAHOO.util.DataSource(“query.action”);
myDataSource.responseType = YAHOO.util.DataSource.TYPE_TEXT;
myDataSource.responseSchema = {
recordDelim: “”n”, //
记录的分割符
fieldDelim: “,”, //
字段的分割符
fields: [“Company”,”Title”,”Name”,”Phone”,”Email”] //
表格的列
};
其中最为常用的是
XML
形式的
DataSource
3.
创建
datatable
var myDataTable = new YAHOO.widget.DataTable(
“myContainer”, //datatable
绑定的页面
element(DIV)
myColumnSet, //
表头定义
, YAHOO.widget.ColumnSet
myDataSource, //
数据源
{caption:”My Caption”,summary:”
摘要
“} //datatable
的配置集
);
DataTable
的配置集
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Container(Dialog)
控件:
从
Panel
上扩展出来的组件,类似于
Windows
的窗口,在浏览器中提供了一种不用页面跳转就能使用交互来获取用户输入的交互方式,用户输入的数据都是通过一个标准的
HTML Form
获取的,并支持多种的获取输入数据的方式:普通的
Form
的提交,
XMLHttpRequest
,或者完全通过脚本来读取。
YAHOO.example.container.dialogInstance =
new
YAHOO.widget.Dialog(
“instanceDialog”
,
{
width :
“60em”
,
x:0,y:0,
iframe :
true
,
monitorresize:
false
,
fixedcenter :
false
,
visible :
false
,
underlay:
“none”
,
constraintoviewport :
false
,
draggable:
false
,
buttons : [
{
text:
“Close”
, handler:handleCancel, isDefault:
true }
]
}
);
YAHOO.example.container.dialogInstance.render();
<body>
<
div
id
=
“instanceDialog”
></
div
>
</body>
注意:
此时定义的这个
dialog
控件需要调用
render()
方法才能将定义中的这些属性配置到对应的这个
div
上。
(
有人会问为什么
Button
的属性配置不需要调用
render
方法呢?我个人的理解是
Button
的定义不是在一个
div
上的,而是在一个
input
或者
span
上的
)
关于引入的顺序:
1
.大部分组件都是依赖于事件驱动,并通过
YUI
提供的工具集进行
DOM
操作的,因此
yahoo.js
,
dom.js
,
event.js
或者这三个文件的合成文件
yahoo-dom-event.js
必须早于其他
YUI
的
js
文件引入
2
.
Autocomplete
如果需要从服务器取数据时,要用到
YUI
提供的
datasource.js
,因此
datasource.js
必须在
autocomplete.js
之前引入;如果是以
XHR
(
JSON
,
XML
等)的方式取数,还要用到
YUI
提供的
connection
,因此
connection.js
也必须在
autocomplete.js
之前引入;如果用到了动画方式展开下拉框,则需要保证
animation.js
在
autocomplete.js
之前引入。
3
.
Datatable
中列宽度的调整,
Container
组件中的
Overlay
以及从
Overlay
继承下来的
Dialog
,
SimpleDialog
的窗口拖动,需要用到
dragdrop.js
,因此
dragdrop.js
必须在
datatable.js
和
container.js
之前引入;如果要用到
Dialog
的动画显示效果,则需要先引入
animation.js
。
YUI
的一些不足
第一,命名规则不统一。这一点主要体现在一些
Widget
的
Configuration Attribute
和一些
CSS
样式名上。举一个简单的例子,在
YAHOO.widget.Panel
的配置属性中,
close
表示一个
Panel
是否可以被关闭,是否可以有关闭按钮,
draggable
代表这个
Panel
是否能被拖动,同样是
Boolean
的属性值,但是一个用了动词一个用了形容词,我不知道老外是否也把
close
和
draggable
的词性看的一致,反正在我看来,觉得不是很好。还有就是有些属性值使用了
“
骆驼
”
的命名方式,即非第一个单词的首字母大写,如
Panel
中的
dragOnly
属性,但是另一些属性却没有,如
fixtoviewport
、
fixedcenter
。
CSS
样式中也存在着同样的问题,你可以看到
yui-panel
和
yuimenu
这两种不同的命名方式。
带来的危害:程序员总是希望有着统一的命名方式,不想在记住属性名称记住相应的命名规则。
第二,继承体系不唯一。这一点主要体现在所有的
Widget
没有实现单根继承上。像
TabView
和
TreeView
就没有一个共同的祖先,
TabView
继承
YAHOO.util.Element
,而
TreeView
没有父类,只是用一些像
EventProvider
来丰富了自己。而
Container
中的一些组件又继承自
YAHOO.widget.Overlay
。这其中的混乱还体现在一些类只是用另一些类来
“
丰富
”
自己,通过
YAHOO.lang.augment
方法,而一些类却是继承了别的类,通过
YAHOO.lang.extend
方法。
带来的危害:不同的继承体系使得
YUI
中不同的组件构造的过程变得不一样,有些是通过
YAHOO.util.Config
的方式,有些是通过
YAHOO.util.AttributeProvider
的方式,这样去扩展
YUI
的组件变得相当的不方便,你需要去了解许多种不同的组件配置和初始化的方式。