久久精品水蜜桃av综合天堂,久久精品丝袜高跟鞋,精品国产肉丝袜久久,国产一区二区三区色噜噜,黑人video粗暴亚裔

Ajax- 動(dòng)態(tài)更新Web頁面

來自站長(zhǎng)百科
跳轉(zhuǎn)至: 導(dǎo)航、? 搜索

導(dǎo)航: 上一頁 | ASP | PHP | JSP | HTML | CSS | XHTML | aJAX | Ruby | JAVA | XML | Python | ColdFusion

如前所述,如果頁面中只有一小部分需要修改,此時(shí)Ajax技術(shù)最適用。換句話說,以前實(shí)現(xiàn)一些用例時(shí),為了更新頁面中的一小部分總是需要使用完全頁面刷新,這些用例就很適合采用Ajax技術(shù)

考慮一個(gè)有單個(gè)頁面的用例,用戶向這個(gè)頁面輸入的信息要增加到列表中。在這個(gè)例子中,你會(huì)看到列出某個(gè)組織中員工的Web頁面。頁面最上面有3個(gè)輸入框,分別接受員工的姓名、職位和部門。點(diǎn)擊Add(增加)按鈕,將員工的姓名、職位和部門數(shù)據(jù)提交到服務(wù)器,在這里將這些員工信息增加到數(shù)據(jù)庫(kù)中。

當(dāng)使用傳統(tǒng)的Web應(yīng)用技術(shù)時(shí),服務(wù)器以重新創(chuàng)建整個(gè)頁面來做出響應(yīng),與前一個(gè)頁面相比,惟一的差別只是新員工信息會(huì)增加到列表中。在這個(gè)例子中,我們要使用Ajax技術(shù)異步地將員工數(shù)據(jù)提交到服務(wù)器,并把該數(shù)據(jù)插入到數(shù)據(jù)庫(kù)中。服務(wù)器發(fā)送一個(gè)狀態(tài)碼向?yàn)g覽器做出響應(yīng),指示數(shù)據(jù)庫(kù)操作是否成功。假設(shè)數(shù)據(jù)庫(kù)成功插入,瀏覽器會(huì)使用JavaScript DOM操作用新員工信息動(dòng)態(tài)更新頁面內(nèi)容。這個(gè)例子中還創(chuàng)建了Delete(刪除)按鈕,以便從數(shù)據(jù)庫(kù)中刪除員工信息。

代碼清單4-13顯示了HTML Web頁面的源代碼。這個(gè)頁面有兩部分:第一部分包括一些輸入框,分別接受員工姓名、職位和部門的數(shù)據(jù),以及啟動(dòng)數(shù)據(jù)庫(kù)插入的Add按鈕;第二部分列出數(shù)據(jù)庫(kù)中的所有員工,每個(gè)記錄有自己的Delete按鈕,從而能從數(shù)據(jù)庫(kù)刪除這個(gè)記錄的信息。

