asfman
android developer
posts - 90,  comments - 213,  trackbacks - 0
这几天忙着在将所有的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)
}
posted on 2006-08-13 15:53 汪杰 阅读(371) 评论(0)  编辑 收藏 引用 所属分类: ajax
只有注册用户登录后才能发表评论。

<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(15)

随笔分类(1)

随笔档案(90)

文章分类(727)

文章档案(712)

相册

收藏夹

http://blog.csdn.net/prodigynonsense

友情链接

最新随笔

搜索

  •  

积分与排名

  • 积分 - 469033
  • 排名 - 6

最新随笔

最新评论

阅读排行榜

评论排行榜