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

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

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

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

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

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

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

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

代碼清單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>

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

代碼清單4-14列出了處理請求的Java servlet,當接收到請求時將調(diào)用servlet的doGet方法。這個方法獲取查詢串a(chǎn)ction參數(shù)的值,并把請求指向適當?shù)姆椒āH绻窃黾有畔?,請求指向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ù)負責(zé)協(xié)調(diào)數(shù)據(jù)庫插入和服務(wù)器響應(yīng)。addEmployee方法委托store- Employee方法完成具體的數(shù)據(jù)庫插入。在實際實現(xiàn)中,storeEmployee方法很可能調(diào)用數(shù)據(jù)庫服務(wù),由它處理數(shù)據(jù)庫插入的具體細節(jié)。在這個簡化的例子中,storeEmployee將模擬數(shù)據(jù)庫插入,其方法是生成一個隨機的惟一ID,模擬實際數(shù)據(jù)庫插入可能返回的ID。生成的惟一ID再返回給addEmployee方法。

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

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

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

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

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

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

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

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

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

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

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

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

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

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