Prototype 1.5 Ajax 使用教程
2.3 Prototype對Ajax的支持
作為一個Ajax開發框架,Prototype對Ajax開發提供了有力的支持。在Prototype中,與Ajax相關的類和對象包括:Ajax、Ajax.Responsders、Ajax.Base、Ajax.Request、Ajax. PeriodicalUpdater和Ajax.Updater,圖2-3所示為這些類和對象之間的關系及其常用屬性和方法,下面分別對這些類和對象進行介紹。
圖2-3 Prototype中Ajax相關類和對象關系示意圖
2.3.1 Ajax對象
Ajax對象為其他的Ajax功能類提供了最基本的支持,它的實現如2.2.7節中例2-10所示,其中包括一個方法getTransport和一個屬性activeRequestCount。getTransport方法返回一個XMLHttpRequest對象,activeRequestCount屬性代表正在處理中的Ajax請求的個數。
2.3.2 Ajax.Base類
Ajax.Base類是Ajax.Request類和Ajax.PeriodicalUpdater類的基類。它提供了3個方法:
l setOptions:設置Ajax操作所使用的選項。
l responseIsSuccess:判斷Ajax操作是否成功。
l responseIsFailure:判斷Ajax操作是否失敗(與responseIsSuccess相反)。
Ajax.Base類的主要作用是提取出一些公用的方法,其他類通過繼承的方式使用這些方法,實現代碼復用。
2.3.3 Ajax.Request類
這是Prototype中最經常使用的一個Ajax相關類。Ajax.Request類的方法通常是內部使用的,因此這里就不一一列舉,有興趣的讀者可以參考Prototype的源代碼。這里重點講講如何使用Ajax.Request類,首先給出一個最簡單的Ajax.Request類的應用示例,如例2-11所示,注意示例中的黑體字。
例2-11 Ajax.Request類應用示例
Ajax.Request測試頁面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>chapter 3</title>
<script type="text/javascript" language="javascript"
src="prototype.js" ></script>
<script type="text/javascript" language="javascript">
function test() {
// 創建Ajax.Request對象,發起一個Ajax請求
var myAjax = new Ajax.Request(
'data.html', // 請求的URL
{
method: 'get', // 使用GET方式發送HTTP請求
onComplete: showResponse // 指定請求成功完成時需要執行的方法
}
);
}
function showResponse(response) {
$('divResult').innerHTML = response.responseText;
}
</script>
</head>
<body>
<input type="button" value="click" onclick="test()" />
<div id="divResult" />
</body>
</html>
data.html:
<input type="text" id="name" />
<input type="button" value="Click Me" onclick="sayHi()">
Ajax.Request對象在初始化時需要提供兩個參數:第1個參數是將要請求頁面的URL,這里使用的data.html是一個普通的HTML靜態頁面;第2個參數是Ajax操作的選項,在Prototype中并沒有專門為Ajax操作選項定義一個類,通常都是像例2-11這樣,通過匿名對象的方式設置Ajax操作的參數。在例2-11中,Ajax操作選項具有兩個屬性:method表示HTTP請求方式,默認是POST方式;onComplete指定了Ajax操作完成以后(即XMLHttpRequest對象的status屬性為4時),頁面將要執行的函數。當然,Ajax操作還包括很多其他選項,如表2-1所示。
表2-1 Ajax操作選項屬性含義
屬性名稱 |
含義 |
method |
HTTP請求方式(POST/GET/HEAD)。 |
parameters |
在HTTP請求中傳入的URL格式的值列表,即URL串中問號之后的部分。 |
asynchronous |
是否做異步XMLHttpRequest請求。 |
postBody |
在POST請求方式下,傳入請求體中的內容。 |
requestHeaders |
和請求一起被傳入的HTTP頭部列表,這個列表必須含有偶數個項目,因為列表中每兩項為一組,分別代表自定義部分的名稱和與之對應的字符串值。 |
onXXXXXXXX |
在HTTP請求、響應的過程中,當XMLHttpRequest對象狀態發生變化時調用的響應函數。響應函數有5個:onUninitialized、onLoading、onLoaded、onInteractive和onComplete。傳入這些函數的參數可以有2個,其中第1個參數是執行HTTP請求的XMLHttpRequest對象,第2個參數是包含被執行的X-JSON響應的HTTP頭。 |
onSuccess |
Ajax操作成功完成時調用的響應函數,傳入的參數與onXXXXXXXX相同。 |
onFailure |
Ajax操作請求完成但出現錯誤時調用的響應函數,傳入的參數與onXXXXXXXX相同。 |
onException |
Ajax操作發生異常情況時調用的響應函數,它可以接收2個參數,其中第1個參數是執行HTTP請求的XMLHttpRequest對象,第2個參數是異常對象。 |
2.3.4 Ajax.Updater類
例2-11使用Ajax.Request類實現了頁面的局部刷新效果,而這樣類似的功能在Ajax應用中是經常使用的。因此,為了簡化這種工作,Prototype框架從Ajax.Requet類中派生出一個子類——Ajax.Updater。與Ajax.Request相比,Ajax.Updater的初始化多了一個container參數,該參數代表將要更新的頁面元素的id。例2-11的功能通過Ajax.Updater的實現,會變得更加簡單,如例2-12所示。
例2-12 Ajax.Updater類的應用示例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>chapter 3</title>
<script type="text/javascript" language="javascript"
src="prototype.js" ></script>
<script type="text/javascript" language="javascript">
function test() {
var myAjax = new Ajax.Updater(
'divResult', // 更新的頁面元素
'data.html', // 請求的URL
{
method: 'get'
}
);
}
</script>
</head>
<body>
<input type="button" value="click" onclick="test()" />
<div id="divResult" />
</body>
</html>
此外,Ajax.Updater類還有另外一個功能,如果請求的頁面內容中包括JavaScript腳本,Ajax.Updater類可以執行其中的腳本,只需要在Ajax操作選項中增加屬性“evalScripts: true”即可。對例2-11中的data.html進行修改,在其中加入JavaScript腳本,如例2-13所示。
例2-13 data.html
<script language="javascript" type="text/javascript">
sayHi = function() {
alert("Hello, " + $F('name') + "!");
}
</script>
<input type="text" id="name" />
<input type="button" value="Click Me" onclick="sayHi()">
調用Ajax.Updater的JavaScript腳本修改為:
function test() {
var myAjax = new Ajax.Updater(
'divResult', // 更新的頁面元素
'data.html', // 請求的URL
{
method: 'get',
evalScripts: true
}
);
}
這樣就可以使用data.html頁面的內容更新當前頁面中的<div>元素divResult,并且執行data.html頁面中包含的JavaScript腳本。
這里需要注意的是例2-13中sayHi函數的寫法,如果寫成
function sayHi() {
alert("Hello, " + $F('name') + "!");
}
或者
var sayHi = function() {
alert("Hello, " + $F('name') + "!");
}
程序是不能正常運行的。這是因為Ajax.Updater執行腳本是通過eval的方式,而不是將腳本內容引入到當前頁面,直接聲明的function sayHi或者用var聲明的sayHi函數,其作用域只是在這段腳本內部,外部的其他腳本不能訪問sayHi函數。而按照例2-13的方式聲明的函數,其作用域是整個window。
2.3.5 Ajax.PeriodicalUpdater類
和Ajax.Request類相似,Ajax.PeriodicalUpdater類也繼承自Ajax.Base類。在一些Ajax應用中,需要周期性地更新某些頁面元素,例如天氣預報、即時新聞等等。實現這樣的功能通常要使用JavaScript中的定時器函數setTimeout、clearTimeout等,而有了Ajax.PeriodicalUpdater類可以很好地簡化這類編碼工作。
新建一個Ajax. PeriodicalUpdater類的實例需要指定3個參數:
l container:將要更新的頁面元素id;
l url:請求的URL地址;
l options:Ajax操作選項。
和Ajax.Updater類相似,Ajax.PeriodicalUpdater類也支持動態執行JavaScript腳本,只需在Ajax操作選項中增加(evalScripts: true)屬性值即可。
Ajax.PeriodicalUpdater類支持兩個特殊的Ajax操作選項:frequency和decay。frequency參數很容易理解,既然是定時更新頁面元素,或者定時執行腳本,那么多長時間更新或者執行一次呢?frequency指的就是兩次Ajax操作之間的時間間隔,單位是秒,默認值為2秒。
如果僅指定frequency參數,程序會按照固定的時間間隔執行Ajax操作。這樣的更新策略合理嗎?答案取決于請求URL中數據的更新頻率。如果請求的數據會很有規律地按照固定頻率改變,那么只要設置一個合適的frequency值,就可以很有效地實現頁面的定時更新。然而實際應用中的數據往往不會那么理想,例如新聞,可能在一天中只有特定的一段時間更新頻率會很高,而在其他時間則幾乎沒有變化。經常遇到這樣的情況該怎么辦呢?Ajax.PeriodicalUpdater類支持的decay屬性就是為了解決這個問題而產生的。當option中帶有decay屬性時,如果請求返回的數據與上次相同,那么下次進行Ajax操作的時間間隔會乘以一個decay的系數。
為了比較明顯地看到decay屬性的效果,在請求的測試頁面中加入記錄時間的腳本,代碼如例2-14所示。
例2-14 Ajax.PeriodicalUpdater類應用示例
ex10.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>chapter 3</title>
<script type="text/javascript" language="javascript"
src="prototype.js" ></script>
<script type="text/javascript" language="javascript">
var str='';
var intcount=0;
function test() {
var myAjax = new Ajax.PeriodicalUpdater(
'divResult', // 定時更新的頁面元素
'script1.html', // 請求的URL
{
method: 'get', // HTTP請求的方式為GET
evalScripts: true, // 是否執行請求頁面中的腳本
frequency: 1, // 更新的頻率
decay: 1 // 衰減系數
}
);
}
</script>
</head>
<body>
<input type="button" value="click" onclick="test()" />
<div id="divResult" ></div>
<div id="divResult2" ></div>
</body>
</html>
script1.html:
<script language="javascript" type="text/javascript">
// Ajax.PeriodicalUpdater調用函數計數
// 在<div>元素divResult2中增加一行結果,并記錄當前時間和
// Ajax.PeriodicalUpdater的調用次數
intcount++;
str = $('divResult2').innerHTML;
$('divResult2').innerHTML = str + "count = " + intcount+ ": " + new Date() + "<br>";
</script>
例2-14的運行結果如圖2-4所示。
圖2-4 Ajax.PeriodicalUpdater類應用示例
可以看到,由于請求返回的數據一直沒有發生變化,每次請求時間的間隔是上一次的2倍(decay=2)。如果某一次請求返回的數據發生了變化,那么執行請求的時間間隔則恢復到初始值。
2.3.6 Ajax.Responders對象
Ajax.Responders對象維護了一個正在運行的Ajax對象列表,在需要實現一些全局的功能時就可以使用它。例如,在Ajax請求發出以后需要提示用戶操作正在執行中,而操作返回以后則取消提示。利用Ajax.Responders對象就可以實現這樣的功能,如例2-15所示。
例2-15 Ajax.Responders對象應用示例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>chapter 3</title>
<script type="text/javascript" language="javascript"
src="prototype.js" ></script>
<script type="text/javascript" language="javascript">
function test() {
var myAjax = new Ajax.Request(
'data.html',
{
method: 'get',
onComplete: showResponse
}
);
}
function showResponse(response) {
$('divResult').innerHTML = response.responseText;
}
var handle = {
onCreate: function() {
Element.show('loading'); // 當創建Ajax請求時,顯示loading
},
onComplete: function() {
// 當請求成功返回時,如果當前沒有其他正在運行中的Ajax請求,隱藏loading
if (Ajax.activeRequestCount == 0) {
Element.hide('loading');
}
}
};
// 將handle注冊到全局的Ajax.Responders對象中,使其生效
Ajax.Responders.register(handle);
</script>
</head>
<body>
<input type="button" value="click" onclick="test()" />
<div id="divResult" ></div>
<div id='loading' style="display:none">
<img src="loading.gif">Loading...
</div>
</body>
</html>
例2-15中定義了一個handle對象,其中包含onCreate和onComplete函數。頁面中發出任何一個Ajax請求時都會調用onCreate方法,而請求完成時都會調用onComplete方法。例2-15的運行結果如圖2-5所示。

posted on 2007-12-30 18:03 feingto 閱讀(568) 評論(0) 編輯 收藏 所屬分類: Ajax、JAVASCRIPT