ajax源码解析-jQuery Ajax事件

jQuery框架中,伴随Ajax请求会触发若干事件,我们可以订阅这些事件并在其中处理我们的逻辑。在jQuery中有两种Ajax事件:局部事件和全局事件。

局部事件(回调函数)

在$.ajax()方法的options参数中声明,可以用来设置请求数据和获取、处理响应数据。

局部事件 具体解析
beforeSend 该函数可在发送请求前修改XMLHttpRequest对象,如添加自定义 HTTP 头。签名:function (jqXHR,s) { }函数说明:传入jqXHR、s对象
dataFilter 在请求成功之后调用。若状态码为304(未修改)则不触发此回调。签名:function (data, dataType) { return newData; }
函数说明:传入返回的数据、”dataType”参数的值。并且必须返回新的数据传递给success回调函数
success 请求成功时触发。签名:function (data,statusText,jqXHR) { }
函数说明:传入返回的数据、描述状态的字符串”success”、jqXHR对象
error 请求失败时调用此函数。签名:function (jqXHR, textStatus, errorThrown) { }
函数说明:传入jqXHR对象、描述状态的字符串”error”、错误信息
complete 请求完成后回调函数 (请求成功或失败之后均调用)签名:function (jqXHR, textStatus) { }
函数说明:传入jqXHR对象、描述状态的字符串(可能值:”No Transport”、”timeout”、”notmodified”—304 “、”parsererror”、”success”、”error”)

定义方式例如:

$.ajax({
// ...
beforeSend: function(){
// Handle the beforeSend event
},
complete: function(){
// Handle the complete event
}
// ...
});

全局事件

每次Ajax请求都会触发,它会向DOM中的所有元素广播,你只需为DOM中任意元素bind好全局事件即会触发(若绑定多次,则会依次触发为事件注册的回调函数)。

全局事件 具体解析
ajaxStart 开始新的Ajax请求,并且此时jQuery对象上没有其他ajax请求正在进行。签名:function(e)
函数说明:传入事件对象
ajaxSend 当一个Ajax请求开始时触发签名:function(e,jqXHR,s)
函数说明:传入事件对象、jqXHR、s对象
ajaxSuccess 全局的请求成功 签名:function(e,jqXHR,s,data)
函数说明:传入事件对象、jqXHR、s对象、请求成功返回的相应数据
ajaxError 全局的发生错误时触发 签名:function(e,jqXHR,s,errorData)
函数说明:传入事件对象、jqXHR、s对象、请求失败返回的错误信息
ajaxComplete 全局的请求完成时触发 签名:function(e,jqXHR,s)
函数说明:传入事件对象、jqXHR、s对象
ajaxStop 当jQuery对象上正在进行Ajax请求都结束时触发。签名:function(e)
函数说明:传入事件对象

全局事件在jQuery中的声明方式:

jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
jQuery.fn[ o ] = function( f ){
return this.on( o, f );
};
});

所以我们可以使用下面两种方式定义全局事件:

// 可以用bind来绑定,用unbind来取消绑定。
$("#loading").bind("ajaxSend", function(){ … });
或者:
$("#loading").ajaxStart(function(){ … });

ajax方法完整的事件流

成功的ajax事件流
image
失败的ajax事件流
image

示例:$.ajax()触发的事件(局部事件和全局事件)

// 全局事件
$("#div_event").ajaxStart(function (e) {
doAddEvent4textarea('txt_event', '触发ajaxStart回调函数');
});
$("#div_event").ajaxSend(function (e) {
doAddEvent4textarea('txt_event', '触发ajaxSend回调函数');
});
$("#div_event").ajaxSuccess(function (e, jqXHR, s, data) {
doAddEvent4textarea('txt_event', '触发ajaxSuccess回调函数');
});
$("#div_event").ajaxError(function (e, jqXHR, s, errorData) {
doAddEvent4textarea('txt_event', '触发ajaxError回调函数');
});
$("#div_event").ajaxComplete(function (e, jqXHR, s) {
doAddEvent4textarea('txt_event', '触发ajaxComplete回调函数');
});
$("#div_event").ajaxStop(function (e) {
doAddEvent4textarea('txt_event', '触发ajaxStop回调函数');
});
// 局部事件
function bindLocalEvent(e) {
var textareaid = e.data.textareaid;
var global = e.data.global;
$.ajax('AjaxHandler.ashx?func=btn_nowTime_long',
{
type: 'get',
dataType: 'text',
global: global,
cache: false,
beforeSend: function (jqXHR, s) {
doAddEvent4textarea(textareaid, '触发beforeSend回调函数');
},
dataFilter: function (data, dataType) {
doAddEvent4textarea(textareaid, '触发dataFilter回调函数');
},
success: function (data, statusText, jqXHR) {
doAddEvent4textarea(textareaid, '触发success回调函数');
},
error: function (jqXHR, textStatus, errorThrown) {
doAddEvent4textarea(textareaid, '触发error回调函数');
},
complete: function (jqXHR, textStatus) {
doAddEvent4textarea(textareaid, '触发complete回调函数');
}
});
}
function doAddEvent4textarea(textareaid, txt) {
var textarea = $("#" + textareaid);
textarea.val(textarea.val() + '\r\n' + txt);
}

$.ajax()方法的全局事件典型用例

你的页面存在多个甚至为数不少的ajax请求,但是这些ajax请求都有相同的消息机制。ajax请求开始前显示一个提示框,提示“正在读取数据”;ajax请求成功时提示框显示“数据获取成功”;ajax请求结束后隐藏提示框。

a) 不使用全局事件的做法是:
给$.ajax()加上beforeSend、success、complete回调函数,在回调函数中加上处理提示框。
b) 使用全局事件的做法是:

$(document).ajaxStart(onStart)
.ajaxComplete(onComplete)
.ajaxSuccess(onSuccess);
function onStart(event) { //..... }
function onComplete(event, xhr, settings) { //..... }
function onSuccess(event, xhr, settings) { //..... }

sunbaixin wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!