欧美三区四区_av先锋影音资源站_亚洲第一论坛sis_影音先锋2020色资源网_亚洲精品社区_在线免费观看av网站_国产一区二区伦理_亚洲欧美视频一区二区_99视频精品全部免费在线_精精国产xxxx视频在线

使用Ajax技術(shù)開發(fā)Web應(yīng)用程序_AJAX教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:揭開AJAX神秘面紗
本文通過一個(gè)簡單的例子來說明如何在IE6中使用AJAX技術(shù)。在這例子中,客戶端每隔十秒,從服務(wù)器端取回一個(gè)隨機(jī)的字符串,在不重新刷新頁情況下,自動(dòng)更新部分頁面內(nèi)容。例子僅用到了兩個(gè)jsp文件,client.jsp及server.jsp。 AJAX,即Asynchronous JavaScript

在過去,由于為了獲得新數(shù)據(jù)而不得不重新加載web頁面(或者加載其他頁面)導(dǎo)致web應(yīng)用程序發(fā)展被限制。雖然有其他方法可用(不加載其他頁面),但是這些技術(shù)都沒有被很好地支持而且有bug成災(zāi)的趨向。在過去的幾個(gè)月里,一個(gè)過去并不被廣泛支持的技術(shù)已經(jīng)被越來越多的web沖浪者(web surfers??是指瀏覽器還是瀏覽者?)所接受,它給了開發(fā)者更多的自由開發(fā)先進(jìn)的web應(yīng)用程序。這些通過javascript來異步取得xml數(shù)據(jù)的應(yīng)用程序,被親切的稱為“Ajax應(yīng)用程序”(Asynchronous Javascript and XML applications)。在這篇文章中,我將會(huì)解釋如何通過Ajax來取回一個(gè)遠(yuǎn)程的XML文件并更新一個(gè)web page,并且隨著這個(gè)系列的繼續(xù),我將討論更多的方法,使用ajax技術(shù)將你的web應(yīng)用程序提升到一個(gè)新的層次.

這第一步就是創(chuàng)建一個(gè)帶一些數(shù)據(jù)的XML文件。我們將這個(gè)文件命名為data.xml。它是一個(gè)簡單的XML文件,而在一個(gè)真實(shí)的程序中,它會(huì)復(fù)雜許多,但對(duì)于我們的例子來說,簡單明了是最合適地。


<?xml version="1.0" encoding="UTF-8"?> <root> <data> 這是一些示例數(shù)據(jù),它被保存在一個(gè)XML文件中,并被JavaScript取回。 </data> </root>

 

 

現(xiàn)在讓我們創(chuàng)建一個(gè)簡單的web頁面包含一些示例數(shù)據(jù)。這個(gè)頁面將是我們的js腳本所在,并且這個(gè)頁面將會(huì)讓用戶們訪問柄看到Ajax腳本的運(yùn)行。我們把它命名為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開發(fā)web應(yīng)用程序 - 示例</title>
</head>
<body>
<h1> 使用ajax開發(fā)web應(yīng)用程序</h1>
<p> 這個(gè)頁面演示了AJAX技術(shù)如何通過動(dòng)態(tài)讀取一個(gè)遠(yuǎn)程文件來更新一個(gè)網(wǎng)頁的內(nèi)容--不需要任何網(wǎng)頁的重新加載。注意:這個(gè)例子對(duì)于禁止js的用戶來說沒有效果。</p>
<p id="xmlObj">
這是一些示例數(shù)據(jù),它是這個(gè)網(wǎng)頁的默認(rèn)數(shù)據(jù) <a href="data.xml"
title="查看這個(gè)XML數(shù)據(jù)." onclick="ajaxRead('data.xml'); this.style.display='none'; return false"> 查看XML數(shù)據(jù).</a>
</p>
</body>
</html>

 

注意,對(duì)于那些沒有javascript的用戶,我們直接鏈接到data.xml文件。對(duì)于那些允許運(yùn)行javascript的用戶,函數(shù)“ajaxRead”將被運(yùn)行,這個(gè)鏈接被隱藏,并不會(huì)被轉(zhuǎn)向到那個(gè)data.xml文件。函數(shù)“ajaxRead”現(xiàn)在還沒定義。所以如果你要檢驗(yàn)上面的示例代碼,你會(huì)得到一個(gè)javascript錯(cuò)誤。讓我們繼續(xù)并定義這個(gè)函數(shù)(還有其他的),讓你能夠看到ajax是如何工作的,下面的腳本要放到你的head標(biāo)簽里:

 

<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>

 

這堆代碼有點(diǎn)多,讓我們一點(diǎn)點(diǎn)的進(jìn)行。第一個(gè)函數(shù)叫做“ajaxRead”-也就是我們在頁面的“查看XML數(shù)據(jù)”鏈接中調(diào)用的函數(shù),我們定義了一個(gè)“xmlObj”變量-這將作為客戶端(用戶正在查看的這個(gè)web頁面)以及服務(wù)端(web站點(diǎn)本身)之間的中間件。我們在一個(gè)if/else塊中定義這個(gè)對(duì)象:

 

if(window.XMLHttpRequest){
xmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return;
}

 

這只是一個(gè)對(duì)不同對(duì)象是否可用的測試-某些瀏覽器實(shí)現(xiàn)了不同的XMLHttpRequest對(duì)象,所以當(dāng)我們定義“xmlObj”作為我們的XMLHttpRequest對(duì)象時(shí),我們不得不根據(jù)瀏覽器所實(shí)現(xiàn)的來定義它。如果沒有可用的XMLHttpRequest對(duì)象,我們將執(zhí)行“return”語句結(jié)束這個(gè)函數(shù)以避免腳本錯(cuò)誤。在大部分情況下,這個(gè)檢驗(yàn)將返回一個(gè)XMLHttpRequest對(duì)象-這部分代碼應(yīng)該能夠在絕大部分的瀏覽器上工作,除了少部分比較老的瀏覽器的異常情況(它能夠工作在ie5.01上,但是在netscape4上會(huì)使函數(shù)終止)。

接下來是這些代碼塊:

 

xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);
}
}

 

每次XMLHttpRequest的狀態(tài)發(fā)生變化,事件“onreadystatechange”就會(huì)被觸發(fā)。通過使用“xmlObj.onreadystatechange = function(){...}”我們能夠創(chuàng)建一個(gè)函數(shù)并讓它在這個(gè)XMLHttpRequest對(duì)象的狀態(tài)每次發(fā)生改變的時(shí)候立刻運(yùn)行。這里總共有五個(gè)狀態(tài),由0走到4。

