??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
function
Hashtable()
{
this
._hash
=
new
Object();
this
.add
=
function
(key,value){
if
(
typeof
(key)
!=
"
undefined
"
){
if
(
this
.contains(key)
==
false
){
this
._hash[key]
=
typeof
(value)
==
"
undefined
"
?
null
:value;
return
true
;
}
else
{
return
false
;
}
}
else
{
return
false
;
}
}
this
.remove
=
function
(key){
delete
this
._hash[key];}
this
.count
=
function
(){
var
i
=
0
;
for
(
var
k
in
this
._hash){i
++
;}
return
i;}
this
.items
=
function
(key){
return
this
._hash[key];}
this
.contains
=
function
(key){
return
typeof
(
this
._hash[key])
!=
"
undefined
"
;}
this
.clear
=
function
(){
for
(
var
k
in
this
._hash){
delete
this
._hash[k];}}
}
var
a
=
new
Hashtable();
a.add(
"
aa
"
);
a.add(
"
bb
"
,
2342
);
a.add(
"
bb
"
,
2342
);
a.remove(
"
aa
"
);
alert(a.count());
alert(a.contains(
"
bb
"
));
alert(a.contains(
"
aa
"
));
alert(a.items(
"
bb
"
));
</
script
>
]]>
我们q是从我们上一文章的代码Q喏Q就在上面)开始我们的学习Q你可以去阅d来作为参考?BR>
q里是q个HTML面Q带jsQ:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="zh-cn" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>如何使用ajax开发web应用E序--CZ</title>
<script type="text/javascript"><!--
function ajaxRead(file){
var xmlObj = null;
if(window.XMLHttpRequest){
xmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return;
}
xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
processXML(xmlObj.responseXML);
}
}
xmlObj.open ('GET', file, true);
xmlObj.send ('');
}
function processXML(obj){
var dataArray = obj.getElementsByTagName('pets')[0].childNodes;
var dataArrayLen = dataArray.length;
var insertData = '<table><tr><th>'
+ 'Pets</th><th>Tasks</th></tr>';
for (var i=0; i<dataArrayLen; i++){
if(dataArray[i].tagName){
insertData += '<tr><td>' + dataArray[i].tagName + '</td>'
+ '<td>' + dataArray[i].getAttribute('tasks') + '</td></tr>';
}
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}
//--></script>
<style type="text/css"><!--
table, tr, th, td {
border: solid 1px #000;
border-collapse: collapse;
padding: 5px;
}
--></style>
</head>
<body>
<h1>使用Ajax开发web应用E序</h1>
<p>q个面演示了AJAX技术如何通过动态读取一个远E文件来更新一个网늚内容Q-不需要Q何网늚重新加蝲。注意:q个例子对于止js的用h说没有效果?lt;/p>
<p>q个面演C如从取回ƈ处理成组的XML数据。被取回的数据将会以表格形式输出到底下?BR><a href="#" onclick="ajaxRead('data_3.php'); return false">查看演示</a>.</p>
<div id="dataArea"></div>
</body>
</html>
(sheneyan注:CZ见http://sheneyan.com/html/article/ajax/example_3.html)
注意Q这里唯一的变化就是我们将我们的ajaxRead()中的“data_2.xml”改成了“data_3.php”。这是因为我们将使用php来输出XMLQ如果你在你的浏览器里打开q个PHP文gQ它会以一个XML文g的Ş式展现出来-Q我们只是要在这个文件中q行操作而不只是一个简单的XMLQ。这个PHP文g的输出类|
<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<?tasks="喂食, 饮水, 抓蟩? />
<?tasks="喂食, 饮水, 带出去遛? />
<?tasks="喂食, 查氧气,水的U度Q其? />
</pets>
</data>
(Sheneyan注:CZ׃提供了,参考底下说明即可?
q只是输出结果,我们准备从一个mysql数据库中获取q些信息。从现在P我们可以直接在我们的数据库中修改数据而不是手动修改XML文g。用AJAX通过PHP来取得数据,q将它获取到一个页面上Q-所有这些,仍然不需要重新加载网c?BR>
W一步是q接到mysql去获取数据。这文章的重点在javascriptQ所以我不会解释下面的代码如何工作,你需要自己去了解如何q接mysql数据库?BR><?php
$user = "admin";
$pass = "adminpass";
$host = "localhost";
$conn = mysql_connect($host, $user, $pass) or die("Unable to connect to MySQL.");
$db = mysql_select_db("pets",$conn) or die("Could not select the database.");
mysql_close($db);
?>
只要你连接了数据库,你可以通过底下的查询来获取信息Q?BR><?php
$user = "admin";
$pass = "adminpass";
$host = "localhost";
$conn = mysql_connect($host, $user, $pass) or die("Unable to connect to MySQL.");
$db = mysql_select_db("pets",$conn) or die("Could not select the database.");
$result = mysql_query("SELECT * FROM `pets`");
if(mysql_num_rows ($result) == 0){
die ('Error: no data found in the database.');
}
while ($row = mysql_fetch_assoc($result)){
echo 'Pet: '.$row['pet'].', tasks: '.$row['tasks'].'. ';
}
mysql_close($db);
?>
q段代码l了你需要的信息Q但它输出ƈ不正。我们需要修改这PHP代码来分隔数据ؓXMLQ而不是纯文本。ؓ了实现这个目标我们得作几个修攏V?BR>
<?php
header('Content-Type: text/xml');//~号1
echo '<?xml version="1.0" encoding="UTF-8"?>';//~号2
echo "\n<data>\n<pets>\n";//~号3
$user = "admin";
$pass = "adminpass";
$host = "localhost";
$conn = mysql_connect($host, $user, $pass) or die("无法q接mysql.");
$db = mysql_select_db("pets",$conn) or die("无法选择数据?");
$result = mysql_query("SELECT * FROM `pets`");
if(mysql_num_rows ($result) == 0){
die ('Error: 数据库没有数?');
}
while ($row = mysql_fetch_assoc($result)){
echo '<'.$row['pet'].' tasks="'.$row['tasks'].'" />'."\n";//~号4
}
echo "</pets>\n</data>";//~号5
mysql_close($db);
?>
让我们从上面开始,一ơ一行的来分析它是如何输出XML?我给每一行都加了注释标记以便于更好的对应理解(原文是I've color-coded each line to make it easier to understand,我懒得上?改成用~号?
~号1:q部分代码发送一个http头来让用户客L明白q个php文g输出的是一个XML。这是Z么你在你的浏览器里看q个文档的时候它以一个XML文g的Ş式展玎ͼ即你的文g有一个?php”后~?BR>
~号2:q部分的代码输出了XML声明。这是我之前展示l你看的XML的第一行?BR>
~号3:q部分的代码输出的最开始的两个标签Q我们的Ҏ{,<data>和我们用来放|所有宠物的<pets>标签?BR>
~号4:q部分的代码最困难的。这里包含了一个@环用来遍历你数据库里所有的数据。每ơ@环,它会输出一个新的节点,q个节点用每一U动物作为标{以及一?d"属性。例如,如果你数据库中的W一只宠物是“猫”而且它相应的d字段是“喂? 饮水, 抓蟩蚤”,那php输出在XML文档中输?<?tasks="喂食, 饮水, 抓蟩? /> 。这个“\n?部分只是在结插入一个新行,保证q个XML代码不至于都在同一行?BR>
~号5:q部分的代码l束?我们开始时打开?lt;/pets> ?</data> 节点。因为XML必须是格式良好的Qwell-formedQ,所以我们必认真对待这部分以确认我们的E序能够正确q行?BR>
现在我们已经让PHP输出XML了,我们现在所要作的就是登录我们的mysql数据库,q进行我们所需要的修改Q来更新q个XML。很P不是吗?我们仍然能够使用上一文章中的js脚本来获取代码,因ؓXML输出和之前的完全一栗?BR>
l论
你可以再q一步的扩展Q用XML来保存和获取数据。换句话_你能够用php来写你的XML文gQ然后让javascript来读。用ajaxQ你也能够定时的查xml文g是否已经更改而且Q如果XML已经更新Q也可以更新本页面?/FONT>
]]>
q第一步就是创Z个带一些数据的XML文g。我们将q个文g命名为data.xml。它是一个简单的XML文gQ而在一个真实的E序中,它会复杂许多Q但对于我们的例子来_单明了是最合适地?BR>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<data>
q是一些示例数据,它被保存在一个XML文g中,q被JavaScript取回?BR></data>
</root>
现在让我们创Z个简单的web面包含一些示例数据。这个页面将是我们的js脚本所在,q且q个面会让用户们讉K柄看到Ajax脚本的运行。我们把它命名ؓajax.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="zh" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>使用ajax开发web应用E序 - CZ</title>
</head>
<body>
<h1>使用ajax开发web应用E序</h1>
<p>q个面演示了AJAX技术如何通过动态读取一个远E文件来更新一个网늚内容Q-不需要Q何网늚重新加蝲。注意:q个例子对于止js的用h说没有效果?lt;/p>
<p id="xmlObj">
q是一些示例数据,它是q个|页的默认数?<a href="data.xml"
title="查看q个XML数据." onclick="ajaxRead('data.xml'); this.style.display='none'; return false">查看XML数据.</a>
</p>
</body>
</html>
注意Q对于那些没有javascript的用P我们直接链接到data.xml文g。对于那些允许运行javascript的用P函数“ajaxRead”将被运行,q个链接被隐藏,q不会被转向到那个data.xml文g。函数“ajaxRead”现在还没定义。所以如果你要检验上面的CZ代码Q你会得C个javascript错误。让我们l箋q定义这个函敎ͼq有其他的)Q让你能够看到ajax是如何工作的Q下面的脚本要放C的head标签里:
<script type="text/javascript"><!--
function ajaxRead(file){
var xmlObj = null;
if(window.XMLHttpRequest){
xmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return;
}
xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);
}
}
xmlObj.open ('GET', file, true);
xmlObj.send ('');
}
function updateObj(obj, data){
document.getElementById(obj).firstChild.data = data;
}
//--></script>
QSheneyan注:完整代码CZ见http://sheneyan.com/html/article/ajax/example.htmlQXML文g见:http://sheneyan.com/html/article/ajax/data.xmlQ?BR>
q堆代码有点多,让我们一点点的进行。第一个函数叫做“ajaxRead”-也就是我们在面的“查看XML数据”链接中调用的函敎ͼ我们定义了一个“xmlObj”变量-q将作ؓ客户端(用户正在查看的这个web面Q以及服务端Qweb站点本nQ之间的中间件。我们在一个if/else块中定义q个对象Q?BR>if(window.XMLHttpRequest){
xmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return;
}
q只是一个对不同对象是否可用的测试-某些览器实C不同的XMLHttpRequest对象Q所以当我们定义“xmlObj”作为我们的XMLHttpRequest对象Ӟ我们不得不根据浏览器所实现的来定义它。如果没有可用的XMLHttpRequest对象Q我们将执行“return”语句结束这个函C避免脚本错误。在大部分情况下Q这个检验将q回一个XMLHttpRequest对象Q这部分代码应该能够在绝大部分的览器上工作Q除了少部分比较老的览器的异常情况Q它能够工作在ie5.01上,但是在netscape4上会使函数终止)?BR> 接下来是q些代码?
xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);
}
}
每次XMLHttpRequest的状态发生变化,事g“onreadystatechange”就会被触发。通过使用“xmlObj.onreadystatechange = function(){...}”我们能够创Z个函数ƈ让它在这个XMLHttpRequest对象的状态每ơ发生改变的时候立刻运行。这里d有五个状态,?走到4?BR>
0 ?未初始化(在这个XMLHttpRequest开始前Q?BR>
1 ?加蝲QXMLHttpRequest初始化一l束Q?BR>
2 ?加蝲l束QXMLHttpRequest一从服务器上获得一个回应)
3 ?交互Q当XMLHttpRequest对象和服务器q接中)
4 ?l束Q当XMLHttpRequest被告知它已经完成了所有h物ƈl束q行Q?BR>
q第五个状态(数字4Q就是我们能够确定数据已l可用的标志Q所以我们检验这个xmlObj.readyState是否{于?”来定数据是否可用Q如果是4Q我们运行updateObj函数。这个函数带两个参数Q一个当前web面的元素IDQ当前web面中要更新的元素)以及用于填充q个元素的数据。这个函数的q行方式在稍后将更详l地解释?BR>
我们的web面的p元素有一个id“xmlData”,q就是我们准备更新的D落。我们正在取得的数据来自于XML文gQ但它有点复杂。这里是它如何工作的原理?BR>
xmlObj.responseXML属性是一个DOM对象 Q?它很象“document”对象,除了它来自远E的XML文g。换句话_如果你在data.xml中运行脚本,那xmlObj.responseXML是一个“document”对象。因为我们知道这些,我们能够通过“getElementsByTagName”方法取得Q何XML节点。数据包含在一个命名ؓ?lt;data>”的XML节点中,所以我们的d很简单:取得W一个(而且只有q一个)数据节点。因而,xmlObject.responseXML.getElementsByTagName("data")[0]q回XML文g中的W一?lt;data>节点?BR>注意Q它q回的是XML节点Q而不是节点中的数据-q个数据必须通过讉KXML节点的属性取得,q就是下一步要说的?BR> 接下来,取得数据只需要简单的指定“firstChild.data”(firstChild指向了那个被<data>节点包含的文本节点,而这个“data”属性则是这个文本节点的实际文本Q?BR>xmlObj.open ('GET', file, true);
xmlObj.send ('');
q是我们的ajaxRead函数的最后一个部分。它说了些什么?嗯,xmlObj的这个“open”方法打开了一个到服务器(通过一个指定的协议Q这里指定的是“GET”-你可以用“USE”或者其他别的协议)的连接,去请求一个文Ӟ在我们的例子里,变量“file”被作ؓ一个参数赋lajaxRead函数Qdata.xmlQ,而且javascript可以同步QfalseQ或者异步(trueQ默认|的处理请求。由于这是异步的Javascript和XMLQAJAXQ,我们用默认的异步方式Q在q个例子中,使用同步方式不起作用?BR>
q是我们函数中的最后一行,它简单的发送一个空字符串回服务器。如果没有这行,xmlObj的readyState永远不会?Q所以你的页面永q不会更新。这个sendҎ能够用于作其他事情,但今天我只是用来从服务器上取得数据-q不发送它Q所以在q篇文章中我不准备介入Q何关于sendҎ的细节?BR>function updateObj(obj, data){
document.getElementById(obj).firstChild.data = data;
}
现在再稍微解释一下updateObj函数Q这个函C用一个新的值来更新当前面上Q何指定的元素。他的第一个参敎ͼ“obj”是当前面中元素的IDQ那个要被更新的对象Q它的第二个参数Q“data”是用来那个将被替换值的对象Q“obj”)的内Ҏ换掉。一般来_验一下ƈ定当前面上确实有一个元素的ID是“obj”是比较明智的,但对我们的脚本的q个隔离U别来说校验q不必要。这个函数更新的方式和我们之前从XML文g的“data”节点取得数据的方式cMQ它定位它要更新的元素(q时候这个元素的ID代替了它的标{和在面中的索引Qƈ讄q个元素的第一个子节点Q文本节点)的data属性ؓ新的倹{如果你需要用HTML而不是纯文本来更C个元素,你也可以使用
document.getElementById(obj).innerHTML = data
q就是全部了
q个概念很简单,而且代码也不是很难。你能够从某个地方读取一个文件ƈ且不需要重新加载这个web面。你有够的灉|性来作各U事情,包括从表单发送数据(不需要重新加载web面Qƈ且用一个服务端语言来动态生成XML文g。如果你需要更q一步,记得q个q接是很有用的-哦,q要记得Google是你朋友。在另外的文章中Q我解释你如何配合服务端技术用AJAX来构造强大的web应用E序?/FONT>
]]>
q篇文章是徏立在上一文章中构造的CZ代码的基之上Q所以如果你不能理解我们现在的代码,你可以回q头去读W一文章(sheneyan注:在上面Q?BR>
开始~
让我们开始我们的W一步:构造XML。我们准备写一个XML文档Q它l织了一pd准备让javascript处理的数据,所以我们将一Ll一些节点和子节点(或者,元素和子元素Q。在q个例子里,我们用一些家庭宠物的名字Q?BR>
<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<pet>?lt;/pet>
<pet>?lt;/pet>
<pet>?lt;/pet>
</pets>
</data>
在上面,我们有这个XML声明Q标明这个文档是一个XML 1.0 文档Q用UTF-8~码Q,一个根元素Q?lt;data>Q将下面所有的元素l合在一P一?lt;pets>元素l织了所有的宠物Q然后一?lt;pet>节点对应一只宠物。ؓ了指定每一只宠物是什么类型的动物Q我们在<pet>元素中设|了文本节点Q猫Q狗Q鱼?BR><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"[url]http://www.w3.org/TR/html4/strict.dtd[/url]">
<html lang="zh" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>使用Ajax开发Web应用E序 - CZ</title>
<script type="text/javascript"><!--
function ajaxRead(file){
var xmlObj = null;
if(window.XMLHttpRequest){
xmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return;
}
xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
processXML(xmlObj.responseXML);
}
}
xmlObj.open ('GET', file, true);
xmlObj.send ('');
}
function processXML(obj){
var dataArray = obj.getElementsByTagName('pet');
var dataArrayLen = dataArray.length;
var insertData = '<table style="width:150px; border: solid 1px #000"><tr><th>'
+ 'Pets</th></tr>';
for (var i=0; i<dataArrayLen; i++){
insertData += '<tr><td>' + dataArray[i].firstChild.data + '</td></tr>';
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}
//--></script>
</head>
<body>
<h1>使用Ajax开发web应用E序</h1>
<p>q个面演示了AJAX技术如何通过动态读取一个远E文件来更新一个网늚内容Q-不需要Q何网늚重新加蝲。注意:q个例子对于止js的用h说没有效果?lt;/p>
<p>q个面演C如从取回ƈ处理成组的XML数据。被取回的数据将会以表格形式输出到底下?BR><a href="#" onclick="ajaxRead('data_2.xml'); return false">查看演示</a>.</p>
<div id="dataArea"></div>
</body>
</html>
QSheneyan注:完整代码CZ见[url]http://sheneyan.com/html/article/ajax/example_2.html[/url]QXML文g见:[url]http://sheneyan.com/html/article/ajax/data_2.xml[/url]Q?BR>
你会注意到我们和上次一样以同样的方式(通过一个超链接Q调用了q个函数Q而且我们数据放入一个DIVQ这ơ这个东东叫做“dataArea”)。这个ajaxRead()函数和上ơ很接近Q除了一点不同:onreadystatechange函数。让我们先看一下这个函敎ͼ
xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
processXML(xmlObj.responseXML);
}
}
我们取消了updateObj函数q用一个叫做processXML()的新函数来代替它。这个函数将得到XML文档本nQ也是被ajaxRead函数取回的)q处理它。(q“XML文档本n”我指的是参数“xmlObj.responseXML”)
现在让我们分析一下这个函数processXML。下面是它的代码Q?BR> function processXML(obj){
var dataArray = obj.getElementsByTagName('pet');
var dataArrayLen = dataArray.length;
var insertData = '<table style="width:150px; border: solid 1px #000"><tr><th>'
+ 'Pets</th></tr>';
for (var i=0; i<dataArrayLen; i++){
insertData += '<tr><td>' + dataArray[i].firstChild.data + '</td></tr>';
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}
首先Q我们定义了一些变量。“dataArray”作为所?lt;pet>节点的数l(不是节点数据Q只是节点)。“dataArrayLen”是q个数组的长度,用于我们的@环。“insertData”则是一个表格的开头的HTML?BR>
我们的第二步则是遍历所有的<pet>元素Q通过变量“dataArray”)q将数据d到变量insertData中。这里我们会创徏一个表DQ插入一个表格数据节?td)q去Q再每一?lt;pet>元素的文本包含进q个表格数据节点Qƈ这些都dq变量“insertData”。因此,每@环一ơ,变量insertData添加一行包含三个宠物中之一名称的新数据?BR>
新数据行d完后Q我们插入一个?lt;/table>”结束标{ֈ变量“insertData”。这完成了这个表|然后我只剩这最后一步来达成我们的目标:我们需要将q个表格攑ֈ面上。幸q的是,我们得感谢innerHTML属性,q很单。我们通过函数document.getElementById()取得DIV“dataArea”ƈ变量“insertData”中的HTML插进厅R嗯Q这个表格冒出来了!
我们l箋之前…?BR>
我得指出两点Q?BR>
首先Q你会注意到我们q没有用节?lt;pets>。这事因为我们只有一个数据组Q?lt;pets>Q以及后来所有的元素Q每一?lt;pet>元素Q;q些子节点包含了不同的数据但它们有相同的名字。在q个例子中,q个节点能够被忽略。然而,所有的元素<pet>放进<pets>元素q是比较好,而不是让q些<pet>元素自己散放Q但仍然在data元素里面Q?BR>
另外一U方式是l每一个宠物放一个指定的标签Q比如:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<?/>
<?/>
<?/>
</pets>
</data>
然后我们能够遍历元素<pets>里的节点。这个processXML函数看v来就像这P
function processXML(obj){
var dataArray = obj.getElementsByTagName('pets')[0].childNodes;
var dataArrayLen = dataArray.length;
var insertData = '<table style="width:150px; border: solid 1px #000"><tr><th>'
+ 'Pets</th></tr>';
for (var i=0; i<dataArrayLen; i++){
if(dataArray[i].tagName){
insertData += '<tr><td>' + dataArray[i].tagName + '</td></tr>';
}
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}
QSheneyan注:修改后的CZ见:[url]http://sheneyan.com/html/article/ajax/example_2_1.html[/url]QXML文g见:[url]http://sheneyan.com/html/article/ajax/data_2_1.xml[/url]Q?BR>
q里所作的修改是我们指向?lt;pets>l元素(q个“[0]”意呌是第一个,即它就是唯一的那一个)以及它的子节点(元素<?/>Q?lt;?/>Q?lt;?/>Q。因为文本元素分割了q几个元素(I格被认为是一个节点)Q我们需要确定只有那些有标签名的节点Q嗯Q也是只有标签Q通过。然后我们输出每一个标{名字。因为每一个标{是一个宠物,我们不需要取得每一个节点的数据Q节点名本n已经_。去看一下它是怎么工作的吧?BR>
q有另外一U方式来完成我们上面的工作,是l每一?lt;pet>节点讄一个属性倹{你的XML文档看v来就像这P
<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<pet type="? />
<pet type="? />
<pet type="? />
</pets>
</data>
你只需要稍微修改一下你的processXML函数Q它变成q样子了Q?BR> function processXML(obj){
var dataArray = obj.getElementsByTagName('pet');
var dataArrayLen = dataArray.length;
var insertData = '<table style="width:150px; border: solid 1px #000"><tr><th>'
+ 'Pets</th></tr>';
for (var i=0; i<dataArrayLen; i++){
insertData += '<tr><td>' + dataArray[i].getAttribute('type') + '</td></tr>';
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}
QSheneyan注:修改后的CZ见:[url]http://sheneyan.com/html/article/ajax/example_2_2.html[/url]QXML文g见:[url]http://sheneyan.com/html/article/ajax/data_2_2.xml[/url]Q?BR>
关键的不同在于我们通过dataArray[i].getAttribute('type')取得|它返回了当前<pet>节点的“type”属性的倹{?BR>
l箋...
现在我们已经知道了一些从一个单独的XML数据l中取回数据的有效方法,让我们看看如何从多个l中取回数据。和只是列出一个pets所拥有的内容不同,我们假设我们有一个针Ҏ们宠物的日课表。因为它们都有不同的需要,每一只宠物都得仔l的照顾。面对这U情况,动物的看员需要一个每日依据。现在来让我们将q些攑օ一个良好格式的XMLQ?BR><?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<pet>Cat
<task>Feed</task>
<task>Water</task>
<task>Comb out fleas</task>
</pet>
<pet>Dog
<task>Feed</task>
<task>Water</task>
<task>Put outside</task>
</pet>
<pet>Fish
<task>Feed</task>
<task>Check oxygen, water purity, etc.</task>
</pet>
</pets>
</data>
也许q个看v来很奇怪,但这是我们正在创徏的子l?sub-group)。每一?lt;pet>元素都是一个组<pets>的子l,而每一?lt;task>则是每一?lt;pet>l的子元素?BR>
在我l箋之前Q你也许希望你的表格用一些css化一下,比如Q?BR><style type="text/css"><!--
table, tr, th, td {
border: solid 1px #000;
border-collapse: collapse;
padding: 5px;
}
--></style>
q让q个表格更容易读取。现在让我们ȝI函数processXMLQ?BR>function processXML(obj){
var dataArray = obj.getElementsByTagName('pet');
var dataArrayLen = dataArray.length;
var subAry, subAryLen;
var insertData = '<table><tr><th>'
+ 'Pets</th><th>Tasks</th></tr>';
for (var i=0; i<dataArrayLen; i++){
insertData += '<tr><td>' + dataArray[i].firstChild.data + '</td>';
subAry = dataArray[i].getElementsByTagName('task');
subAryLen = subAry.length;
insertData += '<td>';
for(var j=0; j<subAryLen; j++){
insertData += subAry[j].firstChild.data;
if( subAryLen != j+1 ) { insertData += ', '; }
}
insertData += '</td></tr>';
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}
QSheneyan注:修改后的CZ见:[url]http://sheneyan.com/html/article/ajax/example_2_3.html[/url]QXML文g见:[url]http://sheneyan.com/html/article/ajax/data_2_3.xml[/url]Q?BR>
新增加的内容Q首先是两个新变量的声明Q“subAry”和“subAryLen”。它们和之前的变量“dataArray”和“dataArrayLen”类|除了它们指向不同的数l(特别是它们将指向那些“task”元素-当“dataArray”和“dataArrayLen”指向“pet”元素的时候)?BR>
我们也改变了变量“insertData”的初始|我们增加了一个表格头Q?lt;th>Q给我们的“tasks”字Dc?BR>
下一步改变在于@环:我们把DlsubAry和subAryLen变量。变量subAry成ؓ当前<pet>?lt;task>元素的数l。变量subAryLen成ؓq个数组的长度,直到q个数组发生变化Q当外部循环走到下一?lt;pet>Ӟ?BR>
我们创徏了一个内嵌的循环来处理所有的<task>元素Q一ơ一个。大概来_我们创徏一个新的数据格Q放q一个用逗号分隔的Q务列表,然后关闭数据表格以及当前行。尤Ӟq些<task>元素节点数据QQ务本w,比如Q“喂食”)攄入变量“insertData”里的数据格?BR>
接下来,我们验当?lt;pet>是否有其它更多的task。如果还有,我们增加一个逗号Q,Q到变量insertData来让每一个Q务用一个逗号分隔Q“a, b, c”,而不是“a, b, c,”-注意Q最后一个逗号在第二个d那里Q所以我们不需要)。这个工作在我们取得subAry数组长度的时候(l@环的“j”变量加1Q就完成了。因个@环会在下一个@环的时候把变量“j”递增1,“j”会比它q次验时q多1。因此,如果“j+1”(或者,“当循环再次开始的时候j的值”){于subAryLenQ当?lt;pet>节点?lt;task>节点数目Q,q个循环停止。如果@环不再运行,我们׃再添加新的逗号来分隔Q务。所以如果“j+1”不{于subAryLenQ我们直到我们可以安全的加入逗号到“insertData”,Z一?lt;task>作准备?BR>
一旦内循环l束Q我们关闭task数据g及pet行。外部@环会重新开始创Z个新行以及移动到下一?lt;pet>。这个处理一直进行到所有的<pet>元素Q以及每一个pet的所?lt;task>元素Q都被处理完?BR>
有其他方法吗Q?BR>
你也怼惻I“那javascript变得相当复杂了,但它只会随着XML来复杂而跟着变复杂,也许我们能够化XMLQ然后,化javascript”。如果你q么惻I很棒Q因Z完全正确。我之前展示的不同方法之一Q我详细说明的那个也许能够成为最合适的。我们怎么使用属性来对应每一只宠物以及相应Q务?XML看v来会变成怎样Q?BR>
<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<pet type="Cat" tasks="Feed, Water, Comb out fleas" />
<pet type="Dog" tasks="Feed, Water, Put outside" />
<pet type="Fish" tasks="Feed, Check oxygen, water purity, etc." />
</pets>
</data>
哇哦Q看h单多了。让我们看看我们的processXML函数如何修改Q?BR>function processXML(obj){
var dataArray = obj.getElementsByTagName('pet');
var dataArrayLen = dataArray.length;
var insertData = '<table><tr><th>'
+ 'Pets</th><th>Tasks</th></tr>';
for (var i=0; i<dataArrayLen; i++){
insertData += '<tr><td>' + dataArray[i].getAttribute('type') + '</td>'
+ '<td>' + dataArray[i].getAttribute('tasks') + '</td></tr>';
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}
QSheneyan注:修改后的CZ见:[url]http://sheneyan.com/html/article/ajax/example_2_4.html[/url]QXML文g见:[url]http://sheneyan.com/html/article/ajax/data_2_4.xml[/url]Q?BR>
像你猜的一P函数单多了。因Z码变得简单,它也会变得更有效率。和我们比较老的函数的唯一的不同在于这个变量insertData现在插入更多的HTMLQ尤其是两个新变量“type”和“tasks”。就如我们较早之前所学的Q那些属性是我们从XML文档?lt;pet>元素中取得的Q而且每个pet的属性都有不同的倹{对于你自己修改q个XML文g以适应你的q度的变动来说也许是最单的Ҏ。例如,如果你最l把你的猫n上的跌抓光了,你只要简单从你的猫的每日d表中把“减蟩蚤数量”删除,然而在之前我们使用的XML中,实现h也许会觉得糊里糊涂?BR>
最后的XML格式化的Ҏ是将两部分合。现在,我们用属性和不同的标{。让我们看一下示例XMLQ?BR><?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<?tasks="喂食, 饮水, 减少跌数量" />
<?tasks="喂食, 饮水, 带出去遛? />
<?tasks="喂食, 查氧气,水的U度Q其? />
</pets>
</data>
q也许是最便于理解的XML。让我们分析一下我们ؓ了让processXML函数q作h所作的变更Q?BR>function processXML(obj){
var dataArray = obj.getElementsByTagName('pets')[0].childNodes;
var dataArrayLen = dataArray.length;
var insertData = '<table><tr><th>'
+ 'Pets</th><th>Tasks</th></tr>';
for (var i=0; i<dataArrayLen; i++){
if(dataArray[i].tagName){
insertData += '<tr><td>' + dataArray[i].tagName + '</td>'
+ '<td>' + dataArray[i].getAttribute('tasks') + '</td></tr>';
}
}
insertData += '</table>';
document.getElementById ('dataArea').innerHTML = insertData;
}
QSheneyan注:修改后的CZ见:[url]http://sheneyan.com/html/article/ajax/example_2_5.html[/url]QXML文g见:[url]http://sheneyan.com/html/article/ajax/data_2_5.xml[/url]Q?BR>
“dataArray”现在指向了<pets>的子节点Q将它们作ؓ一个数l对待(换句话说QdataArray现在是在<pets>节点内所有节点的数组Q。这事因为每一个标{N不同Q?lt;?/>Q?lt;?/>Q?lt;?/>Q,所以我们不能用这些元素的名称来搜索它们(而之前我们可以?lt;pet>Q因为所有的元素都是<pet>Q?BR>
q是一P每个节点之间的有I格Q所以在我们的处理过E中得排除掉文本节点。我们能够检验标{是否存在Q文本节Ҏ节点但没有标{,?lt;?/>Q?lt;?/>Q?lt;?/>节点都是标签。所以如果一个标{有名字Q那我们能够数据插入变量insertData。我们插入的数据是一个表格ƈ有两个表格数据格。这W一个单元格是标{Q也是宠物的类型(猫,狗或|Q而第二个单元格则是指定动物的“tasks”属性|比如“喂食或饮水”)?BR>
l束?BR>
在这文章里Q我演示了这个例子的很多变化Q你可以随意试验它们来检验哪个更适合你。只要记住一点,XML是“可扩展的”,所以没有“错误的”方法来l合你的数据Q虽然经常有一个“最好的”方法。而且Q要注意让你的XML保持格式良好。记住很多问题来自于忘记l束一个标{(比如<?/>而不?lt;?gt;;除非q个节点中有数据Q比如下面的<?gt;q里有数据哦</?gt;Q?BR>
我意图XML和javascript的应用不p涂而变得明朗。一步步的学习处理更多的数据Q你能够ajaxq用于更大的用途。我希望看到ajax更多的应用于企业|站Q及其它。所以如果你这些知识应用于实践Q我很高兴了解到你学C什么(mailQ[email]jona@slightlyremarkable.com[/email]Q?/FONT>
]]>
{
public static String escape (String src)
{
int i;
char j;
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length()*6);
for (i=0;i<src.length() ;i++ )
{
j = src.charAt(i);
if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j))
tmp.append(j);
else
if (j<256)
{
tmp.append( "%" );
if (j<16)
tmp.append( "0" );
tmp.append( Integer.toString(j,16) );
}
else
{
tmp.append( "%u" );
tmp.append( Integer.toString(j,16) );
}
}
return tmp.toString();
}
public static String unescape (String src)
{
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length());
int lastPos=0,pos=0;
char ch;
while (lastPos<src.length())
{
pos = src.indexOf("%",lastPos);
if (pos == lastPos)
{
if (src.charAt(pos+1)=='u')
{
ch = (char)Integer.parseInt(src.substring(pos+2,pos+6),16);
tmp.append(ch);
lastPos = pos+6;
}
else
{
ch = (char)Integer.parseInt(src.substring(pos+1,pos+3),16);
tmp.append(ch);
lastPos = pos+3;
}
}
else
{
if (pos == -1)
{
tmp.append(src.substring(lastPos));
lastPos=src.length();
}
else
{
tmp.append(src.substring(lastPos,pos));
lastPos=pos;
}
}
}
return tmp.toString();
}
public static void main(String[] args)
{
String tmp="~!@#$%^&*()_+|\\=-,./?><;'][{}\"";
System.out.println("testing escape : "+tmp);
tmp =escape(tmp);
System.out.println(tmp);
System.out.println("testing unescape :"+tmp);
System.out.println(unescape(tmp));
}
}
此翻译稿很大一部分内容国内出现的那个先前版?/A>Q我只是Ҏ加入的几进行了译Qƈ且对我熟悉的产品着重介l了一下,以后我会抽时间收集文中提到AJAX工具相关的文章,量内容介l和功能点评做到全面详细炏V所以请x和准备用AJAX做开发的朋友xq篇文章Q我会时常更新的。原文因为是׃个wikipȝl护Q所以在所隑օ出现参差不齐Q风g也有不统一的情况,译时我也是参照原文原封不动的挪了过来,以后我会抽时间改良下?/P>
Z览器的应用框架一般分ZU:
Backbase是一个通过DHTML、JavaScript、CSS和HTML{技术强劲联合v来的一套完整的Windows桌面式的WEB应用E序解决Ҏ。Bindows无需下蝲安装客户端支撑组Ӟ如Java、ActiveX或FlashQ,仅需一个浏览器。纯OO的理念体现在BindowsM地方QBindows或许是笔者见q的最完整最强大的AJAX应用E序q_? DOJO提供完整的轻量H口lg和浏览器-服务器消息映支?/P>
译正文
Z服务器端的应用框枉常以下面两U方式工?管它们Ҏ不同的语aq行了分c?
目录
1. Pure Javascript: Application Frameworks
1.1 Bindows (成立?003q?
Bindows是商业程序的Q用了来自于MB的技?总部位于GA USAQ主要开发中心在瑞典Q成立于2002q??/P>Bindows框架提供的功能和Ҏ有Q?
Bindows开发环境:
1.2 BackBase (成立?003q?
BackBase是一个完整的览器端框架Q提供了丰富的浏览器操作功能Q以及对.NET和JAVAq_的集成?
商业化品,来自于Backbase B.V(总部在AmsterdamQ成立于2003q??
1.3 DOJO (开发中,成立?004q??
Open Rico是一个支持Ajax架构和用户交互的多用途框架?
Tibet提供了大量的易移植和完整的JavaScript APIQ通过q些可以快速生成大量的客户端代码,Tibet自称是企业AJAX?/P>
AJFORM是一个极易上手的AJAX框架Q被用来~写入门U的AJAX代码Q提供有以下功能Q?/P>
The Flash JavaScript Integration Kit可以使Flash和Javascript脚本实现怺集成?/P>
Google AJAXSLTQ是一个Javascript框架Q用来执行XSLT转换以及XPath查询?/P>
HtmlHttpRequest最大的特点是q用XMLHttpRequest对象和标准HTML标签IFrame来实现最大限度的跨浏览跨q_的AJAX支持Q其原理是在支持XMLHttpRequest的浏览器上调用XMLHttpQ如果不支持Q就用IFrame来模拟实现异步交互?/P>
Interactive Website Framework定位在浏览器中支持各U各LAJAX基础应用的开源项目。自U是通过JavaScript、CSS、XML和HTML实现高性能的交互式WEB框架Q包括一个可定制易读的XML解析器。实际上QIWF是一个AJAX的基框架Qƈ且还包括一些通用脚本代码?/P>
var node = doc.groceries.frozen[0].pizza[0].size;装后的数据d
var node = doc.documentElement.firstChild.firstChild.getAttribute("size");原始的DOM操作d
libXmlRequest是一个小型XMLHttpRequest装?/P>
MAJAX是另一个非常小巧的HttpRequest装包,为收发字W型信息提供单接口,qؓ每步动作讄回调界面?/P>
RSLite是一个XMLHttpRequest装lgQ作为Brent Ashley的JSRS(JavaScript Remote Scripting)其中的一部分功能单独发布。详情可以看JSRS的介l?/P>
Sack也是一个很有名字的微型XMLHttpRequest装包。调用者可以自定义回调函数或者是DOM对象。借助于回调DOM对象Q可以把Response回来的数据直接以文本的方式嵌入DOM中?/P>
Sarissa是一个JavaScript APIQ封装了在浏览器端独立调用XML的功能?/P>
XHConn也是一个小型的XMLHttpRequest装库。笔者也使用改良q的XHConnQ其特点是调用单,代码也清晰易诅R?/P>
new XHConn().connect("mypage.php"Q?POST"Q?foo=bar&baz=qux"QfnWhenDone);
CPAINT是一个真正的同时支持PHP和ASP/VBScript脚本的AJAX和JSRS工具包。CPAINT在后台提供你需求的AJAX和JSRS代码Qƈ自动q回到浏览器端相应的Javascript脚本代码Q这U方式易于实时反馈需求的WEB应用E序?/P>
SAJAX的实现方式很独特Q例如:调用一个javascriptҎx_calculateBudget()Q将先把响应传到服务器ƈ调用一个Java calculateBudget()ҎQ然后以javascript方式把D回到x_calculateBudget_cb()中。SAJAX的名气不错,估计很多人都听过甚至用过Q不q缺点就是它的这套映理论感觉较J锁Q远不如一些轻量的封装库好用Q不qSAJAX最大的特点是支持的^C富,几乎囊括了WEB下常用的~程语言和^?/P>
JSON-RPC是一U远E交互协议,cM于XML-RPCQ对JavaScript支持较强
JSRSQ较l典的远E脚本访问组Ӟ支持客L数据通过服务器做代理q行q程的数?操作交互?/P>
Bitkraft是个Z(.NET)Web框架的CLR(公共语言q行?Q允许用独特的方式创建和操作分布式Web内容。用C#~写Q运行在微Y?NET 1.1和Mono框架下,无缝式的客户?服务器响应方式是它的最大特炏VBitkraft没有使用XMLl织数据Q而是用JSON代替?/P>
WebORB for Java是一个开发AJAX和基于Flash的富客户端应用程序的开发^台?A >在线例子
Echo 2允许你用UJava语言~写AJAXE序?Demo.
Direct Web Remoting可以在Javascript代码中直接调用JavaҎ的应用框?/P>
SWATO是一套可重用的和良好集成的Java/JavaScript库,它实C一U更Ҏ的方式来改变你的web应用E序的交互,通过AJAX方式实现?/P>
The AJAX JSP Tag Library是一lJSP标签库,用来AJAXE序开发。可以在J2EE下无需JavascriptpL开发AJAX模式的Web Form。标{ֺ为比较通用的AJAX功能提供?个标{:
The AJAX-JSF用来把Q意的JSF应用E序转变为AJAX应用E序
CL-Ajax实现Javascript直接调用服务端Lisp
WebORB for .NET是一个用.NET和XML Web Services方式开发AJAX和基于Flash的富客户端应用程?在线例子)
Ajax.NET是首家支持各U方式通过Javascript讉K服务?net的免费库
ComfortASP.NET可以让开发者在U?NET下开发类似AJAX(DHTML,JavaScript,XMLHttp)Ҏ的应用E序?/P>
AjaxAspects是个可以用Javascript调用服务端WebService事g的引?/P>
AjaxAC用一个单独类装了完整的应用E序功能
JPSPAN通过Javascript直接调用PHP中的函数?/P>
XAjax通过Javascript直接调用PHP中的函数
Ruby On Rails是一个支持AJAX的完整Web框架Q用Ruby语言~写Q严格按照MVCl构开发?/P>
很多人都看好AJAX无刷新的技术,以至于认同AJAX是用来做无h的。这个认识是错误的,什么是无刷斎ͼ无刷新就是页面无需重蝲Q那什么又是异步交互?异步交互是一个简单的多线E,当你在一个blog里看文章Ӟ同时也可以利用AJAXq行无刷新的回复提交Q看h虽然也是无刷斎ͼ但这里最重要的是异步Q即你能一边看文章Q一边又能向服务器提交你的回复信息,利用好这个异步,才能是掌握了AJAX的精髓。很多场合,无刷新是呈现l用L视觉体验Q而异步交互却是默默无ȝ工作在台后,q种情况D大多Ch的错误理解了AJAX的权重之分?/P>
通过以上两个国外成功应用AJAX的网站,我们发现他们都用的是轻量的AJAXQ就是那U交互简单,数据较少的操作。这也符合AJAX的本意,虽然?A >www.backbase.com?A >bindows都在RIA上有惊h的表现能力,但是速度慢?A title=google对backbase的站内搜索只?99,其中很多都是无关紧要的页?>搜烦引擎支持不好、开发难度大{毛病还是无法让用户满意的,误住:AJAX的最l目的是Z提高用户体验Qؓ了方便用户交互,而不是因技术而技术的?/P>
很多为在成熟的框架中应用AJAX会破坏框架的完整性,比较常见的说法有三层架构的WEB应用中破坏MVC模式Q其实不然。MVC的理论我׃多说了,l典的那三个层、五条线大家都很熟悉Q在WEB应用中,因ؓ览?服务器固有的q种h/响应的断开式网l通讯模式Q决定了在Model层无法实C动向View层发出数据更CӞ所以一般常见的成熟MVC框架中都经典MVC理论E作修改Q由Model层处理完业务后通知Control层,然后由Control层承担向View发送数据更新的义务。但是AJAX天生h监听功能QAJAX实现异步响应的那个OnReadyStateChange事g具有在客户端程序中才会有的事g监听功能。现在想来,利用AJAX实现的MVC模型有如下图q样Q?BR>
理想化的设计如下所C:
一般读取AJAXq回的XMLl构的数据时使用XMLHttp的responseXML对象属性,同时QXMLHttp也提供了另外一个属性,即ResponseTextQ通过q个属性,XMLHttp可以接受来自服务器的文本l构的字W串信息。去掉XML的AJAX可以使用ResponseTextq个对象属性,很灵zȝ操控q回数据的格式,可以自定义格式,比如我通常喜欢用c语言的那U文件流方式定义q回的字W串l构Q有文g头和具体的文件信息实体,文g头分为状态信息以及文件字W长度,我摒弃了文g字符长度的定义,规定L受的ResponseTex字符串中的第一位ؓ状态码Q比如设定常量?表示一h常,?的数字表CZ正常Q甚x错误{。如果有?|E序自动取第二位起到257?长度?56)的字W串l成为状态信息,?58位开始到末尾的字W串是服务器返回的正常l果信息?BR>substring(0,1)取状态码
substring(1,256)取服务器错误信息(错误信息不够256位用I格补齐Q取到数据后q行Trim处理)
substring(256,末尾)取服务器q回的数据信?BR>三次substring卛_成了一个简单但完整的交互工作。比起XML解析lg来说要快的多?/P>
用ResponseText比封装ؓXML处理数据快和单是一个原因,另一个原因是可操控性更大更灉|Q打开Google SuggestQ在搜烦框输入字W可以给你给出拼写提C,Suggest是应用了AJAX技术,不过它在从服务器q回数据时ƈ没有使用XML装Q也没有自定义ResponseText格式Q而是直接返回代码组l成js脚本Q通过览器返回后直接执行Q如eval(XMLHttp.ResponseText)q样的方式进行执行,http://www.google.com/complete/search?hl=en&js=true&qu=ajax 通过q个链接你可以看到Suggest利用AJAX得到的返回数据,此页面是在Google Suggest的搜索框中输?AJAX"后得pȝ动态返回的数据?/P>
sendRPCDone(frameElement, "ajax", new Array("ajax", "ajax amsterdam", "ajax fc", "ajax ontario", "ajax grips", "ajax football club", "ajax public library", "ajax football", "ajax soccer", "ajax pickering transit"), new Array("3,840,000 results", "502,000 results", "710,000 results", "275,000 results", "8,860 results", "573,000 results", "40,500 results", "454,000 results", "437,000 results", "10,700 results"), new Array(""));览器段拿到q段代码后直接eval可以了Q至于sendRPCDoneq个函数Q那当然得实现定义后q装载到面中啦。XMLHttpq个名字以XML开_让很多h锢了思想和创意,完全抛弃XQ你也可以做出纯AJAX的实例来?
当然Q对于大型系l来ԌZ保持数据接口的一致和整齐Q还是用XML来传递更严}更统一点,听说微Y已经发v了重写XML Parselg的号召,估计下一个版本的XMLHttpq是DOMParserq是MSXML2.DOMDocument都会大大提高效率Q减资源占用的?/P>
demo.htm 前台昄.
Server.asp 后台d数据
数据库data.mdb
?nums
id,自动~号
num1,文本
num2,文本
试数据
id num1 num2
1 20.70 20.810
2 10.5 20.5
3 12.3 300
4 132 323
5 563 56
6 20 10
利用XMLHTTP实现的二U连动Select
利用XMLHTTP无刷新添加数据之Post?/A>