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的屬性說明
屬性名稱 |
含義 |
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","
};
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的組件變得相當的不方便,你需要去了解許多種不同的組件配置和初始化的方式。