代碼清單4-13 employeeList.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Employee List</title>
<script type="text/javascript">
var xmlHttp;
var name;
var title;
var department;
var deleteID;
var EMP_PREFIX = "emp-";
function createXMLHttpRequest() {
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}
function addEmployee() {
name = document.getElementById("name").value;
title = document.getElementById("title").value;
department = document.getElementById("dept").value;
action = "add";
if(name == "" || title == "" || department == "") {
return;
}
var url = "EmployeeList?"
+ createAddQueryString(name, title, department, "add")
+ "&ts=" + new Date().getTime();
createXMLHttpRequest();
xmlHttp.onreadystatechange = handleAddStateChange;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function createAddQueryString(name, title, department, action) {
var queryString = "name=" + name
+ "&title=" + title
+ "&department=" + department
+ "&action=" + action;
return queryString;
}
function handleAddStateChange() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
updateEmployeeList();
clearInputBoxes();
}
else {
alert("Error while adding employee.");
}
}
}
function clearInputBoxes() {
document.getElementById("name").value = "";
document.getElementById("title").value = "";
document.getElementById("dept").value = "";
}
function deleteEmployee(id) {
deleteID = id;
var url = "EmployeeList?"
+ "action=delete"
+ "&id=" + id
+ "&ts=" + new Date().getTime();
createXMLHttpRequest();
xmlHttp.onreadystatechange = handleDeleteStateChange;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function updateEmployeeList() {
var responseXML = xmlHttp.responseXML;
var status = responseXML.getElementsByTagName("status")
.item(0).firstChild.nodeValue;
status = parseInt(status);
if(status != 1) {
return;
}
var row = document.createElement("tr");
var uniqueID = responseXML.getElementsByTagName("uniqueID")[0]
.firstChild.nodeValue;
row.setAttribute("id", EMP_PREFIX + uniqueID);
row.appendChild(createCellWithText(name));
row.appendChild(createCellWithText(title));
row.appendChild(createCellWithText(department));
var deleteButton = document.createElement("input");
deleteButton.setAttribute("type", "button");
deleteButton.setAttribute("value", "Delete");
deleteButton.onclick = function () { deleteEmployee(uniqueID); };
cell = document.createElement("td");
cell.appendChild(deleteButton);
row.appendChild(cell);
document.getElementById("employeeList").appendChild(row);
updateEmployeeListVisibility();
}
function createCellWithText(text) {
var cell = document.createElement("td");
cell.appendChild(document.createTextNode(text));
return cell;
}
function handleDeleteStateChange() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
deleteEmployeeFromList();
}
else {
alert("Error while deleting employee.");
}
}
}
function deleteEmployeeFromList() {
var status =
xmlHttp.responseXML.getElementsByTagName("status")
.item(0).firstChild.nodeValue;
status = parseInt(status);
if(status != 1) {
return;
}
var rowToDelete = document.getElementById(EMP_PREFIX + deleteID);
var employeeList = document.getElementById("employeeList");
employeeList.removeChild(rowToDelete);
updateEmployeeListVisibility();
}
function updateEmployeeListVisibility() {
var employeeList = document.getElementById("employeeList");
if(employeeList.childNodes.length > 0) {
document.getElementById("employeeListSpan").style.display = "";
}
else {
document.getElementById("employeeListSpan").style.display = "none";
}
}
</script>
</head>
<body>
v<h1>Employee List</h1>
<form action="#">
<table width="80%" border="0">
<tr>
<td>Name: <input type="text" id="name"/></td>
<td>Title: <input type="text" id="title"/></td>
<td>Department: <input type="text" id="dept"/></td>
</tr>
<tr>
<td colspan="3" align="center">
<input type="button" value="Add" onclick="addEmployee();"/>
</td>
</tr>
</table>
</form>
<span id="employeeListSpan" style="display:none;">
<h2>Employees:</h2>
<table border="1" width="80%">
<tbody id="employeeList"></tbody>
</table>
</span>
</body>
</html>

點(diǎn)擊Add按鈕啟動(dòng)數(shù)據(jù)庫(kù)插入操作?;贏dd按鈕的onclick事件將調(diào)用addEmployee函數(shù)。addEmployee函數(shù)使用createAddQueryString來建立查詢串,其中包括用戶輸入的員工姓名、職位和部門信息。創(chuàng)建XMLHttpRequest對(duì)象并設(shè)置onreadystatechange事件處理程序后,請(qǐng)求提交到服務(wù)器。

代碼清單4-14列出了處理請(qǐng)求的Java servlet,當(dāng)接收到請(qǐng)求時(shí)將調(diào)用servlet的doGet方法。這個(gè)方法獲取查詢串a(chǎn)ction參數(shù)的值,并把請(qǐng)求指向適當(dāng)?shù)姆椒?。如果是增加信息,?qǐng)求指向addEmployee方法。

代碼清單4-14 EmployeeListServlet.java

