ajax onreadystatechange状态转换函数研究

有些时候我们需要将ajax请求的功能打包成一个类库方便调用,此时需要用到ajax的状态转换函数,对于执行onreadystatechange函数时,this对象到底是那个对象,不同浏览器的表现方式差异颇大。

  下面未进行打包时状态处理函数的测试,示例代码如下

HTML code
   
   
< div id ="dvAjax" ></ div > < script type ="text/javascript" > var xhr = window.XMLHttpRequest ? new XMLHttpRequest():(window.ActiveXObject ? new ActiveXObject( ' microsoft.xmlhttp ' ): false ); if ( ! xhr) throw new Error( ' 浏览器不支持Ajax ' ); xhr.open( ' GET ' , ' data.txt?_dc= ' + new Date().getTime(), true ); function statechr(){ if (xhr.readyState == 4 ){ alert( ( this === xhr) + ' /n ' + ( this === window) + ' /n ' + ( this === statechr) ) if (xhr.status == 200 || xhr.status == 0 )document.getElementById( ' dvAjax ' ).innerHTML = xhr.responseText; else alert( ' 发生错误!/nstatus= ' + xhr.status); } } xhr.onreadystatechange = statechr; xhr.send( null ); </ script >



  运行上面的代码后,下面是不同浏览器的输出,循序为IE6,IE7,IE8,FF2,FF3.6,chrome4,opera9,safari3。


  通过上图可以看出,除了IE6下this==window对象,FF2下this为状态转换函数,其他浏览器this对象都为xhr对象本身。所以在进行打包时,得注意下状态转换函数this的指向问题。

  当了解了onreadystatechange状态转换函数中this对象为什么时,我们就可以进行一些简单的打包操作了。

  打包后的简单示例代码如下。

HTML code
   
   
< div id ="dvAjax" ></ div > < script type ="text/javascript" > function Ajax(url,method,params,callback){ this .url = url; this .method = method; this .callback = callback; this .async = typeof this .callback == ' function ' // 根据回调函数判断是同步或者异步,未传递callback时为同步,本文讨论的都是异步的,同步不在考虑范围内 this .params = params; // params为处理好后的键值对 } Ajax.prototype.getObject = function (){ var xhr = window.XMLHttpRequest ? new XMLHttpRequest():(window.ActiveXObject ? new ActiveXObject( ' microsoft.xmlhttp ' ): false ); if ( ! xhr) throw new Error( ' 浏览器不支持Ajax ' ); return xhr; } Ajax.prototype.statechr = function (){ // 注意callServer中状态转换函数的添加方法,这种添加方法在IE6,FF2中不太符合闭包和继承的精神,需要使用实例名称来访问,callServer中状态转换函数不推荐这样来绑定 // 为了兼容IE6和FF2,不能使用this对象来访问xhr对象,而且还需要调用回调函数,this指向并非ajax的实例对象,this对象指向参考第一个示例代码的说明 if (xhr.ajax.readyState == 4 ){ if (xhr.ajax.status == 200 )xhr.callback(xhr.ajax.responseText); else alert( ' 发生错误/nstatus ' + xhr.ajax.status); } } Ajax.prototype.callServer = function (){ this .ajax = this .getObject(); if ( this .method.toLowerCase() == ' get ' ){ this .url += ' ? ' + this .params + ( this .params == '' ? '' : ' & ' ) + ' _dc= ' + new Date().getTime(); this .params = null ; } this .ajax.open( this .method, this .url, this .async); if ( this .async){ // 为异步时添加状态转换函数,添加此回调函数注意了,this对象指向问题和statechr状态转换函数的关系,这是第一种添加状态转换函数的方法,另外一种参考下面的【强烈推荐此方法】 this .ajax.onreadystatechange = this .statechr; // 这样来添加状态转换函数等同于上面的过程化的方法,this对象指向请考上面的方法 } this .ajax.send( this .params); if ( ! this .async) return this .ajax.responseText; // 如果未传递回调函数,则可以直接返回responseText } var xhr = new Ajax( ' data.txt ' , ' get ' , '' , function (responseText){document.getElementById( ' dvAjax ' ).innerHTML = responseText;}); xhr.callServer(); </ script >



  推荐的事件绑定方法

JScript code
   
   
Ajax.prototype.statechr = function (){ // 在所有浏览器下this对象为Ajax类的实例,不是window,ajax对象本身和状态转换函数了 if ( this .ajax.readyState == 4 ){ if ( this .ajax.status == 200 ) this .callback( this .ajax.responseText); else alert( ' 发生错误/nstatus ' + this .ajax.status); } } Ajax.prototype.callServer = function (){ this .ajax = this .getObject(); if ( this .method.toLowerCase() == ' get ' ){ this .url += ' ? ' + this .params + ( this .params == '' ? '' : ' & ' ) + ' _dc= ' + new Date().getTime(); this .params = null ; } this .ajax.open( this .method, this .url, this .async); // 做个闭包,将this对象传入,然后使用me调用statechr方法,这样this就为Ajax的实例对象了 if ( this .async) this .ajax.onreadystatechange = ( function (me){ return function (){me.statechr();}})( this ); this .ajax.send( this .params); if ( ! this .async) return this .ajax.responseText; // 如果未传递回调函数,则可以直接返回responseText }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值