当前位置:嗨网首页>书籍在线阅读

14-讨论

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

16.3.3 讨论

jQuery Ajax实现的一个巨大好处是输出全局Ajax事件,可以由每个Ajax请求在所有元素上触发。在下面的解决方案中,用快捷方法将其中两个事件 ajaxStartajaxStop 绑定到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() 时定义)包括 beforeSendsuccesserrorcomplete 。这些事件内联定义,与每个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请求,触发事件的顺序如下, successajaxSucess 分别被 errorajaxError 代替:

  • ajaxStart (全局)
  • beforeSend (局部)
  • ajaxSend (全局)
  • error (局部)
  • ajaxError (局部)
  • complete (局部)
  • ajaxComplete (全局)
  • ajaxStop (全局)

ajaxStartajaxStop 是全局作用域里的两个特殊事件。它们的不同在于处理多个并发请求时的表现。 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);