第6章 jQuery与Ajax的应用

Ajax的全称:Asynchronous JavaScript and XML (异步Javascript和XML)

传统模式中,数据提交通过表单方式实现,数据的获取是靠全页面刷新来重新获取整页的内容。而Ajax模式只是通过XMLHttpRequest对象向服务器端提交数据,即按需发送。因为Ajax需要与Web服务器端进行交互,所以用个服务器,我这里用的是Tomcat。


 1. 传统Js的Ajax操作

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script language="javascript" type="text/javascript">
//通过这个函数来异步获取信息
function Ajax(){
var xmlHttpReq = null; //声明一个空对象用来装入XMLHttpRequest
if (window.ActiveXObject){//IE5 IE6是以ActiveXObject的方式引入XMLHttpRequest的
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest){//除IE5 IE6 以外的浏览器XMLHttpRequest是window的子对象
xmlHttpReq = new XMLHttpRequest();//实例化一个XMLHttpRequest
}
if(xmlHttpReq != null){ //如果对象实例化成功
xmlHttpReq.open("GET","test.jsp",true); //调用open()方法并采用异步方式
xmlHttpReq.onreadystatechange=RequestCallBack; //设置回调函数
xmlHttpReq.send(null); //因为使用get方式提交,所以可以使用null参调用
}
function RequestCallBack(){//一旦readyState值改变,将会调用这个函数
if(xmlHttpReq.readyState == 4){//readyState的值为4表示请求完成加载(即请求发出去了)
if(xmlHttpReq.status == 200){//HTTP状态为200表示相服务器应成功
//将xmlHttpReq.responseText的值赋给ID为 resText 的元素
document.getElementById("resText").innerHTML = xmlHttpReq.responseText;
}
}
}
}
</script>
</head>
<body>
<input type="button" id="" value="Ajax提交" onclick="Ajax();" />
<div id="resText" ></div>
</body>
</html>

2. jQuery中的Ajax 

$.ajax(); $.load(); $.get(); $.post(); $.getStript(); $.getJSON() 这几个常用的方法。

$.load()方法: 将远程的HTML载入并插入DOM中。

首先构建一个test.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div class="comment">
<h6>张三:</h6>
<p class="para">沙发.</p>
</div>
<div class="comment">
<h6>李四:</h6>
<p class="para">板凳.</p>
</div>
<div class="comment">
<h6>王五:</h6>
<p class="para">地板.</p>
</div>
</body>
</html>

然后用load()方法将它插入到另一个页面中:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
* { margin:0; padding:0;}
body { font-size:12px;}
.comment { margin-top:10px; padding:10px; border:1px solid #ccc;background:#DDD;}
.comment h6 { font-weight:700; font-size:14px;}
.para { margin-top:5px; text-indent:2em;background:#DDD;}
</style>
<!-- 引入jQuery -->
<script src="../scripts/jquery.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$(function(){
$("#send").click(function(){
$("#resText").load("test.html");
})
})
</script>
</head>
<body>
<input type="button" id="send" value="Ajax获取" /> <div class="comment">
已有评论:
</div>
<div id="resText" ></div>
</body>
</html>

自己第一遍写的时候忘记了基本的事:对于jQuery来说,为页面元素添加事件要在DOM初始完成之后再操作,即$(document).ready(......);

   

load()方法里的第三个参数是个回调函数,这个函数有3个参数,分别代表请求返回的内容,请求状态和XMLHttpRequest对象

$("#resText").load("test.html .para",function (responseText, textStatus, XMLHttpRequest){
alert( $(this).html() ); //在这里this指向的是当前的DOM对象,即 $("#iptText")[0]
alert(responseText); //请求返回的内容
alert(textStatus); //请求状态:success,error
alert(XMLHttpRequest); //XMLHttpRequest对象
}); 

$.get()方法和$.post()方法

分别使用get方式和post方式来进行异步请求。

注意上面的回调函数是只有当请求成功时才会被调用,这点和$.load()的回调函数不一样。面是一个评论页面的HTML的代码,来说明$.get()方法的使用。