0 – 尚未初始化(在這個(gè)XMLHttpRequest開始前)

1 – 加載(XMLHttpRequest初始化一結(jié)束)

2 – 加載結(jié)束(XMLHttpRequest一從服務(wù)器上獲得一個(gè)回應(yīng))

3 – 交互(當(dāng)XMLHttpRequest對(duì)象和服務(wù)器連接中)

4 – 結(jié)束(當(dāng)XMLHttpRequest被告知它已經(jīng)完成了所有人物并結(jié)束運(yùn)行)

這第五個(gè)狀態(tài)(數(shù)字4)就是我們能夠確定數(shù)據(jù)已經(jīng)可用的標(biāo)志,所以我們檢驗(yàn)這個(gè)xmlObj.readyState是否等于“4”來確定數(shù)據(jù)是否可用,如果是4,我們運(yùn)行updateObj函數(shù)。這個(gè)函數(shù)帶兩個(gè)參數(shù):一個(gè)當(dāng)前web頁面的元素ID(當(dāng)前web頁面中要更新的元素)以及用于填充這個(gè)元素的數(shù)據(jù)。這個(gè)函數(shù)的運(yùn)行方式在稍后將更詳細(xì)地解釋。

我們的web頁面的p元素有一個(gè)id“xmlData”,這就是我們準(zhǔn)備更新的段落。我們正在取得的數(shù)據(jù)來自于XML文件,但它有點(diǎn)復(fù)雜。這里是它如何工作的原理。

xmlObj.responseXML屬性是一個(gè)DOM對(duì)象 - 它很象“document”對(duì)象,除了它來自遠(yuǎn)程的XML文件。換句話說,如果你在data.xml中運(yùn)行腳本,那xmlObj.responseXML就是一個(gè)“document”對(duì)象。因?yàn)槲覀冎肋@些,我們能夠通過“getElementsByTagName”方法取得任何XML節(jié)點(diǎn)。數(shù)據(jù)包含在一個(gè)命名為“<data> ”的XML節(jié)點(diǎn)中,所以我們的任務(wù)很簡單:取得第一個(gè)(而且只有這一個(gè))數(shù)據(jù)節(jié)點(diǎn)。因而,xmlObject.responseXML.getElementsByTagName("data")[0]返回XML文件中的第一個(gè)<data> 節(jié)點(diǎn)。

注意: 它返回的是XML節(jié)點(diǎn),而不是節(jié)點(diǎn)中的數(shù)據(jù)-這個(gè)數(shù)據(jù)必須通過訪問XML節(jié)點(diǎn)的屬性取得,這就是下一步要說的。

接下來,取得數(shù)據(jù)只需要簡單的指定“firstChild.data”(firstChild指向了那個(gè)被<data> 節(jié)點(diǎn)包含的文本節(jié)點(diǎn),而這個(gè)“data”屬性則是這個(gè)文本節(jié)點(diǎn)的實(shí)際文本)。

 

xmlObj.open ('GET', file, true);
xmlObj.send ('');

 

這是我們的ajaxRead函數(shù)的最后一個(gè)部分。它說了些什么?嗯,xmlObj的這個(gè)“open”方法打開了一個(gè)到服務(wù)器(通過一個(gè)指定的協(xié)議,這里指定的是“GET”-你可以使用“USE”或者其他別的協(xié)議)的連接,去請(qǐng)求一個(gè)文件(在我們的例子里,變量“file”被作為一個(gè)參數(shù)賦給ajaxRead函數(shù)-data.xml),而且javascript可以同步(false)或者異步(true,默認(rèn)值)的處理請(qǐng)求。由于這是異步的Javascript和XML(AJAX),我們將使用默認(rèn)的異步方式-在這個(gè)例子中,使用同步方式將不起作用。

這是我們函數(shù)中的最后一行,它簡單的發(fā)送一個(gè)空字符串回服務(wù)器。如果沒有這行,xmlObj的readyState永遠(yuǎn)不會(huì)到4,所以你的頁面永遠(yuǎn)不會(huì)更新。這個(gè)send方法能夠用于作其他事情,但今天我只是用來從服務(wù)器上取得數(shù)據(jù)-并不發(fā)送它-所以在這篇文章中我不準(zhǔn)備介入任何關(guān)于send方法的細(xì)節(jié)。

 

function updateObj(obj, data){
document.getElementById(obj).firstChild.data = data;
}

 

現(xiàn)在再稍微解釋一下updateObj函數(shù):這個(gè)函數(shù)使用一個(gè)新的值來更新當(dāng)前頁面上任何指定的元素。他的第一個(gè)參數(shù),“obj”是當(dāng)前頁面中元素的ID-那個(gè)要被更新的對(duì)象;它的第二個(gè)參數(shù),“data”是用來將那個(gè)將被替換值的對(duì)象(“obj”)的內(nèi)容替換掉。一般來說,檢驗(yàn)一下并確定當(dāng)前頁面上確實(shí)有一個(gè)元素的ID是“obj”是比較明智的,但對(duì)我們的腳本的這個(gè)隔離級(jí)別來說校驗(yàn)并不必要。這個(gè)函數(shù)更新的方式和我們之前從XML文件的“data”節(jié)點(diǎn)取得數(shù)據(jù)的方式類似-它定位它要更新的元素(這時(shí)候這個(gè)元素的ID代替了它的標(biāo)簽名和在頁面中的索引)并設(shè)置這個(gè)元素的第一個(gè)子節(jié)點(diǎn)(文本節(jié)點(diǎn))的data屬性為新的值。如果你需要使用HTML而不是純文本來更新一個(gè)元素,你也可以使用

 

document.getElementById(obj).innerHTML = data

 

這就是全部了

這個(gè)概念很簡單,而且代碼也不是很難。你能夠從某個(gè)地方讀取一個(gè)文件并且不需要重新加載這個(gè)web頁面。你有足夠的靈活性來作各種事情,包括從表單發(fā)送數(shù)據(jù)(不需要重新加載web頁面)并且使用一個(gè)服務(wù)端語言來動(dòng)態(tài)生成XML文件。如果你需要更近一步,記得這個(gè) 連接 是很有用的-哦,還要記得Google是你朋友。在另外的文章中,我將解釋你如何配合服務(wù)端技術(shù)使用AJAX來構(gòu)造強(qiáng)大的web應(yīng)用程序。
在上一篇文章中,我們討論了如何通過javascript從一個(gè)遠(yuǎn)程XML文件中取得數(shù)據(jù)。在這篇文章中,我們將學(xué)會(huì)怎樣對(duì)數(shù)據(jù)作更復(fù)雜的處理。作為一個(gè)示例,我們會(huì)準(zhǔn)備一組XML數(shù)據(jù),將數(shù)據(jù)分割成獨(dú)立的片斷并以不同的方式展示這些片斷(取決于它們是如何被標(biāo)識(shí)的)。

