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将变得非常困难,而且会耗费大量的资源。