最近在学习Ajax的过程中,做了一个关于图书的购物车示例,图书的信息保存在服务器端的XML文档中,通过Ajax的异步交互获取XML文件内容,然后在客户端解析XML DOM,最后再在客户端用JS实现简单的分页。
本人觉得JS文件中的分页做得不是很好,请各位能够多多提点意见,大家共同进步。
效果示例图:
---------------------------以下是基本的文件代码-----------------------------
bookList.xml-->存储书本信息
<?xml version="1.0" encoding="utf-8"?>
<CATALOG>
<BOOK>
<Img>001.jpg</Img>
<BookName>Beginning ASP.NET with C #</BookName>
<Authors>Hart, Kauffman, Sussman, Ullman</Authors>
<ISBN>0764588508</ISBN>
<Price>$39.99</Price>
<Quantity>50</Quantity>
<VerYear>1985</VerYear>
</BOOK>
<BOOK>
<Img>002.jpg</Img>
<BookName>计算机技术集成概论</BookName>
<Authors>张三牛</Authors>
<ISBN>0764588509</ISBN>
<Price>$59.99</Price>
<Quantity>45</Quantity>
<VerYear>2001</VerYear>
</BOOK>
<BOOK>
<Img>003.jpg</Img>
<BookName>操作系统原理</BookName>
<Authors>李四喜</Authors>
<ISBN>0764588510</ISBN>
<Price>$69.99</Price>
<Quantity>55</Quantity>
<VerYear>2002</VerYear>
</BOOK>
<BOOK>
<Img>004.jpg</Img>
<BookName>汇编语言</BookName>
<Authors>刘也</Authors>
<ISBN>0764588511</ISBN>
<Price>$69.99</Price>
<Quantity>55</Quantity>
<VerYear>2002</VerYear>
</BOOK>
<BOOK>
<Img>005.jpg</Img>
<BookName>Oracle 实用开发指南</BookName>
<Authors>朱五六</Authors>
<ISBN>0764588513</ISBN>
<Price>$69.99</Price>
<Quantity>55</Quantity>
<VerYear>2002</VerYear>
</BOOK>
<BOOK>
<Img>006.jpg</Img>
<BookName>Ajax的工作原理</BookName>
<Authors>李小将</Authors>
<ISBN>0764588514</ISBN>
<Price>$69.99</Price>
<Quantity>55</Quantity>
<VerYear>2002</VerYear>
</BOOK>
<BOOK>
<Img>007.jpg</Img>
<BookName>数据结构</BookName>
<Authors>何伟</Authors>
<ISBN>0764588515</ISBN>
<Price>$69.99</Price>
<Quantity>55</Quantity>
<VerYear>2002</VerYear>
</BOOK>
<BOOK>
<Img>008.jpg</Img>
<BookName>SQL Server开发指南</BookName>
<Authors>耿文化</Authors>
<ISBN>0764588516</ISBN>
<Price>$69.99</Price>
<Quantity>55</Quantity>
<VerYear>2002</VerYear>
</BOOK>
</CATALOG>
Cart.js-->异步交互的JS文件
var xmlHttpRequest;
var currentPage = 0;//记录当前页索引
var everyPageCount = 3;//每页显示的项目数量
var maxPageCount = 0;//记录最大页数
var bookIndex = -1;//当前BOOK元素的索引
var result = null;//服务器返回的XML文档对象
var bookNodes = null;//储存所有BOOK节点对象
//创建一个用来和服务端交互的Ajax核心对象XMLHttpRequest
function createXMLHttpRequest(){
if(window.XMLHttpRequest){
xmlHttpRequest = new XMLHttpRequest();
if(xmlHttpRequest.overrideMimeType){
xmlHttpRequest.overrideMimeType("text/xml");
}
}
else if(window.ActiveXObject){
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
}
//使用传统的注册事件模型注册按钮
function registerButtonEvent(){
document.getElementById("previousPage").onclick = sendPreviousPage;
document.getElementById("nextPage").onclick = sendNextPage;
}
//购物车页面初始化
function sendRequest(){
registerButtonEvent();//注册页面的按钮事件
createXMLHttpRequest();//创建XMLHttpRequest对象
//异步加载XML文档数据
xmlHttpRequest.open("GET", "bookList.xml?id=" + Number(new Date), true);
//指定回调函数
xmlHttpRequest.onreadystatechange = getInitData;
xmlHttpRequest.send(null);
}
//页面初始化回调函数从服务器端获取XML文档数据并解析
function getInitData(){
if(xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
//alert("Server Success!");
result = xmlHttpRequest.responseXML;
bookNodes = result.getElementsByTagName('BOOK');
//alert("bookNodes.length=" + bookNodes.length);
if(currentPage == 0 && bookNodes.length == 0){
document.getElementById("info").innerHTML = "很抱歉,未找到相关数据!";
document.getElementById("maxPageCount").innerHTML = 0;
document.getElementById("currentPage").innerHTML = 0;
return;
}
else{
//判断并获取最大页数
//alert(parseInt(bookNodes.length/everyPageCount));
maxPageCount = bookNodes.length%everyPageCount==0?parseInt(bookNodes.length/everyPageCount):parseInt(bookNodes.length/everyPageCount+1);
document.getElementById("maxPageCount").innerHTML = maxPageCount;
sendNextPage();
}
}
}
//前一页按钮
function sendPreviousPage(){
var pageFirstItem = 0;//记住上一页的第一项的索引
if(bookIndex%3 == 0){
pageFirstItem = bookIndex - everyPageCount * 2 + 2;
}
else if(bookIndex%3 == 1){
pageFirstItem = bookIndex - everyPageCount * 2 + 1;
}
else if(bookIndex%3 == 2){
pageFirstItem = bookIndex - everyPageCount * 2;
}
if(currentPage == 0 || currentPage == 1){
alert("当前页已经是第一页!");
return;
}
// if(pageFirstItem < -1){
// alert("当前页已经是第一页!");
// return;
// }
if(pageFirstItem >= -1){
bookIndex = pageFirstItem;
currentPage--;
document.getElementById("currentPage").innerHTML = currentPage;
for(var i = 0; i < everyPageCount; i++){
var imgTag = "img" + (i+1).toString();
var desTag = "des" + (i+1).toString();
if(bookIndex < bookNodes.length - 1){
bookIndex++;
displayItem(bookIndex,imgTag,desTag,1);
}
else{
displayItem(bookIndex,imgTag,desTag,0);
}
}
}
}
//下一页按钮
function sendNextPage(){
var pageEndItem = bookIndex + everyPageCount;//下一页面最后一项的索引
if(pageEndItem <= bookNodes.length + 1){
currentPage++;
document.getElementById("currentPage").innerHTML = currentPage;
for(var i = 0; i < everyPageCount; i++){
var imgTag = "img" + (i+1).toString();
var desTag = "des" + (i+1).toString();
if(bookIndex < bookNodes.length - 1){
bookIndex++;
displayItem(bookIndex,imgTag,desTag,1);
}
else{
displayItem(bookIndex,imgTag,desTag,0);
}
}
}
// else if(currentPage + 1 == maxPageCount){
// alert("当前页是最后一页!");
// return;
// }
else if(pageEndItem > bookNodes.length){
alert("当前页是最后一页!");
return;
}
}
//显示指定索引的BOOK项目到指定的页面位置
function displayItem(bookIndex,imgTag,desTag,flag){
if(flag == 1){
var imgString = null;
var desString = null;
var bookImg = bookNodes[bookIndex].getElementsByTagName("Img")[0].childNodes[0].nodeValue;
//alert(bookImg);
var bookName = " 书名: " + bookNodes[bookIndex].getElementsByTagName("BookName")[0].childNodes[0].nodeValue;
var authors = " 作者: " + bookNodes[bookIndex].getElementsByTagName("Authors")[0].childNodes[0].nodeValue + "<br/>";
var isbn = " 出版号: " + bookNodes[bookIndex].getElementsByTagName("ISBN")[0].childNodes[0].nodeValue + "<br/>";
var price = " 出版年: " + bookNodes[bookIndex].getElementsByTagName("VerYear")[0].childNodes[0].nodeValue + "<br/>";
var quantity = " 价格: " + bookNodes[bookIndex].getElementsByTagName("Price")[0].childNodes[0].nodeValue + "<br/>";
var varYear = " 库存数量: " + bookNodes[bookIndex].getElementsByTagName("Quantity")[0].childNodes[0].nodeValue + "<br/>";
imgString = "<img src=\"" + bookImg + "\"/>";
desString = bookName + "<br/>";
desString += authors;
desString += isbn;
desString += varYear;
desString += price;
desString += quantity;
desString += "<a href=\"#\" onclick=\"addRemoveItem('add','" + bookName + "')\">" + "将这本书加入购物车(购买)</a>";
//alert("<a href=\"#\" onclick=\"addRemoveItem('add','" + bookName + "')\">" + "将这本书加入购物车(购买)</a>");
document.getElementById(imgTag).innerHTML = imgString;
document.getElementById(desTag).innerHTML = desString;
}
else{
document.getElementById(imgTag).innerHTML = "";
document.getElementById(desTag).innerHTML = "";
}
}
//利用服务器Session保存购物车内容
function addRemoveItem(action,bookName){
if(action == 'add'){
var url = "/ManageCartServlet?action=" + action + "&bookName=" +encodeURIComponent(bookName) + "&value=" + Number(new Date);
xmlHttpRequest.open("GET", url, true);
xmlHttpRequest.onreadystatechange = getData;
xmlHttpRequest.send(null);
}
else{
var url = "/ManageCartServlet?action=" + action + "&bookName=" +encodeURIComponent(bookName) + "&value=" + Number(new Date);
xmlHttpRequest.open("GET", url, true);
xmlHttpRequest.onreadystatechange = getData;
xmlHttpRequest.send(null);
}
}
//回调函数从服务器端获取结果数据并解析
function getData(){
if(xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
//alert("Server Success!");
var result = xmlHttpRequest.responseXML;
var bookNodes = result.getElementsByTagName('BOOK');
var bookNameNodes = result.getElementsByTagName('BookName');
var quantityNodes = result.getElementsByTagName('Quantity');
var spantag = document.getElementById('cart');
spantag.innerHTML = "";
for(var i = 0; i < bookNodes.length; i++){
if(window.ActiveXObject){
spantag.innerHTML += " " + bookNodes[i].firstChild.text;
spantag.innerHTML += " --> ";
spantag.innerHTML += " " + bookNodes[i].lastChild.text;
spantag.innerHTML += " ";
spantag.innerHTML += " " + "<a href=\"#\" onclick=\"addRemoveItem('remove','" + bookNodes[i].firstChild.text + "')\">" + "从购物车删除这本书</a>";
spantag.innerHTML += "<br/>";
}
else{
spantag.innerHTML += " " + bookNameNodes[i].firstChild.nodeValue;
//spantag.innerHTML += " " + bookNodes[1].firstChild.textContent;
spantag.innerHTML += " --> ";
spantag.innerHTML += " " + quantityNodes[i].firstChild.nodeValue;
//spantag.innerHTML += " " + bookNodes[1].firstChild.textContent;
spantag.innerHTML += " ";
spantag.innerHTML += " " + "<a href=\"#\" onclick=\"addRemoveItem('remove','" + bookNameNodes[i].firstChild.nodeValue + "')\">" + "从购物车删除这本书</a>";
spantag.innerHTML += "<br/>";
}
}
}
}
Cart.html-->页面显示使用的HTML文件
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>购物车示例</title>
<script type="text/javascript" src="Cart.js"></script>
</head>
<body onload="sendRequest()">
总共<span id="maxPageCount"></span>页----当前第<span id="currentPage"></span>页
<hr size="1"/>
<div id="info"></div>
<table>
<tr>
<td><div id="img1"></div></td>
<td><div id="img2"></div></td>
<td><div id="img3"></div></td>
</tr>
<tr>
<td><div id="des1"></div></td>
<td><div id="des2"></div></td>
<td><div id="des3"></div></td>
</tr>
</table>
<br/>
<input type="button" id="previousPage" value="前一页"/>
<input type="button" id="nextPage" value="下一页"/>
<hr size="1"/>
<h3>您的购物车:</h3><br/>
<span id="cart"></span>
</body>
</html>
ManageCartServlet.java-->实现购物车信息存储的Servlet文件
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Iterator;
public class ManageCartServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action")==null?"":request.getParameter("action");
//System.out.println("action:" + action);
String newItem = request.getParameter("bookName")==null?"":request.getParameter("bookName");
//System.out.println("newItem:" + newItem);
HttpSession session = request.getSession(true);
Hashtable ht = new Hashtable();
String cartXml = "";
//当前已经处于购物页面,并且已经处于购物状态.
if(session.getAttribute("cart") != null){
//System.out.println("已经处于购物状态");
ht = (Hashtable)session.getAttribute("cart");
//添加购物项目
if("add".equals(action)) {
//已经存在于购物车中的项目
if(ht.containsKey(newItem)){
Integer count = (Integer)ht.get(newItem);
count ++;
ht.put(newItem, new Integer(count));
session.setAttribute("cart", ht);
cartXml = toXml(ht);
response.setContentType("text/xml");
response.getWriter().write(cartXml);
}
//购物车中不存在的项目,现在新增加.
else{
ht.put(newItem, new Integer(1));
session.setAttribute("cart", ht);
cartXml = toXml(ht);
response.setContentType("text/xml");
response.getWriter().write(cartXml);
}
}
//删除购物项目
else if("remove".equals(action)){
//System.out.println(ht == null);
Integer count = (Integer)ht.get(newItem);
//System.out.println(count == null);
count --;
if(count == 0){
ht.remove(newItem);
}
else{
ht.put(newItem, new Integer(count));
}
session.setAttribute("cart", ht);
cartXml = toXml(ht);
response.setContentType("text/xml");
response.getWriter().write(cartXml);
}
}
//初次进入购物页面
else{
//System.out.println("初次进入购物页面");
ht.put(newItem, 1);
session.setAttribute("cart", ht);
cartXml = toXml(ht);
response.setContentType("text/xml");
response.getWriter().write(cartXml);
}
//System.out.println(cartXml);
}
//将集合的内容转换为字符串形式组成的XML数据
public String toXml(Hashtable ht)
{
StringBuffer xmlDoc = new StringBuffer();
xmlDoc.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
xmlDoc.append("<CART>\n");
for (Iterator iter = ht.keySet().iterator(); iter.hasNext();)
{
String item = (String)iter.next();
int Quantity = ((Integer)ht.get(item)).intValue();
xmlDoc.append("<BOOK>\n");
xmlDoc.append("<BookName>");
xmlDoc.append(item);
xmlDoc.append("</BookName>\n");
xmlDoc.append("<Quantity>");
xmlDoc.append(Quantity);
xmlDoc.append("</Quantity>\n");
xmlDoc.append("</BOOK>\n");
}
xmlDoc.append("</CART>\n");
return xmlDoc.toString();
}
}
备注:示例中使用的图片请在附件中下载!
部署说明:所有源代码以及相关文件在附件上传,只需要在IDE工具中根据以往的Java Web项目创建,然后拷贝文件到src和WebRoot就OK了。。。