這篇文章是建立在上一篇文章中構(gòu)造的示例代碼的基礎(chǔ)之上,所以如果你不能理解我們現(xiàn)在的代碼,你可以回過頭去讀第一篇文章(sheneyan注:就在上面)。

開始~

讓我們開始我們的第一步:構(gòu)造XML。我們準(zhǔn)備寫一個(gè)XML文檔,它組織了一系列準(zhǔn)備讓javascript處理的數(shù)據(jù),所以我們將一起組織一些節(jié)點(diǎn)和子節(jié)點(diǎn)(或者,元素和子元素)。在這個(gè)例子里,我們將使用一些家庭寵物的名字:

 

<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<pet> 貓</pet>
<pet> 狗</pet>
<pet> 魚</pet>
</pets>
</data>

 

在上面,我們有這個(gè)XML聲明(標(biāo)明這個(gè)文檔是一個(gè)XML 1.0 文檔,使用UTF-8編碼),一個(gè)根元素(<data> )將下面所有的元素組合在一起,一個(gè)<pets> 元素組織了所有的寵物,然后一個(gè)<pet> 節(jié)點(diǎn)對(duì)應(yīng)一只寵物。為了指定每一只寵物是什么類型的動(dòng)物,我們在<pet> 元素中設(shè)置了文本節(jié)點(diǎn):貓,狗,魚。

 

<!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開發(fā)Web應(yīng)用程序 - 示例</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開發(fā)web應(yīng)用程序</h1>
<p> 這個(gè)頁面演示了AJAX技術(shù)如何通過動(dòng)態(tài)讀取一個(gè)遠(yuǎn)程文件來更新一個(gè)網(wǎng)頁的內(nèi)容--不需要任何網(wǎng)頁的重新加載。注意:這個(gè)例子對(duì)于禁止js的用戶來說沒有效果。</p>
<p> 這個(gè)頁面將演示如從取回并處理成組的XML數(shù)據(jù)。被取回的數(shù)據(jù)將會(huì)以表格形式輸出到底下。
<a href="#" onclick="ajaxRead('data_2.xml'); return false"> 查看演示</a> .</p>
<div id="dataArea"> </div>
</body>
</html>

 

你會(huì)注意到我們和上次一樣以同樣的方式(通過一個(gè)超鏈接)調(diào)用了這個(gè)函數(shù),而且我們將數(shù)據(jù)放入一個(gè)DIV(這次這個(gè)東東叫做“dataArea”)。這個(gè)ajaxRead()函數(shù)和上次很接近,除了一點(diǎn)不同:onreadystatechange函數(shù)。讓我們先看一下這個(gè)函數(shù):

 

xmlObj.onreadystatechange = function(){
if(xmlObj.readyState == 4){
processXML(xmlObj.responseXML);
}
}

 

我們?nèi)∠藆pdateObj函數(shù)并用一個(gè)叫做processXML()的新函數(shù)來代替它。這個(gè)函數(shù)將得到XML文檔本身(也就是被ajaxRead函數(shù)取回的)并處理它。(這“XML文檔本身”我指的是參數(shù)“xmlObj.responseXML”)

現(xiàn)在讓我們分析一下這個(gè)函數(shù)processXML。下面是它的代碼:

 

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;
}

 

首先,我們定義了一些變量。“dataArray”作為所有<pet> 節(jié)點(diǎn)的數(shù)組(不是節(jié)點(diǎn)數(shù)據(jù),只是節(jié)點(diǎn))。“dataArrayLen”是這個(gè)數(shù)組的長度,用于我們的循環(huán)。“insertData”則是一個(gè)表格的開頭的HTML。

我們的第二步則是遍歷所有的<pet> 元素(通過變量“dataArray”)并將數(shù)據(jù)添加到變量insertData中。這里我們會(huì)創(chuàng)建一個(gè)表格行,插入一個(gè)表格數(shù)據(jù)節(jié)點(diǎn)(td)進(jìn)去,再將每一個(gè)<pet> 元素的文本包含進(jìn)這個(gè)表格數(shù)據(jù)節(jié)點(diǎn),并將這些都添加進(jìn)變量“insertData”。因此,每循環(huán)一次,變量insertData將添加一行包含三個(gè)寵物中之一名稱的新數(shù)據(jù)。

新數(shù)據(jù)行添加完后,我們插入一個(gè)“</table> ”結(jié)束標(biāo)簽到變量“insertData”。這完成了這個(gè)表格,然后我只剩這最后一步來達(dá)成我們的目標(biāo):我們需要將這個(gè)表格放到頁面上。幸運(yùn)的是,我們得感謝innerHTML屬性,這很簡單。我們通過函數(shù)document.getElementById()取得DIV“dataArea”并將變量“insertData”中的HTML插進(jìn)去。嗯,這個(gè)表格冒出來了!

我們繼續(xù)之前……

我得指出兩點(diǎn):

首先,你會(huì)注意到我們并沒有使用節(jié)點(diǎn)<pets> 。這事因?yàn)槲覀冎挥幸粋(gè)數(shù)據(jù)組(<pets> )以及后來所有的元素(每一個(gè)<pet> 元素);這些子節(jié)點(diǎn)包含了不同的數(shù)據(jù)但它們有相同的名字。在這個(gè)例子中,這個(gè)節(jié)點(diǎn)能夠被忽略。然而,將所有的元素<pet> 放進(jìn)<pets> 元素還是比較好,而不是讓這些<pet> 元素自己散放(但仍然在data元素里面)。

另外一種方式是給每一個(gè)寵物放一個(gè)指定的標(biāo)簽,比如:

 

<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<貓 />
<狗 />
<魚 />
</pets>
</data>

 

然后我們能夠遍歷元素<pets> 里的節(jié)點(diǎn)。這個(gè)processXML函數(shù)看起來就像這樣:

 

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;
}

 

