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控件(varmyLogReader = 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的属性说明
属性名称 | 含义 |
key | 列的属性名 |
text | 列的显示名称 |
type | 列的类型,包括"string", "number", "date", "currency", "checkbox", "select", "email", "link",缺省为”string” |
resizeable | Boolean值,是否可通过拖动改变列宽度 |
sortable | Boolean值,是否可排序 |
children | 定义子表头,类型为YAHOO.widget.ColumnSet |
width | 列宽度,单位为px |
className | 定义本列单元格的样式名称 |
formatter | 定义本列单元格的格式化函数 function(elCell, oRecord, oColumn, oData) |
editor | 定义可编辑的列,可用的值为”textbox”,”textarea” |
descFunction | 递减排序的函数function(a,b) |
ascFunction | 递增排序的函数function(a,b) |
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的配置集
属性名称 | 含义 |
caption | 表格的表头文字 |
summary | 表格摘要 |
paginator | Boolean值,是否分页,缺省为false |
paginatorOptions | { rowsPerPage: 每页显示的记录数, pageLinks: 最多显示的页面链接数,0为全部 currentPage:当前页 dropdownOptions:下拉框选择项,null表示不使用下拉框 } |
initialRequest | XHR方式下,附加的请求参数 |
fixedWidth | 固定表格宽度 |
scrollable | 表格有滚动条,滚动时表格表头保持不动,Boolean值 |
rowSingleSelect | 只允许选择一行,Boolean值 |
contextMenu | 表格的上下文菜单,右键弹出,YAHOO.widget.ContextMenu |
sortedBy | {colKey:排序的列, dir: 排序的方向,"desc"和"asc" } |
pageCurrent | 表格的当前页 |
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的组件变得相当的不方便,你需要去了解许多种不同的组件配置和初始化的方式。