package ajaxbook.chap4;
import java.io.*;
import java.net.*;
import java.util.Random;
import javax.servlet.*;
import javax.servlet.http.*;
public class EmployeeListServlet extends HttpServlet {
protected void addEmployee(HttpServletRequest request
, HttpServletResponse response)
throws ServletException, IOException {
//Store the object in the database
String uniqueID = storeEmployee();
//Create the response XML
StringBuffer xml = new StringBuffer("<result><uniqueID>");
xml.append(uniqueID);
xml.append("</uniqueID>");
xml.append("</result>");
//Send the response back to the browser
sendResponse(response, xml.toString());
}
protected void deleteEmployee(HttpServletRequest request
, HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id");
/* Assume that a call is made to delete the employee from the database */
//Create the response XML
StringBuffer xml = new StringBuffer("<result>");
xml.append("<status>1</status>");
xml.append("</result>");
//Send the response back to the browser
sendResponse(response, xml.toString());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
if(action.equals("add")) {
addEmployee(request, response);
}
else if(action.equals("delete")) {
deleteEmployee(request, response);
}
}
private String storeEmployee() {
/* Assume that the employee is saved to a database and the
* database creates a unique ID. Return the unique ID to the
* calling method. In this case, make up a unique ID.
*/
String uniqueID = "";
Random randomizer = new Random(System.currentTimeMillis());
for(int i = 0; i < 8; i++) {
uniqueID += randomizer.nextInt(9);
}
return uniqueID;
}
private void sendResponse(HttpServletResponse response, String responseText)
throws IOException {
response.setContentType("text/xml");
response.getWriter().write(responseText);
}

}

addEmployee函數(shù)負(fù)責(zé)協(xié)調(diào)數(shù)據(jù)庫(kù)插入和服務(wù)器響應(yīng)。addEmployee方法委托store- Employee方法完成具體的數(shù)據(jù)庫(kù)插入。在實(shí)際實(shí)現(xiàn)中,storeEmployee方法很可能調(diào)用數(shù)據(jù)庫(kù)服務(wù),由它處理數(shù)據(jù)庫(kù)插入的具體細(xì)節(jié)。在這個(gè)簡(jiǎn)化的例子中,storeEmployee將模擬數(shù)據(jù)庫(kù)插入,其方法是生成一個(gè)隨機(jī)的惟一ID,模擬實(shí)際數(shù)據(jù)庫(kù)插入可能返回的ID。生成的惟一ID再返回給addEmployee方法。

假設(shè)數(shù)據(jù)庫(kù)插入成功,addEmployee方法則繼續(xù)準(zhǔn)備響應(yīng)。響應(yīng)是一個(gè)簡(jiǎn)單的XML串,它向?yàn)g覽器返回一個(gè)狀態(tài)碼。XML通過串連接創(chuàng)建,然后寫至響應(yīng)的輸出流。

瀏覽器通過調(diào)用handleAddStateChange方法來處理服務(wù)器的響應(yīng)。只要XMLHttpReq- uest對(duì)象發(fā)出信號(hào)指出其內(nèi)部準(zhǔn)備狀態(tài)有變化,就會(huì)調(diào)用這個(gè)方法。一旦readystate屬性指示服務(wù)器響應(yīng)已經(jīng)成功完成,就會(huì)調(diào)用updateEmployeeList函數(shù),然后再調(diào)用clear- InputBoxes函數(shù)。updateEmployeeList函數(shù)負(fù)責(zé)把成功插入的員工信息增加到頁面上顯示的員工列表中。clearInputBoxes函數(shù)是一個(gè)簡(jiǎn)單的工具方法,它會(huì)清空輸入框,準(zhǔn)備接收下一個(gè)員工的信息。

updateEmployeeList函數(shù)向表中增加行以列出員工的信息。首先使用document.cre- ateElement方法來創(chuàng)建表行的一個(gè)實(shí)例。這一行的id屬性設(shè)置為包括由數(shù)據(jù)庫(kù)插入生成的惟一ID的值。id屬性值惟一地標(biāo)識(shí)了表行,這樣點(diǎn)擊Delete按鈕時(shí)就能很容易地從表中刪除這一行。

