AJAX回調模組與調用模組作者:Clear 日期:2006-05-21字型大小: 小 中 大
這幾天忙著在將所有的AJAX應用程式模組化,然後在仔細研究Dave Crane,Eric Pascarello,Darren
James合著的<Ajax in
Action>後,發現老外還真是牛啊,比起目前出的其他5本ajax書來說,該書完全是一部權威級的著作,那幾本就很小兒科了.
從潛到深描述一下我又新學到的東西:
首先就是完全的模組化寫法,從prototype裡面偷來一點簡化思想,從代碼開始講起吧.
聲明ID是在寫調用對象的程式中必不可少的,目前我是這樣來寫的:
程式碼function $(objID) {
return document.getElementById(objID)
}
以後需要調用ID的時候直接$(IDName),是不是方便了很多.
經典的位置在這裡:
程式碼function $() {
return document.getElementById(arguments[0])
}
這
樣寫也同樣可以,很多人都不知道arguments是個什麼東西,其實他幾是對應的函數參數數組,第一個參數就是arguments[0],第二個就是
arguments[1],以此類推.不過arguments屬於是一個偽數組,不能直接用運算元組的方式操作arguments,而要使用定義原形的方
式,這個我會專門用一篇日誌來解說的.
按照這個思想我又寫了一個定義標籤名字的函數:
程式碼function $f(objName) {
return document.getElementsByName(objName)[0]
}
getElementsByName就是調用HTML裡面所有標籤名的一個數組對象,通過指定標籤名,來尋找對象的方法.
好了,開始將回呼函數模組.
估計很多人都使用過window.onload,而在大型項目中,可能設計到要onload很多函數,而又不可能每個頁面都使用不同的onload,因為這樣做會很麻煩.所以我們要想到一種思路,如何可以按需回呼函數.
先看代碼:
程式碼window.$loads = new Array()
window.$load = function(func,arg){
window.$loads[window.$loads.length] = [func,(arg) ? arg : ""];
}
window.onload = function(){
for(var i=0; i < window.$loads.length; i++){
var func = window.$loads[i][0];
func(window.$loads[i][1])
}
}
估計現在你應該知道怎麼做了.因為頁面載入的時候,總要首先載入window內容,所以我們擴充一個window對象數組,然後動態將所要使用的回呼函數按需要寫在不同的位置,而一旦頁面載入,可以只載入所需要的本頁面函數.
載入的方法就是在不同頁面寫上window.$load(funcName,argument),是不是很方便了。
我擴充了一下這個模組,可以載入函數的參數,當然,你不用載入參數的時候可以不寫argument.
這個模組的思路就是利用onload的一個迴圈,把需要載入的函數從數組中讀書,然後一各個運行他.
AJAX
的核心功能調用,就是通過後台JS與伺服器之間進行互動,可能我們需要調用伺服器的不同,所需要實現的功能不同,而寫出很多相類似的核心調用代碼,這樣不
僅加重了工作量,更為將來代碼的維護造成了極大的不方便.同樣我在Dave的思路上將代碼繼續擴張了一下,可以將這個模組用在不同的AJAX核心資料調用
的位置,而且還可以自訂不同調用狀態所需要的動作.
代碼:
程式碼//ajax組件
var ajax = new Object();
ajax.$x = function(url,onload,onerror,stateArray){
this.url = url;
this.req = null;
this.onload = onload;
this.onerror = (onerror) ? onerror : this.defaultError;
this.stateNum = (stateArray) ? stateArray : false;
this.loadXMLDoc(url);
}
ajax.$x.prototype = {
loadXMLDoc:function(url){
if(window.XMLHttpRequest){
this.req = new XMLHttpRequest();
if(this.req.overrideMimeType){
this.req.overrideMimeType('text/xml');
}
}else if(window.ActiveXObject){
try{
this.req = new ActiveXObject("Msxml3.XMLHTTP");
}catch(e){
try{
this.req = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try{
this.req = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){}
}
}
}
if(this.req){
try{
var loader = this;
this.req.onreadystatechange = function(){
loader.onReadyState.call(loader)
}
this.req.open("GET",url,true);
this.req.send(null);
}catch(err){
this.onerror.call(this);
}
}
},
onReadyState:function(){
var req = this.req;
var ready = req.readyState;
if(this.stateNum && ready >= 1 && ready <= 3){
this.stateNum[ready-1].call(this);
}else if(ready == 4){
var httpStatus = req.status;
if(httpStatus == 200 || httpStatus == 0){
this.onload.call(this);
}else{
this.onerror.call(this);
}
}
},
defaultError:function(){
alert("資料連線錯誤!"
+ "/n/nreadyState: " + this.req.readyState
+ "/nstatus: " + this.req.status
+ "/nheafers: " + this.req.getAllResponseHeaders()
)
}
}
不
要給這段代碼所嚇住了,這個代碼基本上可以在不改動的情況下,滿足你所有的AJAX核心資料調用功能.而這個思路就是傳統的OOP(物件導向
Object-Oriented
Programming)編程思想.可能你會覺得不可思議,是啊,之前我也給OOP嚇倒了,不過在接觸大配量序語言後發現,這是個非常優秀的思想,而我也
非常樂意地接受了他.我可以這樣說,當你擁有某種思想意識後,對於程式這個東西的掌握,是水到渠成的.當javascript使用了這樣的思路,相信傳統
的程式員也會汗顏輕視了js.
我只講一下這個控制項的調用方式,用我的驗證碼提示作為案例吧,這個東西我還沒發過,呵呵!
程式碼//檢查驗證碼對錯
function checkCode(){
//設定資料交換的伺服器端URL
var url = "common/checkCode.asp?timeStamp="+new Date().getTime();
//調用AJAX資料核心模組
//第一個參數是URL地址,
//第二個參數是AJAX資料與伺服器互動成功後所要調用的函數名
//第三個參數是AJAX資料互動失敗所調用的函數名,當然,你可以不寫,因為我在模組裡定義了一個預設的出錯處理函數
//
第四個參數是你需要在資料調用過程中的每個狀態所需要調用的函數,同樣你也可以不寫,那麼就不使用其他狀態回調,記住這個是一個數組名,就是你需要按照這
個方法寫每個狀態的回呼函數:tocheck1 function(){}, function
tocheck2(){},function tocheck3(){},切記!
var checks = new ajax.$x(url,toCheck,toCheckError)
}
//資料調用成功後的回呼函數
function toCheck(){
var res = this.req.responseXML.documentElement;
var vadcode = res.getElementsByTagName("codes")[0].firstChild.nodeValue;
var newtxt = document.forms[0].validate.value.toLowerCase()
if(newtxt == vadcode){
$("codetxt").innerHTML = "驗證碼正確!";
}else if(newtxt.length < 4){
$("codetxt").innerHTML = "驗證碼未完成!"
}else{
$("codetxt").innerHTML = "驗證碼錯誤!提示:<label ondblclick='toCopyCode(this);'>" + vadcode + "</label>"
}
}
//這是一個小彩蛋,留給你發現吧
function toCopyCode(thisCode){
document.forms[0].validate.value = thisCode.innerHTML;
$("codetxt").innerHTML = "驗證碼正確!";
}
//資料調用失敗處理
function toCheckError(){
$("codetxt").innerHTML = "驗證碼檢測錯誤!";
}
var oldCom,timeID
//這個是檢測你輸入的驗證碼過程需要調用的動作
function onComChange(){
var inputxt = document.forms[0].validate.value
if(inputxt != oldCom && Trim(inputxt) != ""){
oldCom = inputxt;
checkCode("recode")
}else if(inputxt.length == 0){
$("codetxt").innerHTML = "請輸入驗證碼!"
}
timeID = setTimeout(onComChange,100)
}
//當離開輸入驗證碼框後,停止驗證
function onblurs(){
clearTimeout(timeID)
}
也許你還有很多疑惑,授之以魚,不如授之以漁,假如你有心想學這個,相信你可以看懂.那種只靠複製別人代碼的人,我相信,我解釋地再清楚,他也看不懂.
技術他永遠都是技術,是你踏上管理事業的基礎.要相信一個不會技術的企業管理者,一定比會技術的企業管理者遜色的多.而當你同時擁有強硬的技術,英明的管理,以及敏銳的市場嗅覺的時候,恭喜你,你成功了!
而我,就在與這個目標無限接近!