這里所作的修改就是我們指向了<pets> 組元素(這個(gè)“[0]”意味這是第一個(gè),即使它就是唯一的那一個(gè))以及它的子節(jié)點(diǎn)(元素<貓 /> ,<狗 /> ,<魚 /> )。因?yàn)槲谋驹胤指盍诉@幾個(gè)元素(空格被認(rèn)為是一個(gè)節(jié)點(diǎn)),我們需要確定只有那些有標(biāo)簽名的節(jié)點(diǎn)(嗯,也就是只有標(biāo)簽)通過。然后我們輸出每一個(gè)標(biāo)簽的名字。因?yàn)槊恳粋(gè)標(biāo)簽名是一個(gè)寵物,我們不需要取得每一個(gè)節(jié)點(diǎn)的數(shù)據(jù)-節(jié)點(diǎn)名本身已經(jīng)足夠。去看一下它是怎么工作的吧。

還有另外一種方式來完成我們上面的工作,就是給每一個(gè)<pet> 節(jié)點(diǎn)設(shè)置一個(gè)屬性值。你的XML文檔看起來就像這樣:

 

<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<pet type="貓" />
<pet type="狗" />
<pet type="魚" />
</pets>
</data>

 

你只需要稍微修改一下你的processXML函數(shù),它變成這樣子了:

 

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;
}

 

(Sheneyan注:修改后的示例見:附件: example_2_2.htm ,XML文件見:附件: data_2_3.xml )

關(guān)鍵的不同在于我們通過dataArray[i].getAttribute('type')取得值,它返回了當(dāng)前<pet> 節(jié)點(diǎn)的“type”屬性的值。

繼續(xù)...

現(xiàn)在我們已經(jīng)知道了一些從一個(gè)單獨(dú)的XML數(shù)據(jù)組中取回?cái)?shù)據(jù)的有效方法,讓我們看看如何從多個(gè)組中取回?cái)?shù)據(jù)。和只是列出一個(gè)pets所擁有的內(nèi)容不同,我們假設(shè)我們有一個(gè)針對(duì)我們寵物的日課表。因?yàn)樗鼈兌加胁煌男枰恳恢粚櫸锒嫉米屑?xì)的照顧。面對(duì)這種情況,動(dòng)物的看管員需要一個(gè)每日依據(jù)。現(xiàn)在來讓我們將這些放入一個(gè)良好格式的XML:

 

<?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>

 

也許這個(gè)看起來很奇怪,但這就是我們正在創(chuàng)建的子組(sub-group)。每一個(gè)<pet> 元素都是一個(gè)組<pets> 的子組,而每一個(gè)<task> 則是每一個(gè)<pet> 組的子元素。

在我繼續(xù)之前,你也許希望將你的表格用一些css美化一下,比如:

 

<style type="text/css"> <!--
table, tr, th, td {
border: solid 1px #000;
border-collapse: collapse;
padding: 5px;
}
--> </style>

 

這讓這個(gè)表格更容易讀取。現(xiàn)在讓我們?nèi)パ芯亢瘮?shù)processXML:

 

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;
}

 

新增加的內(nèi)容,首先是兩個(gè)新變量的聲明:“subAry”和“subAryLen”。它們和之前的變量“dataArray”和“dataArrayLen”類似,除了它們指向不同的數(shù)組(特別是它們將指向那些“task”元素-當(dāng)“dataArray”和“dataArrayLen”指向“pet”元素的時(shí)候)。

我們也改變了變量“insertData”的初始值-我們增加了一個(gè)表格頭(<th> )給我們的“tasks”字段。

下一步改變在于循環(huán):我們把值賦給subAry和subAryLen變量。變量subAry成為當(dāng)前<pet> 的<task> 元素的數(shù)組。變量subAryLen成為這個(gè)數(shù)組的長度,直到這個(gè)數(shù)組發(fā)生變化(當(dāng)外部循環(huán)走到下一個(gè)<pet> 時(shí))。

我們創(chuàng)建了一個(gè)內(nèi)嵌的循環(huán)來處理所有的<task> 元素,一次一個(gè)。大概來說,我們創(chuàng)建一個(gè)新的數(shù)據(jù)格,放進(jìn)一個(gè)用逗號(hào)分隔的任務(wù)列表,然后關(guān)閉數(shù)據(jù)表格以及當(dāng)前行。尤其,這些<task> 元素節(jié)點(diǎn)數(shù)據(jù)(任務(wù)本身,比如,“喂食”)放置入變量“insertData”里的數(shù)據(jù)格。

接下來,我們檢驗(yàn)當(dāng)前<pet> 是否有其它更多的task。如果還有,我們增加一個(gè)逗號(hào)(,)到變量insertData來讓每一個(gè)任務(wù)使用一個(gè)逗號(hào)分隔(“a, b, c”,而不是“a, b, c,”-注意,最后一個(gè)逗號(hào)在第二個(gè)任務(wù)那里,所以我們不需要)。這個(gè)工作在我們?nèi)〉胹ubAry數(shù)組長度的時(shí)候(給循環(huán)的“j”變量加1)就完成了。因?yàn)檫@個(gè)循環(huán)會(huì)在下一個(gè)循環(huán)的時(shí)候把變量“j”遞增1,“j”會(huì)比它這次檢驗(yàn)時(shí)還多1。因此,如果“j+1”(或者,“當(dāng)循環(huán)再次開始的時(shí)候j的值”)等于subAryLen(當(dāng)前<pet> 節(jié)點(diǎn)的<task> 節(jié)點(diǎn)數(shù)目),這個(gè)循環(huán)將停止。如果循環(huán)不再運(yùn)行,我們就不再添加新的逗號(hào)來分隔任務(wù)。所以如果“j+1”不等于subAryLen,我們直到我們可以安全的加入逗號(hào)到“insertData”,為下一個(gè)<task> 作準(zhǔn)備。

一旦內(nèi)循環(huán)結(jié)束,我們關(guān)閉task數(shù)據(jù)格以及pet行。外部循環(huán)會(huì)重新開始創(chuàng)建一個(gè)新行以及移動(dòng)到下一個(gè)<pet> 。這個(gè)處理一直進(jìn)行到所有的<pet> 元素(以及每一個(gè)pet的所有<task> 元素)都被處理完。

有其他方法嗎?

