搞定J2EE核心技术与企业应用
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

8.2 Ajax涉及的技术

前面讲过,Ajax采用XMLHttpRequest对象进行数据的异步交互,使用JavaScript增强用户体验,使用DOM组织内容,使用CSS显示外观,使用XML封装数据,这几种技术都是在软件开发中经常使用的,并没有什么新意,但正是这几种技术的组合才创造了Ajax这种神奇的技术。下面将对这几种技术进行简要讲解,以使读者大体上了解这些技术。

8.2.1 XMLHttpRequest技术

在XMLHttpRequest技术出现以前,开发人员要想实现无须刷新页面即可向服务器传输数据的功能,只能依赖于IFrame,但这种技术经常会被黑客们所利用,因此为了解决这个问题,微软公司在其IE 5.0版本上,通过一个名为XMLHTTP的ActiveX对象来实现在不刷新页面的情况下直接与服务器通信的能力。随后,其他的浏览器比如Mozilla、Opera、Safari等也实现了具有相同接口的原生对象。

在IE 5.0和IE 6.0的相关版本中,XMLHttpRequest对象的实现方式如下:

      var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

而在其他的浏览器中,XMLHttpRequest对象的实现方式如下:

      var xmlhttp = new XMLHttpRequest();

为了使其实现方式一致,在IE 7.0版本以后,XMLHttpRequest对象的实现方式也改为如下方式:

      var xmlhttp = new XMLHttpRequest();