<form id="form1">
<p>评论:</p>
<p>姓名: <input type="text" name="username" id="username" /></p>
<p>内容: <textarea name="content" id="content" ></textarea></p>
<p><input type="button" id="send" value="提交"/></p>
</form> <div class='comment'>已有评论:</div>
<div id="resText" >
</div>

实现点击提交按钮后将评论显示在已有评论下方:

$(function(){
$("#send").click(function(){
$.get("get1.jsp", { //使用$get()方法异步请求,第一个参数是请求页面的URL地址,第二个是发送至服务器的data,第三个是回调函数
username : encodeURI( $("#username").val() ) ,
content : encodeURI( $("#content").val() )
}, function (data, textStatus){ //第一个参数是返回的内容,第二个是请求状态
$("#resText").html( decodeURI(data) ); // 把返回的数据添加到页面上
}
);
})
})

Js的encodeURI()和decodeURI() 方法,encodeURI() 函数可把字符串作为 URI 进行编码。对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的: , / ? : @ & = + $ #

decodeURI() 函数可对 encodeURI() 函数编码过的 URI 进行解码。


数据格式:HTML片段、XML文档(jQuery的DOM处理也可用于XML文档)、JSON

jQuery解析XML文档:

$(function(){
$("#send").click(function(){
$.get("get2.jsp", {
username : encodeURI( $("#username").val() ) ,
content : encodeURI( $("#content").val() )
}, function (data, textStatus){
var username = $(data).find("comment").attr("username");
var content = $(data).find("comment content").text();
username = decodeURI(username);
content = decodeURI(content);
var txtHtml = "<div class='comment'><h6>"+username+":</h6><p class='para'>"+content+"</p></div>";
$("#resText").html(txtHtml); // 把返回的数据添加到页面上
});
})
})

jQuery解析JSon:

$(function(){
$("#send").click(function(){
$.get("get3.jsp", {
username : encodeURI( $("#username").val() ) ,
content : encodeURI( $("#content").val() )
}, function (data, textStatus){
var username = data.username;
var content = data.content;
username = decodeURI(username);
content = decodeURI(content);
var txtHtml = "<div class='comment'><h6>"+username+":</h6><p class='para'>"+content+"</p></div>";
$("#resText").html(txtHtml); // 把返回的数据添加到页面上
},"json");
})
})

$.getScript()和$.getJson()方法

$.getScript()用来加载js文件,它也有回调函数,在js文件加载成功后运行。

$.getJson()方法用于加载json文件,用法和$.getScript()相同。

可以通过JSONP形式的回调函数来加载其它网站的JSON数据,关于JSON和JSONP。例如从图片网站Flickr搜索4张汽车图片:

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
* { margin:0; padding:0;}
body { font-size:12px;}
.para {
width:100px;
height:100px;
margin:5px;
border:0;
}
</style>
<!-- 引入jQuery -->
<script src="../scripts/jquery.js" type="text/javascript"></script>
<script>
$(function(){
$('#send').click(function() {
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=car&tagmode=any&format=json&jsoncallback=?",
function(data){
$.each(data.items, function( i,item ){
$("<img class='para'/> ").attr("src", item.media.m ).appendTo("#resText");
if ( i == 3 ) {
return false;
}
});
}
);
})
})
</script>
</head>
<body> <p>
<input type="button" id="send" value="加载"/>
</p> <div id="resText" > </div> </body>
</html>

关于遍历用的$.each()函数:以一个数组或者对象作为第一个参数,以一个回调函数作为第二个参数。回调函数有两个参数,第一个是对象的成员或者数组的索引,第二个是对应变量或内容。


$.ajax()方法:jQuery最底层ajax的实现。

<!-- $.ajax()方法代替$.getScript()方法 -->
<script>
$(function(){
$('#send').click(function() {
$.ajax({
type: "GET",
url: "test.js",
dataType: "script"
});
});
})
</script>
<!-- $.ajax()方法代替$.getJson()方法 -->
<script>
$(function(){
$('#send').click(function() {
$.ajax({
type: "GET",
url: "test.json",
dataType: "json",
success : function(data){
$('#resText').empty();
var html = '';
$.each( data , function(commentIndex, comment) {
html += '<div class="comment"><h6>' + comment['username'] + ':</h6><p class="para">' + comment['content'] + '</p></div>';
})
$('#resText').html(html);
}
});
});
})
</script>