你也許會(huì)想:“那javascript變得相當(dāng)復(fù)雜了,但它只會(huì)隨著XML越來越復(fù)雜而跟著變復(fù)雜,也許我們能夠簡化XML,然后,簡化javascript”。如果你這么想,很棒,因?yàn)槟阃耆_。我之前展示的不同方法之一,我詳細(xì)說明的那個(gè)也許能夠成為最合適的。我們怎么使用屬性來對(duì)應(yīng)每一只寵物以及相應(yīng)任務(wù)?XML看起來會(huì)變成怎樣?

 

<?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>

 

哇哦!看起來簡單多了。讓我們看看我們的processXML函數(shù)如何修改:

 

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;
}

 

(Sheneyan注:修改后的示例見:附件: example_2_4.htm ,XML文件見:附件: data_2_4.xml )

就像你猜的一樣,函數(shù)簡單多了。因?yàn)榇a變得簡單,它也會(huì)變得更有效率。和我們比較老的函數(shù)的唯一的不同在于這個(gè)變量insertData現(xiàn)在插入更多的HTML,尤其是兩個(gè)新變量“type”和“tasks”。就如我們較早之前所學(xué)的,那些屬性是我們從XML文檔的<pet> 元素中取得的,而且每個(gè)pet的屬性都有不同的值。對(duì)于你自己修改這個(gè)XML文件以適應(yīng)你的進(jìn)度的變動(dòng)來說也許是最簡單的方法。例如,如果你最終把你的貓身上的跳蚤抓光了,你只要簡單從你的貓的每日任務(wù)表中把“減少跳蚤數(shù)量”刪除,然而在之前我們使用的XML中,實(shí)現(xiàn)起來也許會(huì)覺得糊里糊涂。

最后的XML格式化的方法是將兩部分混合。現(xiàn)在,我們將使用屬性和不同的標(biāo)簽。讓我們看一下示例XML:

 

<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<貓 tasks="喂食, 飲水, 減少跳蚤數(shù)量" />
<狗 tasks="喂食, 飲水, 帶出去遛遛" />
<魚 tasks="喂食, 檢查氧氣,水的純度,其它" />
</pets>
</data>

 

這也許是最便于理解的XML。讓我們分析一下我們?yōu)榱俗宲rocessXML函數(shù)運(yùn)作起來所作的變更:

 

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;
}

 

(Sheneyan注:修改后的示例見:附件: example_2_5.htm ,XML文件見:附件: data_2_5.xml )

“dataArray”現(xiàn)在指向了<pets> 的子節(jié)點(diǎn),將它們作為一個(gè)數(shù)組對(duì)待(換句話說,dataArray現(xiàn)在是在<pets> 節(jié)點(diǎn)內(nèi)所有節(jié)點(diǎn)的數(shù)組)。這事因?yàn)槊恳粋(gè)標(biāo)簽都不同(<貓 /> ,<狗 /> ,<魚 /> ),所以我們不能使用這些元素的名稱來搜索它們(而之前我們可以使用<pet> ,因?yàn)樗械脑囟际牵紁et> )。

還是一樣,每個(gè)節(jié)點(diǎn)之間的有空格,所以在我們的處理過程中得排除掉文本節(jié)點(diǎn)。我們能夠檢驗(yàn)標(biāo)簽名是否存在-文本節(jié)點(diǎn)是節(jié)點(diǎn)但沒有標(biāo)簽,而<貓 /> ,<狗 /> ,<魚 /> 節(jié)點(diǎn)都是標(biāo)簽。所以如果一個(gè)標(biāo)簽有名字,那我們能夠?qū)?shù)據(jù)插入變量insertData。我們插入的數(shù)據(jù)是一個(gè)表格并有兩個(gè)表格數(shù)據(jù)格。這第一個(gè)單元格是標(biāo)簽名,也就是寵物的類型(貓,狗或魚),而第二個(gè)單元格則是指定動(dòng)物的“tasks”屬性值(比如“喂食或飲水”)。

結(jié)束語
在這篇文章里,我演示了這個(gè)例子的很多變化,你可以隨意試驗(yàn)它們來檢驗(yàn)?zāi)膫(gè)更適合你。只要記住一點(diǎn),XML是“可擴(kuò)展的”,所以沒有“錯(cuò)誤的”方法來組合你的數(shù)據(jù),雖然經(jīng)常有一個(gè)“最好的”方法。而且,要注意讓你的XML保持格式良好。記住很多問題來自于忘記結(jié)束一個(gè)標(biāo)簽(比如<狗 /> 而不是<狗> ;除非這個(gè)節(jié)點(diǎn)中有數(shù)據(jù),比如下面的<狗> 這里有數(shù)據(jù)哦</狗> )。

我意圖使XML和javascript的應(yīng)用不糊涂而變得明朗。一步步的學(xué)習(xí)處理更多的數(shù)據(jù),你能夠?qū)jax運(yùn)用于更大的用途。我希望看到ajax更多的應(yīng)用于企業(yè)網(wǎng)站,及其它。所以如果你將這些知識(shí)應(yīng)用于實(shí)踐,我很高興了解到你學(xué)到了什么(mail:jona#slightlyremarkable.com #換成@)。
在這個(gè)關(guān)于AJAX系列的第三部分中,我們將學(xué)習(xí)如何使用AJAX與服務(wù)端進(jìn)行寫作以及這些技術(shù)如何產(chǎn)生強(qiáng)大的web應(yīng)用程序。如果你對(duì)學(xué)習(xí)如何構(gòu)建類似GMail或者Google Maps的web程序感興趣的話,這是一篇基礎(chǔ)的入門(雖然那兩個(gè)東東會(huì)比我們在這篇文章中提及的內(nèi)容復(fù)雜的多)。在這篇文章中,我使用PHP作為服務(wù)端語言,但AJAX能夠和任何服務(wù)端語言進(jìn)行很好的兼容,所以你盡可以選擇你所鐘愛的任何語言!

我們還是從我們上一篇文章的代碼(喏,就在上面)開始我們的學(xué)習(xí),你可以去閱讀它來作為參考。

這里就是這個(gè)HTML頁面(帶js):

 

<!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開發(fā)web應(yīng)用程序--示例</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開發(fā)web應(yīng)用程序</h1>
<p> 這個(gè)頁面演示了AJAX技術(shù)如何通過動(dòng)態(tài)讀取一個(gè)遠(yuǎn)程文件來更新一個(gè)網(wǎng)頁的內(nèi)容--不需要任何網(wǎng)頁的重新加載。注意:這個(gè)例子對(duì)于禁止js的用戶來說沒有效果。</p>
<p> 這個(gè)頁面將演示如從取回并處理成組的XML數(shù)據(jù)。被取回的數(shù)據(jù)將會(huì)以表格形式輸出到底下。
<a href="#" onclick="ajaxRead('data_3.php'); return false"> 查看演示</a> .</p>
<div id="dataArea"> </div>
</body>
</html>

注意:這里唯一的變化就是我們將我們的ajaxRead()中的“data_2.xml”改成了“data_3.php”。這是因?yàn)槲覀儗⑹褂胮hp來輸出XML(如果你在你的瀏覽器里打開這個(gè)PHP文件,它會(huì)以一個(gè)XML文件的形式展現(xiàn)出來--我們只是要在這個(gè)文件中進(jìn)行操作而不只是一個(gè)簡單的XML)。這個(gè)PHP文件的輸出類似:

 

 

 