updateEmployeeList函數(shù)使用名為createCellWithText的工具函數(shù)來創(chuàng)建表單元格元素,其中包含指定的文本。createCellWithText函數(shù)分別為用戶輸入的姓名、職位和部門信息創(chuàng)建表單元格,再把各個(gè)單元格增加到先前創(chuàng)建的表行中。

最后要?jiǎng)?chuàng)建的是Delete按鈕以及包含這個(gè)按鈕的單元格。使用document.createElement方法創(chuàng)建通用的輸入元素,其type和value屬性分別設(shè)置為button和Delete,這樣就能創(chuàng)建Delete按鈕。再創(chuàng)建表單元格,用來放置Delete按鈕,并把Delete按鈕作為子元素增加到表單元格。然后把這個(gè)單元格增加到表行,接下來將這一行增加到員工列表中,現(xiàn)在行中已經(jīng)包含了對(duì)應(yīng)員工姓名、職位、部門和Delete按鈕的單元格。

刪除員工與增加員工的工作是一樣的。Delete按鈕的onclick事件處理程序調(diào)用delete- Employee函數(shù),將員工的惟一ID傳遞給這個(gè)函數(shù)。此時(shí)創(chuàng)建一個(gè)簡(jiǎn)單的查詢串,指示想做的動(dòng)作(刪除)和要?jiǎng)h除的員工記錄的惟一ID。XMLHttpRequest對(duì)象的onreadystatechange屬性設(shè)置為所需的事件處理程序后,提交請(qǐng)求。

EmployeeListServlet servlet使用deleteEmployee方法來處理員工刪除用例。這個(gè)例子做了簡(jiǎn)化,在此假設(shè)還有另一個(gè)方法處理數(shù)據(jù)庫(kù)刪除的具體細(xì)節(jié)。如果成功地完成了數(shù)據(jù)庫(kù)刪除,deleteEmployee方法會(huì)準(zhǔn)備XML串,返回給瀏覽器。與員工增加用例類似,這個(gè)用例向?yàn)g覽器返回一個(gè)狀態(tài)碼。一旦創(chuàng)建XML串,則將XML串通過響應(yīng)對(duì)象的輸出流寫回到瀏覽器。

瀏覽器通過handleDeleteStateChange函數(shù)處理服務(wù)器響應(yīng),如果響應(yīng)成功,將轉(zhuǎn)發(fā)到deleteEmployeeFromList方法。deleteEmployeeFromList函數(shù)從XML響應(yīng)獲取狀態(tài)碼,如果狀態(tài)碼指示刪除不成功,這個(gè)函數(shù)將立即退出。假設(shè)成功地完成了刪除操作,這個(gè)函數(shù)則會(huì)繼續(xù),使用document.getElementById方法獲取表示所刪除信息的表行,然后使用表體的removeChild方法從中刪除這一行。

為什么不使用setattribute方法來設(shè)置DELETE按鈕的事件處理程序?

你可能已經(jīng)注意到,設(shè)置Delete按鈕的事件處理程序時(shí)采用了何種方法。你可能認(rèn)為,設(shè)置Delete按鈕的onclick事件處理程序的代碼應(yīng)該如下所示:

deleteButton.setAttribute("onclick", "deleteEmployee('" + unique_id + "');");

確實(shí),這個(gè)代碼從理論上是對(duì)的,它遵循W3C標(biāo)準(zhǔn),而且在大多數(shù)當(dāng)前瀏覽器中都可行,只有IE例外。幸運(yùn)的是,對(duì)于IE也有一個(gè)解決辦法,它可以在Firefox、Opera、Safari和Konqueror中適用。

這種解決辦法是使用點(diǎn)記法引用Delete按鈕的onclick事件處理程序,然后使用調(diào)用deleteEmployee函數(shù)的匿名函數(shù)來設(shè)置事件處理程序。

圖4-14顯示了實(shí)際運(yùn)行的動(dòng)態(tài)更新例子。
Image014.jpg 圖4-14 每次點(diǎn)擊Add按鈕時(shí)每個(gè)姓名動(dòng)態(tài)增加到列表中,而不必每次都刷新頁面