2. 序列化元素

其余需要注意的方法是:serializaArray()方法,作用于DOM对象而不是全局函数,将DOM元素序列化后,返回JSON数据的格式。eg:

$(function(){
var fields = $(":checkbox,:radio").serializeArray();
console.log(fields);// Firebug输出
$.each( fields, function(i, field){
$("#results").append(field.value + " , ");
});
})

$.param()方法,用来对一个数组或对象按照key/value进行序列化。


3. jQuery中的ajax全局事件

使某个Ajax请求不受全局方法影响。


4. 实战案例——基于jQuery的Ajax聊天室程序

Mysql建表,这里navicat建表的话字段名和表名不要加什么双引号之类的,否则报错。

CREATE TABLE messages (
id INT (7) NOT NULL auto_increment,
USER VARCHAR (255) NOT NULL,
msg text NOT NULL,
time INT (9) NOT NULL,
PRIMARY KEY (id)
);

HTML:

<body>

    <div id="wrapper">
<p id="messagewindow"><span id="loading">加载中...</span></p>
<form id="chatform" action="#">
姓名: <input type="text" id="author" size="50"/><br />
内容: <input type="text" id="msg" size="50"/> <br />
<input type="submit" value="发送" /><br />
</form>
</div> </body>

书上给的例子只有PHP的....,你妹的我只懂JSP啊!!!结果只好自己用JSP来实现了。

对于服务端:

对于客户端:

使用Myeclipse新建web工程,src目录下建servlet存放servlet类和数据操作的类。顺便说一句:引入jar包时,直接将jar包黏贴到web工程的lib目录下即可,不需要再build path了

数据库操作,这里可以参照的是jdbc连接数据库的写法,以后直接拷贝:

 package servlets;

 import java.sql.Connection;
import java.sql.DriverManager; public class DatabaseConnection {
private static final String DBDRIVER = "org.gjt.mm.mysql.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/test";
private static final String USER = "root";
private static final String PASSWORD = "root";
private Connection conn = null; public DatabaseConnection(){
try{
Class.forName(DBDRIVER);
this.conn=DriverManager.getConnection(URL,USER,PASSWORD);
}catch (Exception e) {
e.printStackTrace();
}
} public Connection getConnection(){
return conn;
} public void close() throws Exception{
if(conn!=null){
try{
conn.close();
}catch (Exception e) {
throw e;
}
}
}
}

编写后端的servlet,用于处理前端页面发来的请求并将对应的请求结果发回给前端页面:

 package servlets;

 import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class AjaxServlet extends HttpServlet {
DatabaseConnection db = new DatabaseConnection();
Connection connection = db.getConnection();
PreparedStatement pstmt = null; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/xml;charset=utf-8");
resp.setHeader("Cache-Control", "no-cache");
PrintWriter out = resp.getWriter(); //这里要注意
int status_code = 2;
String name = req.getParameter("name");
String message = req.getParameter("message");
String current=req.getParameter("time");
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("MMddHHmmss");
String dateNowStr = sdf.format(d);
int time=Integer.parseInt(dateNowStr);
if (req.getParameter("action") != null
&& req.getParameter("action").equals("postmsg")) {
String sql = "insert into messages (user, msg, time) values(?,?,?)";
try {
pstmt = connection.prepareStatement(sql);
pstmt.setString(1, name);
pstmt.setString(2, message);
pstmt.setLong(3, time);
pstmt.execute();
} catch (SQLException e) {
e.printStackTrace();
}
}
String sql = "select user,msg from messages where time>? order by id asc";
try {
pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Integer.parseInt(current));
ResultSet resultSet = pstmt.executeQuery();
if (resultSet.next()) {
status_code = 1;
} else {
status_code = 2;
}
System.out.println(status_code);
out.println("<?xml version='1.0' encoding='utf-8'?>");
out.println("<response>");
out.println("\t<status>" + status_code + "</status>");
out.println("\t<time>" + time + "</time>");
if (status_code == 1) {
do {
out.println("\t<message>");
out.println("\t\t<author>" + resultSet.getString("user")
+ "</author>");
out.println("\t\t<text>" + resultSet.getString("msg")
+ "</text>");
out.println("\t</message>");
} while (resultSet.next());
}
out.println("</response>");
} catch (Exception e) {
e.printStackTrace();
}
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
} }