但是为了能够有更好的兼容性,所以在创建一个XMLHttpRequest对象时,一般采用如下写法:

      var xmlhttp;
      if (window.XMLHttpRequest) {
          //其他浏览器
          xmlhttp = new XMLHttpRequest();
      } else if (window.ActiveXObject) {
          try {
              //IE浏览器
              xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (e) {
              xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
          }
      }

XMLHttpRequest可以采用同步或异步的方式与服务器通信。同步方式适用于数据量非常少的场合;一般情况下,在Ajax中都使用异步方式来与服务器通信。通过XMLHttpRequest对象的open方法的第3个参数,可以用来设定是采用同步还是异步方式,参数为true代表异步,为false代表同步,示例代码如下:

      xmlhttp.open("GET", "http://localhost:8080/index.jsp", true);

设定好通信方式之后,需要调用send方法把数据传输给服务器。如果采用POST方式给服务器发送信息,则必须先调用setRequestHeader方法,修改MIME类型,示例代码如下:

      xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

如果前面设定为采用异步方式来进行通信,则还需要设置一个回调函数,当数据返回时系统会执行这个回调函数。通过为XMLHttpRequest对象的onreadystatechange属性赋值来设置一个回调函数的示例代码如下:

      xmlhttp.onreadystatechange=function() {...};

XMLHttpRequest对象的返回值可以是XML,也可以是文本,在服务器端要进行如下设置:

      response.setContentType("text/xml;charset=utf-8");
      response.setContentType("text/plain;charset=utf-8");

在客户端则可以通过responseXML和responseText进行处理。

8.2.2 JavaScript(Java脚本语言)

一直以来,软件开发人员对JavaScript都是持贬低的态度,直到Ajax的广泛应用,JavaScript才被提到了一个新的高度。尤其是Prototype的出现,开发人员才发现:原来JavaScript也可以一种面向对象的方式来编程,也可以有类的封装和继承。

对于XMLHttpRequest对象的创建来说,下面这种创建方式无疑太麻烦,而且如果要创建的对象比较多的话,则要不断地进行选择判断。原来的示例代码如下:

      var xmlhttp;
      if (window.XMLHttpRequest) {
          //其他浏览器
          xmlhttp = new XMLHttpRequest();
      } else if (window.ActiveXObject) {
          try {
              //IE浏览器
              xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (e) {
              xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
          }
      }

针对上述问题,Prototype给出了一个很好的解决方案,在Prototype中定义了一个Try.these()函数,示例代码如下:

      var Try = {
          these: function() {
              var returnValue;
              //遍历参数,分别创建
              for (var i = 0, length = arguments.length; i < length; i++) {
                  var lambda = arguments[i];
                  try {
                      //如果创建成功,则中止
                      returnValue = lambda();
                      break;
                  } catch (e) {}
              }
              return returnValue;
          }
      }

通过这个函数,创建XMLHttpRequest对象的方式就可以改为如下所示:

      var Ajax = {
          getTransport: function() {
              return Try.these(
                  //分别创建,直到有一个成功
                  function() {return new XMLHttpRequest()},
                  function() {return new ActiveXObject('Msxml2.XMLHTTP')},
                  function() {return new ActiveXObject('Microsoft.XMLHTTP')}
              ) || false;
          },
          //当前已经使用的XMLHttpRequest对象为0
          activeRequestCount: 0
      }

读者可以看出,这样的使用方式,无论是在代码的组织上还是开发人员思路的整理上,都更加清晰,更容易理解和管理。

8.2.3 DOM(文档对象模型)

DOM(文档对象模型)是访问和操作构成文档的各种元素的应用程序接口。它是W3C组织的推荐标准,以树形结构表示HTML和XML文档,定义了遍历树和检查、修改树的节点的方法和属性。一般来说,支持JavaScript的所有浏览器都支持DOM。

先来看一棵树形图,如图8.5所示。

图8.5 一棵树形图

这棵树的根节点是A,下面有两个子节点B和C,在B的下面又有两个子节点D和E;在C的下面有一个子节点F,在F的下面有两个子节点H和I。

如果将上述描述采用DOM的形式来描述,则如下所示:

      A. firstChild=B
      A. lastChild=C
      B. firstChild=D
      B. lastChild=E
      C. firstChild=F
      F. firstChild=H
      F. lastChild=I
      B. nextSibling=C
      C. prevSibling=B
      H.parentNode.parentNode.parentNode=A

或者:

      A. childNodes[0]=B
      A. childNodes[1]=C
      B. childNodes[0]=D
      B. childNodes[1]=E
      C. childNodes[0]=F
      F. childNodes[0]=H
      F. childNodes[1]=I

由此可以看出,采用DOM的方式来表示一棵树,要比采用文字的表达方式清晰得多,而且容易操作。

在JavaScript中,用来获取ID标记的元素,最常用的方法是:

      document.getElementById()

如果要获取的元素比较多,这样写就太麻烦了,要重复很多代码,因此在Prototype中,只采用一个简单的$()符号就代替了document.getElementById()。$()的实现代码如下所示:

      function $(element) {
          if (arguments.length > 1) {
              //循环获取阐述的值
              for (var i = 0, elements = [], length = arguments.length; i < length; i++)
                  elements.push($(arguments[i]));
              return elements;
          }
          //假如是字符串类型
          if (typeof element == 'string')
              element = document.getElementById(element);
          return Element.extend(element);
      }

从上面的代码可以看出,Prototype的$()函数其实还是采用了document.getElementById()方法,只不过对该方法进行了封装,不但可以返回一个ID的元素,还可以返回多个ID的元素。

8.2.4 CSS(层叠样式表单)

CSS(Cascading Style Sheet,层叠样式表单)主要用于控制网页样式,并可以将展现样式与网页内容分离。其实也可以将网页内容和展现样式看成是面向对象的一种展示方式,这会使美工人员专著于展现样式的设计,并将其样式封装好,这样HTML开发人员就可以直接使用封装好的样式了,就好像使用类一样。

有3种使用CSS的方式:

(1)在HTML网页的<HTML>和<BODY>标记之间插入一个<STYLE>...</STYLE>标记,在该标记内定义CSS样式,示例代码如下所示:

      <html>
      <style type="text/css">
      <!--
      body {font: 12pt }
      table td {font: 12pt "Arial"; font-weight: bold; color: red}
      div {font: 12pt "Arial"; color: yellow}
      -->
      </style>
      <body>

(2)直接在标记的对象内使用CSS样式。示例代码如下所示:

      <td style=" font: 12pt "Arial"; font-weight: bold; color: red ">表格</td>

(3)单独建立CSS样式表,然后在HTML网页中通过link把样式表引入网页,示例代码如下所示:

      <head>
      <title>样式示例</title>
      <link rel=stylesheet href="../index.css" type="text/css">
      </head>

一般情况下,CSS的选择符也有3种表示方式:

● className——使用类选择符,要在标记的类名称前加“.”。

● #id——使用ID选择符,要在标记的ID前加“#”。

● Type——使用类型选择符,就是直接使用标记的名称。

8.2.5 XML(可扩展标识语言)

XML(eXtensible Markup Language,可扩展标识语言)是一种开放的、可扩展的、可自描述的语言结构,已经成为网上数据和文档传输的标准。目前,XML已经成为最普遍的数据操纵和数据传输方式。但并非所有的数据传输方式都适合使用XML进行传输,当数据量大到一定程度时,创建和解析XML将变得非常困难,而且会耗费大量的资源。