<?xml version="1.0" encoding="UTF-8"?>
<data>
<pets>
<貓 tasks="喂食, 飲水, 抓跳蚤" />
<狗 tasks="喂食, 飲水, 帶出去遛遛" />
<魚 tasks="喂食, 檢查氧氣,水的純度,其它" />
</pets>
</data>
(Sheneyan注:示例就不提供了,參考底下說明即可。)

 

這只是輸出結(jié)果,我們準(zhǔn)備從一個(gè)mysql數(shù)據(jù)庫中獲取這些信息。從現(xiàn)在起,我們可以直接在我們的數(shù)據(jù)庫中修改數(shù)據(jù)而不是手動(dòng)修改XML文件。用AJAX通過PHP來取得數(shù)據(jù),并將它獲取到一個(gè)頁面上--所有這些,仍然不需要重新加載網(wǎng)頁。

第一步是連接到mysql去獲取數(shù)據(jù)。這篇文章的重點(diǎn)在javascript,所以我不會(huì)解釋下面的代碼如何工作,你需要自己去了解如何連接mysql數(shù)據(jù)庫。

 

<?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);
?>

 

只要你連接了數(shù)據(jù)庫,你可以通過底下的查詢來獲取信息:

 

<?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);
?>

 

這段代碼給了你需要的信息,但它輸出并不正確。我們需要修改這PHP代碼來分隔數(shù)據(jù)為XML,而不是純文本。為了實(shí)現(xiàn)這個(gè)目標(biāo)我們得作幾個(gè)修改。

 

<?php
header('Content-Type: text/xml');//編號(hào)1
echo '<?xml version="1.0" encoding="UTF-8"?> ';//編號(hào)2
echo "\n<data> \n<pets> \n";//編號(hào)3
user = "admin";
pass = "adminpass";
host = "localhost";
conn = mysql_connect(host, user, pass) or die("無法連接mysql.");
db = mysql_select_db("pets",conn) or die("無法選擇數(shù)據(jù)庫.");
result = mysql_query("SELECT * FROM `pets`");
if(mysql_num_rows (result) == 0){
die ('Error: 數(shù)據(jù)庫沒有數(shù)據(jù).');
}
while (row = mysql_fetch_assoc(result)){
echo '<'.row['pet'].' tasks="'.row['tasks'].'" /> '."\n";//編號(hào)4
}
echo "</pets> \n</data> ";//編號(hào)5
mysql_close(db);
?>

 

讓我們從上面開始,一次一行的來分析它是如何輸出XML的.我給每一行都加了注釋標(biāo)記以便于更好的對(duì)應(yīng)理解(原文是I've color-coded each line to make it easier to understand,我懶得上色,就改成用編號(hào)了)

編號(hào)1:這部分代碼發(fā)送一個(gè)http頭來讓用戶客戶端明白這個(gè)php文件輸出的是一個(gè)XML。這就是為什么你在你的瀏覽器里看這個(gè)文檔的時(shí)候它以一個(gè)XML文件的形式展現(xiàn),即使你的文件有一個(gè)“.php”后綴。

編號(hào)2:這部分的代碼輸出了XML聲明。這是我之前展示給你看的XML的第一行。

編號(hào)3:這部分的代碼輸出的最開始的兩個(gè)標(biāo)簽:我們的根標(biāo)簽,<data> 和我們用來放置所有寵物的<pets> 標(biāo)簽。

編號(hào)4:這部分的代碼最困難的。這里包含了一個(gè)循環(huán)用來遍歷你數(shù)據(jù)庫里所有的數(shù)據(jù)。每次循環(huán),它會(huì)輸出一個(gè)新的節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)用每一種動(dòng)物作為標(biāo)簽名以及一個(gè)"任務(wù)"屬性。例如,如果你數(shù)據(jù)庫中的第一只寵物是“貓”而且它相應(yīng)的任務(wù)字段是“喂食, 飲水, 抓跳蚤”,那php將輸出在XML文檔中輸出 <貓 tasks="喂食, 飲水, 抓跳蚤" /> 。這個(gè)“\n” 部分只是在結(jié)尾插入一個(gè)新行,保證這個(gè)XML代碼不至于都在同一行。

編號(hào)5:這部分的代碼結(jié)束了 我們開始時(shí)打開的</pets> 和 </data> 節(jié)點(diǎn)。因?yàn)閄ML必須是格式良好的(well-formed),所以我們必須認(rèn)真對(duì)待這部分以確認(rèn)我們的程序能夠正確運(yùn)行。

現(xiàn)在我們已經(jīng)讓PHP輸出XML了,我們現(xiàn)在所要作的就是登錄我們的mysql數(shù)據(jù)庫,并進(jìn)行我們所需要的修改,來更新這個(gè)XML。很酷,不是嗎?我們?nèi)匀荒軌蚴褂蒙弦黄恼轮械膉s腳本來獲取代碼,因?yàn)閄ML輸出和之前的完全一樣。

結(jié)論

你可以再進(jìn)一步的擴(kuò)展,使用XML來保存和獲取數(shù)據(jù)。換句話說,你能夠使用php來寫你的XML文件,然后讓javascript來讀。用ajax,你也能夠定時(shí)的檢查xml文件是否已經(jīng)更改而且,如果XML已經(jīng)更新,也可以更新本頁面。

 

分享:解讀AJAX是否能夠取代桌面應(yīng)用程序
一、 引言 在AJAX是否能夠取代桌面應(yīng)用程序的問題上,存在很多爭論。如今,這兩種陣營正在逐步形成。在本文中,我的看法是:AJAX不可能取代桌面應(yīng)用程序;但是它將導(dǎo)致一種新型軟件應(yīng)用程序的出現(xiàn)。大多數(shù)AJAX程序應(yīng)該會(huì)是生產(chǎn)工具、協(xié)作和商業(yè)應(yīng)用程序。許