自己写代码就会写得乱七八糟的.....,嘛、现在是完成主义就对了(并没有完成保持数据库中只有10条数据这个功能,懒)。上面代码的注意点有:

1. 如何向前台页面返回XML文档?首先是

resp.setContentType("text/xml;charset=utf-8");

resp.setHeader("Cache-Control", "no-cache");

设置了返回内容的类型,编码,头部。然后是 PrintWriter out = resp.getWriter(), 接着套xml的格式拼装打印输出到前端页面即可。

2. 第二个要注意的比较基本,数据库基本API的使用:Connection  PreparedStatement  ResultSet之类的,jdbc的基本操作。

3. 注意使用$.post(url,data,callback,type)时,JSP后端是怎么拿到data里的值的:req.getParameter("name")

接下来在web.xml配置我们写的servlet:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>ajax</servlet-name>
<servlet-class>servlets.AjaxServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ajax</servlet-name>
<url-pattern>/back</url-pattern>
</servlet-mapping> </web-app>

编写脚本,下面是完整的前端页面:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
body {
margin: 0;
padding: 0;
font-size: 12px;
} #messagewindow {
height: 250px;
border: 1px solid;
padding: 5px;
overflow: auto;
} #wrapper {
margin: auto;
width: 438px;
}
</style>
<!-- 引入jQuery -->
<script src="scripts/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
//定义时间戳
timestamp = 0;
//调用更新信息函数
updateMsg();
//表单提交
$("#chatform").submit(function(){
$.post("back",{
message: $("#msg").val(),
name: $("#author").val(),
action: "postmsg",
time: timestamp
}, function(xml) {
//清空信息文本框内容
$("#msg").val("");
//调用解析xml的函数
addMessages(xml);
});
return false; //阻止表单提交
});
});
//更新信息函数,每隔一定时间去服务端读取数据
function updateMsg(){
$.post("back",{ time: timestamp }, function(xml) {
//移除掉 等待提示
$("#loading").remove();
//调用解析xml的函数
addMessages(xml);
});
//每隔4秒,读取一次.
setTimeout('updateMsg()', 4000);
}
//解析xml文档函数,把数据显示到页面上
function addMessages(xml) {
//如果状态为2,则终止
if($("status",xml).text() == "2") return;
//更新时间戳
timestamp = $("time",xml).text();
//$.each循环数据
$("message",xml).each(function() {
var author = $("author",this).text(); //发布者
var content = $("text",this).text(); //内容
var htmlcode = "<strong>"+author+"</strong>: "+content+"<br />";
$("#messagewindow").prepend( htmlcode ); //添加到文档中
});
}
</script>
</head>
<body>
<div id="wrapper">
<p id="messagewindow">
<span id="loading">加载中...</span>
</p>
<form id="chatform" action="#">
姓名: <input type="text" id="author" size="50" /><br /> 内容: <input
type="text" id="msg" size="50" /> <br /> <input type="submit"
value="发送" /><br />
</form>
</div>
</body>
</html>

上面的代码中要注意的是jQuery对xml文档的DOM操作:$("status",xml)方法用来通知jQuery去XML文档中寻找 "status"标签,找到后再利用text()方法取其标签里的文本即可。运行效果如下:

