14-讨论
16.3.3 讨论
jQuery Ajax实现的一个巨大好处是输出全局Ajax事件,可以由每个Ajax请求在所有元素上触发。在下面的解决方案中,用快捷方法将其中两个事件 ajaxStart 和 ajaxStop 绑定到ID为 ajaxStatus 的XHTML元素上。当Ajax请求在单击 #doAjaxButton 时触发,也调度 ajaxStart 事件,并调用 #ajaxStatus 元素上的 show() 。注意,这些事件是自动触发的,是使用 $.ajax() (或者 $.get() 等快捷方法)的副作用。这为在应用程序范围内的请求(如提交Ajax请求)提供了一个简洁的无耦合解决方案:
(function($) {
$(document).ready(function() {
$('#ajaxStatus')
.ajaxStart(function() {
$(this).show();
})
.ajaxStop(function() {
$(this).hide();
});
//在单击doAjaxButton时启动Ajax请求
$('#doAjaxButton').click(function() {
$.ajax({
url: 'ajax-gateway.php',
data: { val : 'Hello world' },
dataType: 'json',
success: function(json) {
//数据处理代码
$('body').append( 'Response value: ' + json.val );
}
});
});
});
})(jQuery);
我们来看看其他的一些事件和局部与全局Ajax事件之间的差异。局部Ajax事件(用 $.ajaxSetup() 建立或者在调用 $.ajax() 时定义)包括 beforeSend 、 success 、 error 和 complete 。这些事件内联定义,与每个Ajax请求紧密耦合。全局Ajax事件与本地事件交错,但是由绑定它们的元素触发,而且使用jQuery的原生事件处理架构。下面是处理局部Ajax事件(如 complete 事件)的简单回顾:
$.ajax({
type: 'GET',
url: 'ajax-gateway.php',
dataType: 'html',
complete: function(xhr, textStatus) {
//处理响应的代码
}
});
现在我们来看看成功的Ajax请求后触发事件的分类、顺序和作用域:
ajaxStart(全局)beforeSend(局部)ajaxSend(全局)success(局部)ajaxSuccess(全局)complete(局部)ajaxComplete(全局)ajaxStop(全局)
对于不成功的Ajax请求,触发事件的顺序如下, success 和 ajaxSucess 分别被 error 和 ajaxError 代替:
ajaxStart(全局)beforeSend(局部)ajaxSend(全局)error(局部)ajaxError(局部)complete(局部)ajaxComplete(全局)ajaxStop(全局)
ajaxStart 和 ajaxStop 是全局作用域里的两个特殊事件。它们的不同在于处理多个并发请求时的表现。 ajaxStart 在请求发出且没有其他请求正在进行中时触发。 ajaxStop 在一个请求完成且没有其他请求正在进行中时触发。这两个事件在发出多个并发请求的时候只触发一次:
(function($) {
$(document).ready(function() {
$('#ajaxStatus')
.ajaxStart(function() {
$(this).show();
})
.ajaxStop(function() {
$(this).hide();
});
//在单击doAjaxButton时启动Ajax请求
$('#doAjaxButton').click(function() {
$.ajax({
url: 'ajax-gateway.php',
complete: function() {
//数据处理代码
}
});
$.ajax({
url: 'ajax-data.php',
complete: function() {
//数据处理代码
}
});
});
});
})(jQuery);
global 设置可以传递给 $.ajax() 方法,该设置的值可以是 true 或者 false 。通过将 global 设置为 false ,可以禁止全局事件触发。
注意
如果你在应用程序中遇到性能问题,可能是大量元素事件传播的代价所致。在这种情况下,将
global设置为false可改进性能。
beforeSend 回调是一个局部事件,允许在请求发送之前修改 XMLHttpRequest 对象(作为参数传递)。在下面的示例中,为请求指定一个自定义HTTP标头。从回调返回 false 可以取消请求:
(function($) {
$(document).ready(function() {
//当单击doAjaxButton时启动Ajax请求
$('#doAjaxButton').click(function() {
$.ajax({
url: 'ajax-gateway.php',
beforeSend: function(xmlHttpRequest) {
xmlHttpRequest.setRequestHeader('X-SampleHeader',
'Hello world');
},
complete: function() {
//数据处理代码
}
});
});
});
})(jQuery);
现在如果我们修改解决方案来考虑所有这些事件,就会得到如下代码:
(function($) {
$(document).ready(function() {
$('#ajaxError')
.ajaxError(function(evt, xhr, ajaxOptions, error) {
$(this)
.html( 'Error: ' + ( xhr ? xhr.status : '' )
+ ' ' + ( error ? error :'Unknown' ) )
.show();
})
.ajaxSuccess(function() {
$(this).hide();
});
$('#ajaxStatus')
.ajaxStart(function() {
$(this).show();
})
.ajaxSend(function() {
$(this).html('Sending request...');
})
.ajaxStop(function() {
$(this).html('Request completed...');
var t = this;
setTimeout(function() {
$(t).hide();
}, 1500);
});
//在单击doAjaxButton时启动Ajax请求
$('#doAjaxButton').click(function() {
$.ajax({
url: 'ajax-gateway.php',
complete: function() {
//数据处理代码
}
});
});
});
})(jQuery);