來源:模板無憂//所屬分類:AJAX教程/更新時(shí)間:2010-04-13
相關(guān)AJAX教程
成人av在线亚洲| 久久久久久久av麻豆果冻| 欧美日韩亚洲综合在线 欧美亚洲特黄一级| 91高清免费视频| 日韩av播放器| 在线免费看91| 日韩一区二区久久| 欧美在线free| 高清国语自产拍免费一区二区三区| 日本人妻一区二区三区| 亚洲欧美日韩动漫| 久久国产婷婷国产香蕉| 欧美videos大乳护士334| 久久国产精品精品国产色婷婷| 巨胸大乳www视频免费观看| 素人啪啪色综合| 国产盗摄一区二区三区| 欧美经典一区| 午夜国产精品视频免费体验区| 亚洲成人一区二区| 国产精品福利小视频| 男生和女生一起差差差视频| www.com.cn成人| 极品少妇xxxx偷拍精品少妇| 亚洲黄页视频免费观看| 亚洲永久激情精品| 日韩毛片在线视频| 中文在线播放一区二区| 色综合久久久网| 亚洲中国色老太| 波多野结衣av在线免费观看| 国产精久久久| 国产日本欧美一区二区| 国产最新精品视频| 日韩 国产 一区| 午夜av成人| av一区二区三区| 久久伊人精品天天| 免费看国产黄色片| 韩国成人漫画| 成人av第一页| 欧美大胆在线视频| wwww.国产| 婷婷综合六月| av欧美精品.com| 欧美日本在线视频中文字字幕| 国产v亚洲v天堂无码久久久| 人妻少妇精品无码专区| 丁香激情综合国产| 久久久精品国产亚洲| 免费一级特黄录像| 亚洲承认视频| 久久久久久久性| 久久久欧美精品| 欧美日韩在线观看一区二区三区| 国产欧美一区二区三区视频| 制服丝袜中文字幕第一页| 久久精品女人天堂av免费观看 | 亚洲第一区在线观看| 正在播放久久| 国产强伦人妻毛片| 国产老女人精品毛片久久| 久久成人一区二区| 一级黄色免费毛片| 最新国产一区二区| 一区二区欧美视频| 国产精品免费观看高清| 精品少妇爆乳无码av无码专区| 欧美精选在线| 精品国产91洋老外米糕| 99在线免费视频观看| 免费观看国产精品| ww亚洲ww在线观看国产| 青草青草久热精品视频在线观看| 制服丝袜第二页| 久久av导航| 欧美人体做爰大胆视频| 中文字幕一区综合| 国产精品无码免费播放| 国产在线精品一区二区夜色| xxx一区二区| √天堂资源在线| 香蕉成人在线| 椎名由奈av一区二区三区| 自拍偷拍亚洲精品| 熟妇人妻va精品中文字幕| 无码国产精品一区二区色情男同| av中文字幕亚洲| 久久免费视频这里只有精品| 想看黄色一级片| 麻豆一二三区精品蜜桃| 亚洲另类色综合网站| 91在线|亚洲| 青娱乐国产精品| 伊人久久大香线蕉av超碰演员| 欧美精品一区二区精品网| 伊人久久大香线蕉av一区| www香蕉视频| www成人在线观看| 国产激情久久久久| 日韩欧美国产系列| 91在线观看免费网站| 爱爱视频免费在线观看| 欧美激情视频一区二区三区在线播放 | 成人黄动漫网站免费| 国产高清在线免费观看| 精品福利av| 亚洲男人天堂2023| 日韩大片一区二区| 欧美日韩一区二区三区四区不卡| 欧美午夜无遮挡| 相泽南亚洲一区二区在线播放| 中文字幕在线视频第一页| 精品一区二区精品| 欧美高跟鞋交xxxxhd| 在线观看免费视频黄| 免费成人网www| 色菇凉天天综合网| 97中文字幕在线| 日韩免费小视频| 亚洲人吸女人奶水| 国产一区二区三区av在线| 无码人妻精品一区二区| 国产在线精品一区二区夜色| 97在线视频精品| 欧美福利在线视频| 一区二区影视| 最近2019中文字幕一页二页| www.美色吧.com| 日韩精品午夜| 亚洲福利精品在线| 日韩精品你懂的| 老司机aⅴ在线精品导航| 精品1区2区3区| 日本十八禁视频无遮挡| av在线国产精品| 欧美性高潮床叫视频| 综合久久国产| 毛片无码国产| 精品国产亚洲av麻豆| 丝袜美腿亚洲综合| 欧美人交a欧美精品| 粉嫩av蜜桃av蜜臀av| 精品视频网站| 日韩精品资源二区在线| 国产视频手机在线播放| 亚洲另类av| 精品国产91洋老外米糕| 污网站在线免费| 九一亚洲精品| 亚洲第一视频网站| 欧美精品色视频| 亚洲国产精品久久久天堂| 亚洲日本成人女熟在线观看| 色男人天堂av| 天天综合亚洲| 在线视频日本亚洲性| 手机在线免费毛片| 一区二区国产在线| 最近2019中文字幕大全第二页| 欧美成人三级伦在线观看| 欧美精品日本| 久久国产天堂福利天堂| 青青青视频在线播放| 国产欧美91| 国产成人精品免费视频| 日本三级中文字幕| 成人永久免费视频| 懂色中文一区二区三区在线视频 | 欧美视频一区二| 日本熟妇人妻xxxxx| а√中文在线天堂精品| 精品免费日韩av| 久久久久国产免费| 国内自拍一区| 欧美精品成人在线| 国产亚洲第一页| 成人av片在线观看| 91丨九色丨国产在线| 国产成人手机在线| 亚洲香肠在线观看| 欧妇女乱妇女乱视频| 一区二区日韩| 日韩精品一区二区在线| 免费观看黄网站| 欧美人成在线| 久久精品久久精品亚洲人| 91精品国产高清一区二区三蜜臀| 国产电影精品久久禁18| av免费观看久久| 亚洲精品久久久久久久久久| 亚洲va国产va欧美va观看| 人体内射精一区二区三区| 欧美日韩另类图片| 亚洲美女福利视频网站| 一区二区三区影视| 高清视频一区二区| 久久亚裔精品欧美| 国产超碰精品| 在线电影院国产精品| 日本黄色一级网站| 一本色道久久综合亚洲精品不卡| 久久久中文字幕| 天天综合网久久综合网| 国产欧美一区二区精品性| 五码日韩精品一区二区三区视频| 福利一区二区三区视频在线观看| 欧美日韩二区三区| 欧美xxxx日本和非洲| 西西裸体人体做爰大胆久久久| 欧美中文在线观看国产| 美女黄页在线观看| 亚洲精品美国一| 欧美日韩性生活片| 久久在线视频免费观看| 欧美激情视频网| 黄色av网站免费观看| 午夜欧美大尺度福利影院在线看| 国产亚洲天堂网| 欧美男男gaytwinkfreevideos| 色妞一区二区三区| 日韩精品视频播放| 中文字幕日本不卡| 免费看黄色一级大片| 亚洲视频久久| 国产精品视频自拍| 亚洲欧美另类综合| 欧美在线观看视频一区二区三区| 奇米视频7777| 黄色欧美成人| 3d蒂法精品啪啪一区二区免费| 中文字幕在线视频网站| 羞羞色国产精品| 国产伦精品一区二区三区视频网站| 亚洲最大色网站| 污污网站免费看| 日韩网站在线| 91精品视频在线看| japanese23hdxxxx日韩| 精品国产百合女同互慰| 国产精品视频在| 99免费精品视频| 精品一区二区三区毛片| 精品国产乱码久久久| 国内精品小视频在线观看| 亚洲天堂777| 一本一道波多野结衣一区二区| 国产乱叫456| 日本视频在线一区| 精品视频一区在线| 欧美一级大片在线视频| 中文字幕欧美精品日韩中文字幕| 日韩少妇高潮抽搐| 亚洲一区在线视频观看| 色啦啦av综合| 久久av最新网址| 国产精品久久精品国产| 国产精品亚洲综合在线观看 | 日本午夜在线亚洲.国产| 亚洲第一页综合| 日韩丝袜美女视频| 亚洲欧美精品久久| 中文字幕一区二区日韩精品绯色| 成人羞羞国产免费网站| 国产日韩高清一区二区三区在线| 97人人澡人人爽| 国产精品麻豆| 亚洲午夜色婷婷在线| 中文字幕精品无| 在线亚洲一区二区| 一女三黑人理论片在线| caoporn国产精品| 丰满少妇久久久| 99成人免费视频| 乱一区二区三区在线播放| 欧美日韩夜夜| 日韩av电影在线播放| 写真福利精品福利在线观看| 亚洲欧美精品中文字幕在线| 国产成人在线免费视频| 亚洲香肠在线观看| 国产免费一区二区三区网站免费| 久久新电视剧免费观看| wwwxxx黄色片| 奇米一区二区三区| 一级二级三级欧美| 欧美日韩视频| 久久综合九色欧美狠狠| 久久av电影| 国产精品情侣自拍| 综合久久伊人| 欧美第一黄色网| 国内精品国产成人国产三级| 亚洲美女喷白浆| 正在播放木下凛凛xv99| 91麻豆精品国产91久久久久| 老女人性淫交视频| 欧美日韩国产精品专区 | 欧美午夜精品| 久久riav二区三区| 欧美日韩在线播放视频| 成人综合网网址| a一区二区三区亚洲| 欧美在线日韩在线| 成人四虎影院| 欧美大片免费观看| 欧美电影网站| 久久精品国产久精国产一老狼| 亚洲精品字幕在线| 精品视频久久久久久久| 久久久久久少妇| 欧美一区二区三区男人的天堂| 国产精品1000| 欧美三级电影网站| 天天操天天摸天天干| 欧美日本高清视频在线观看| 久久免费公开视频| 欧美性欧美巨大黑白大战| 侵犯稚嫩小箩莉h文系列小说| 亚洲精品乱码久久久久久日本蜜臀| 熟女高潮一区二区三区| 亚洲精品国产a| 美女久久久久久久久久| 亚洲人妖av一区二区| 亚洲天堂成人av| 欧美国产精品劲爆| 30一40一50老女人毛片| 亚洲欧美日韩国产手机在线| 亚洲中文字幕一区| 亚洲特级片在线| 国产精品久久久久无码av色戒| 亚洲福利视频一区| 网爆门在线观看| 欧美日韩亚洲天堂| www.超碰在线观看| 欧美在线视频日韩| 日韩精品视频免费播放| 欧美一区二区大片| 波多野结衣高清在线| 亚洲精品一区二区三区福利 | 2018中文字幕第一页| 麻豆一区二区三| 日韩av片在线看| 成人免费看视频| 亚洲无在线观看| 欧美高清在线视频| 日本japanese极品少妇| 图片区小说区国产精品视频| 国产日韩欧美在线观看视频| 日本韩国精品在线| 国产午夜精品无码一区二区| 337p亚洲精品色噜噜| 国产午夜福利一区二区| 日韩av在线导航| 黑人操亚洲女人| 欧美日韩国产va另类| 亚洲成a人片777777久久| 国产99视频在线观看| 日韩电影不卡一区| 国产传媒欧美日韩| 欧美激情日韩| 肉大捧一出免费观看网站在线播放 | 亚洲va欧美va天堂v国产综合| 中文字幕人妻一区二区| 色婷婷久久久亚洲一区二区三区 | 欧美色视频日本高清在线观看| 欧美黄色一区二区三区| 欧美一区二区三区婷婷月色| 91高潮大合集爽到抽搐| 欧美大胆在线视频| 亚洲一区二区三区免费| 成人av免费在线看| 永久亚洲成a人片777777| 一区二区三区四区五区视频| 日韩精品久久理论片| 国产96在线 | 亚洲| 99国产欧美另类久久久精品 | 国产午夜无码视频在线观看| 国产香蕉97碰碰久久人人| 高清不卡av| 欧美亚洲一级片| 国产va免费精品观看精品视频| 农村寡妇一区二区三区| 免费精品视频| 日本爱爱免费视频| 亚洲日本中文字幕区| 永久久久久久久| 亚洲成人网久久久| 午夜视频免费看| 国产日韩精品在线观看| 欧美搞黄网站| 精品久久久久久无码中文野结衣| www.亚洲精品| 中文字幕一区二区三区人妻电影| 欧美日韩国产高清一区二区三区| 国产精品特级毛片一区二区三区| 欧美大片在线看| 猛男gaygay欧美视频| 久久精品国产综合精品| 精品无人码麻豆乱码1区2区|