《锋利的JQuery》读书要点笔记5——jQuery与Ajax的应用的更多相关文章

  1. 《锋利的JQuery》读书要点笔记1——认识JQuery&&选择器

    <锋利的jQuery>源码下载,包括了这本书中全部代码以及用到的CSS文件 第一章 认识jQuery jQuery是个Js库.首先该明确的一点是:在jQuery库中$就是jQuery的一个 ...

  2. 《锋利的jQuery》读书要点笔记7——制作商城网页:网站脚本

    第8章 用jQuery打造个性网站 上一节将网页的样式设计完了,现在开始用jQuery来编写网站的脚本.首先要确定的是应该完成哪些功能. 首页应该完成的功能是: 详情页: 这个页面要完成的效果是: 接 ...

  3. 《锋利的jQuery》读书要点笔记6——制作商城网页:结构和样式设计

    第8章 用jQuery打造个性网站 做一个购物网站并用jQuery来完善.大体步骤是: 收集素材 确定网站结构 A. 文件结构,imagea文件夹用来存放将要用到的图片,styles文件夹存放CSS, ...

  4. 《锋利的JQuery》读书要点笔记4——表格表单的操作

    第五章 jQuery对表单,表格的操作以及更多应用 这章主要以一些具体案例讲解了jQuery对表单,表格的常用操作,以及一些常见的jQuery应用,用到的都是上几章说的东西.下面就以具体的案例来展开. ...

  5. 《锋利的JQuery》读书要点笔记3——事件和动画

    第四章 jQuery中的事件和动画 JS和HTML的交互是通过用户和浏览器操作页面时引发的事件来处理的,事件由浏览器自动生成. 4.1 jQuery中的事件 1. 加载DOM 这里主要是搞明白wind ...

  6. 《锋利的JQuery》读书要点笔记2——DOM操作

    第三章 jQuery中的DOM操作 3.1 DOM(Document Object Model)操作的分类 1. DOM Core    例如:document.getElementsByTagNam ...

  7. jQuery源代码学习笔记:jQuery.fn.init(selector,context,rootjQuery)代码具体解释

    3.1 源代码 init: function( selector, context, rootjQuery ) { var match, elem, ret, doc; // Handle $(&qu ...

  8. 锋利的jQuery读书笔记---jQuery中Ajax--get、post等方法

    load()方法通常用来从Web服务器上获取静态的数据文件,然而这并不能体现ajax的全部价值. 在项目中,如果需要传递一些参数给服务器中的页面,那么可以使用$.get()或者$.post()方法(或 ...

  9. 锋利的jQuery读书笔记---jQuery中Ajax--load方法

    第一个Ajax例子 <!DOCTYPE html> <html> <head lang="en"> <meta charset=" ...

随机推荐

  1. Spring MVC前台POST/GET方式传参数的方法

    假设前台通过submit传值,代码如下: <form action="testPost.do" method="post"> 页码:<inpu ...

  2. Java 中的异常和处理详解(转载)

    原文出处: 代码钢琴家 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函 ...

  3. sping事务的理解

    阅读数:2020 一.事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤 ...

  4. Chromium学习笔记

    1. How to build chromium Follow the steps on:http://www.chromium.org/Home 需要安装Win7 x64的OS,PC的配置尽可能高端 ...

  5. [剑指Offer] 37.数字在排序数组中出现的次数

    题目描述 统计一个数字在排序数组中出现的次数. [思路]因为是排序数组,所以可以用二分法搜索到要查找的值在数组中的一个位置,接着向两侧扫描,遇到不等的就停止. class Solution { pub ...

  6. sql 先查出已知的数据或者需要的数据再筛选

    sql 先查出已知的数据或者需要的数据再筛选

  7. mac 倍速播放

    Mac的倍速播放,使用工具播放是quick time player,使用方式是,按住 “option” + “>>” 即可调整倍数:

  8. hdu4418 Time travel 【期望dp + 高斯消元】

    题目链接 BZOJ4418 题解 题意:从一个序列上某一点开始沿一个方向走,走到头返回,每次走的步长各有概率,问走到一点的期望步数,或者无解 我们先将序列倍长形成循环序列,\(n = (N - 1) ...

  9. 遇到问题---java---myeclipse中maven项目引用另一个导致的resource文件混乱的问题

    遇到情况 情况是这样的,我们在构建项目时,经常会把一些公用的类和配置提取出去,作为一个公共项目.然后把公共项目作为一个jar包构件引入我们当前的项目中. 引入方式是 <dependency> ...

  10. 上海GDG活动有感

    本周参加了场上海的GDG活动.本次活动的主办方 先介绍一下: GDG Shanghai 上海GDG(Google开发者社区,以前是GTUG, Google技术用户组) ,众所周知,Google的搜索引 ...