Ajax&jQuery
Ajax&jQuery
1.Ajax
Asynchronous JavaScript and XML(非同步的 JavaScript 和 XML),不是新的程式語言,而是一種使用現有標準的新方法。
AJAX 最大的優點是在不重新載入整個頁面的情況下,可以與伺服器交換資料並更新網頁上的區域性內容。
AJAX 不需要任何瀏覽器外掛,但需要使用者允許JavaScript在瀏覽器上執行。
1.1XMLHttpRequest物件
XMLHttpRequest物件用於和伺服器交換資料。
- 建立XMLHttpRequest物件
var xmlhttp; if (window.XMLHttpRequest){ // IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行程式碼 xmlhttp=new XMLHttpRequest(); }else{ // IE6, IE5 瀏覽器執行程式碼 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }
XMLHttpRequest的常用方法:
-
open(method,url,async)
XMLHttpRequest.open(method,url,async):規定請求的型別、URL 以及是否非同步處理請求。
method:"GET":get請求;"POST":post請求
url:"/Demo2/AjaxDemoServlet?id=1",請求地址路徑
async:true:非同步請求;false:同步請求 -
send(string)
XMLHttpRequest.send(String):將請求傳送到伺服器。
String僅針對post請求,get請求不能攜帶String。
-
setRequestHeader(header,value)
xmlHttpRequest.setRequestHeader(header,value):向請求新增HTTP頭。
如果需要像 HTML 表單那樣 POST 資料,請使用 setRequestHeader() 來新增 HTTP 頭。然後在 send() 方法中規定您希望傳送的資料:
xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlHttpRequest.send("id=1&name=wang");
1.2伺服器響應
使用 XMLHttpRequest 物件的 responseText 或 responseXML 屬性來獲取伺服器的響應。
- responseText:獲得字串形式的響應資料。
- responseXML:獲得 XML 形式的響應資料。
1.3onreadystatechange事件
用於執行一些基於響應的任務,當readyState改變時,就會觸發onreadystatechange事件。
下面是 XMLHttpRequest 物件的三個重要的屬性:
當 readyState 等於 4 且狀態為 200 時,表示響應已就緒。
1.4Ajax執行Get請求
- 不獲取響應資料
<script>
function getDemo() {
//1.建立XMLHttpRequest物件
var xmlHttpRequest=new XMLHttpRequest();
//2.向伺服器傳送Get請求
xmlHttpRequest.open("GET","/Demo2/AjaxDemoServlet?id=1",true);
//將請求傳送到伺服器
xmlHttpRequest.send();
}
</script>
- 獲取響應資料
<script>
function getDemo() {
var xmlHttpRequest=new XMLHttpRequest();
//3.註冊監聽,以便獲取響應資料
xmlHttpRequest.onreadystatechange=function () { if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
alert(xmlHttpRequest.responseText);
}
}
xmlHttpRequest.open("GET","/Demo2/AjaxDemoServlet?id=1",true);
xmlHttpRequest.send();
}
響應資料:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("收到一個get請求,id為"+request.getParameter("id"));
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("收到了get請求");
}
1.5Ajax執行Post請求
- 不獲取響應資料
function postDemo() {
//1.建立XMLHttpRequest物件
var xmlHttpRequest=new XMLHttpRequest();
//2.向伺服器傳送Post請求
xmlHttpRequest.open("POST","/Demo2/AjaxDemoServlet",true);
//向請求新增新增http頭,表示像html表單那樣post資料
xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//將請求傳送到伺服器
xmlHttpRequest.send("id=1&name=wang");
}
- 獲取響應資料
function postDemo() {
var xmlHttpRequest=new XMLHttpRequest();
//獲取響應資料
xmlHttpRequest.onreadystatechange=function(){
if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
alert(xmlHttpRequest.responseText);
}
}
xmlHttpRequest.open("POST","/Demo2/AjaxDemoServlet",true);
xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHttpRequest.send("id=1&name=wang");
}
響應資料:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("收到一個post請求,id為"+request.getParameter("id")+",name為"+request.getParameter("name"));
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("收到了post請求");
}
1.6案例:Ajax校驗使用者名稱是否可用
- register_Ajax.jsp
<head>
<title>使用者註冊頁面</title>
<script>
function checkUsername() {
var xmlHttpRequest=new XMLHttpRequest();
var username=document.getElementById("name").value;
xmlHttpRequest.onreadystatechange=function () {
if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
var data=xmlHttpRequest.responseText;
if(data==0){
document.getElementById("span1").innerHTML="<font color='red'>使用者名稱已被佔用</font>"
}else if(data==1){
document.getElementById("span1").innerHTML="<font color='green'>使用者名稱可用</font>"
}
}
}
xmlHttpRequest.open("GET","/Demo2/CheckUsernameServlet?username="+username,true);
xmlHttpRequest.send();
}
</script>
</head>
<body>
<form action="RegisterServlet" method="post">
請輸入使用者名稱:<input type="text" name="username" id="name" onblur="checkUsername()"/><span id="span1"></span><br/>
請輸入密碼:<input type="text" name="password"/><br/>
<input type="submit" value="註冊"/>
</form>
</body>
注意:獲取id為name的元素的值要用document.getElementById("name").value,而不是document.getElementById("name")。
用document.getElementById("name")獲取的是元素,而不是值,如下圖:
- CheckUsernameServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
response.setContentType("text/html;charset=utf-8");
if(username.equals("COCO")){
// response.getWriter().write(0);
response.getWriter().print(0);
}else {
//response.getWriter().write(1);
response.getWriter().print(1);
}
}
注意:這裡返回int只能用print或println,write只能寫字元型,即char,而且數字傳到前端會產生亂碼,如下:
- write和print方法比較:
write():僅支援輸出字元型別資料,字元、字元陣列、字串等;
print():可以將各種型別(包括Object)的資料通過預設編碼轉換成bytes位元組形式,這些位元組都通過write(int c)方法被輸出。
2.jQuery
jQuery是一個JavaScript庫,可以極大簡化Javascript程式設計。
2.1安裝jQuery
- 下載後安裝jQuery
將jquery-1.11.3.min.js拷貝到工程目錄中,如web/js/jquery-1.11.3.min.js,然後在頁面上引用:
<script src="js/jquery-1.11.3.min.js"></script>
是否疑惑為什麼沒有在 <script> 標籤中使用 type="text/javascript"?因為在HTML5中,不必那樣做了。JavaScript 是HTML5以及所有現代瀏覽器中的預設指令碼語言。
- CDN引用
如果不希望下載並存放 jQuery,那麼也可以通過 CDN(內容分發網路) 引用它。Staticfile CDN、百度、又拍雲、新浪、谷歌和微軟的伺服器都存有 jQuery 。
百度CDN:
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
又拍雲CDN:
<script src="https://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js">
2.2jQuery選擇器
-
元素選擇器
基於元素名選取元素。
$("button"):在頁面獲取所有的
<button>
元素。 -
id選擇器
通過元素的id屬性選取指定的元素。
$("#id2"):獲取id為id2的元素。
-
類選擇器
通過指定的class屬性查詢元素。
$(".test"):查詢帶有class="test"屬性的元素。
2.3jQuery設定內容
-
text()
設定或返回所選元素的文字內容,兩個標籤中寫值,如
<textarea id="id3"></textarea>
-
html()
設定或返回元素的內容(包括html標記)。
-
val()
設定或返回表單欄位的值,用於元素裡面有value屬性的。
2.4jQuery常用方法
2.4.1load()方法
load()方法從伺服器載入資料,並把返回的資料放入被選元素中。
語法:
$(selector).load(URL,data,callback);
/*
必需的 URL 引數規定您希望載入的 URL。
可選的 data 引數規定與請求一同傳送的查詢字串鍵/值對集合。
可選的 callback 引數是 load() 方法完成後所執行的函式名稱。
*/
2.4.1.1load()方法演示
- jQueryServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("收到一個請求");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("執行load方法");
}
- jQueryDemo.jsp
<head>
<title>Title</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
function loadDemo() {
$("#id2").load("/Demo2/jQueryServlet",function (responseTxt,statusTxt,xhr){
$("#id2").val(responseTxt);//將響應回的資料放入到id為id2的元素中
});
}
</script>
</head>
<body>
<a href="" onclick="loadDemo()" id="id1">使用jQuery執行load方法</a><br/>
<input type="button" value="使用jQuery執行load方法" onclick="loadDemo()"/>
<input type="text" id="id2"/>
</body>
注意:
如果用超連結:
<a href="" onclick="loadDemo()" id="id1">使用jQuery執行load方法</a><br/>
響應回的資料會在id2中一閃而過,原因是有兩次重新整理,先走 onClick的方法,取到資料回來之後,賦值顯示。接著走 href=""的路徑,但是這個屬性沒有給值,所以會把當前的頁面重新再重新整理一次,導致看不見值。
2.4.2get()方法
$.get() 方法通過 HTTP GET 請求從伺服器上請求資料。
語法:
$.get(url,callback);
必需的url引數規定希望請求的URL。
可選的callback引數是請求成功後所執行的函式名。
2.4.2.1get()方法演示
<script>
$(document).ready(function () {
$("button").click(function () {//即點選button後執行get請求
$.get("/Demo2/jQueryServlet",function (data,status) {
$("#id2").val(data);//將返回的資料填入id2
$("#id3").text(data);
});
});
})
</script>
<body>
<button>演示get</button><br/>
<input type="text" id="id2"/>
<textarea id="id3"></textarea>
</body>
2.4.3post()方法
$.post() 方法通過 HTTP POST 請求從伺服器上請求資料。
語法:
$.post(url,data,callback);
必需的url引數規定您希望請求的url。
可選的data引數規定連同請求傳送的資料。
可選的callback引數是請求成功後所執行的函式名。
2.4.3.1post()方法演示
<script>
$(document).ready(function () {
$("button").click(function () {
$.post("/Demo2/jQueryServlet",{name:"wanger",age:19},
function (data,status) {
$("#id2").val(data+"\\"+status);
});
});
})
</script>
<body>
<button>演示post</button><br/>
<input type="text" id="id2"/>
</body>
2.5案例1:jQuery校驗使用者名稱是否可用
- register_jQuery.jsp
<script>
function checkUsername() {
//var username=document.getElementById("name").value;
var username=$("#name").val();//以jQuery方式獲取使用者名稱
$.post("/Demo2/jQueryServlet",{name:username},function (data,status) {
if(data==0){
$("#span1").html("<font color='red'>使用者名稱已被佔用</font>");
}else{
$("#span1").html("<font color='green'>使用者名稱可用</font>");
}
})
}
</script>
<body>
<form action="RegisterServlet" method="post">
請輸入使用者名稱:<input type="text" name="username" id="name" onblur="checkUsername()"/><span id="span1"></span><br/>
請輸入密碼:<input type="text" name="password"/><br/>
<input type="submit" value="註冊"/>
</form>
</body>
2.6案例2:jQuery實現仿百度提示
效果如下:
- HeimaSearch.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>黑馬搜尋</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
/*文件就緒程式碼:$(document).ready(function () {})可簡寫為$(function(){})*/
$(function () {
$("#search").keyup(function () {
//var search=$("#search").val();
var search=$(this).val();//this即為執行此方法的物件:$("#search");
if(search!=""){//當輸入框不為空時才傳送請求
$.post("/StuSysMvc/HeimaSearchServlet",{searchValue:search},function(data,status){
if(data!=""){
$("#div01").show();//當返回值不為空時才展示搜尋提示框
$("#div01").html(data);
}else{
$("#div01").hide();//非第一次時返回值為空時隱藏搜尋提示框
}
})
}else{
$("#div01").hide();//刪除搜尋內容後要隱藏搜尋提示框
}
})
})
</script>
</head>
<body>
<center >
<br/><br/><br/><br/><br/><br/>
<h2>Heima黑馬</h2>
<input type="text" name="search" id="search" onkeyup="initSearch()" style="width: 600px ; height: 55px ;font-size: 20px;"/>
<input type="button" value="黑馬一下" style="height: 55px ; width: 100px ; ">
<div id="div01" style="position:relative; left : -52px; width: 600px; border: 1px solid blue; display: none;"></div>
<%--
display:none搜尋框預設不顯示;
div01這個div不指定高度,而是根據返回的list.jsp中的資料動態調整。
--%>
</center>
</body>
</html>
- HeimaSearchServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String searchValue = request.getParameter("searchValue");
System.out.println("收到請求:"+searchValue);
StudentService studentService=new StudentServiceImpl();
List<Student> list=studentService.initSearch(searchValue);//dao層可設定預設最多隻查詢10條
request.setAttribute("list",list);
request.getRequestDispatcher("list.jsp").forward(request,response);
//響應list.jsp頁面給請求者。請求:瀏覽器請求,瀏覽器看到這個jsp頁面
}
-
list.jsp
在list.jsp頁面遍歷list,HeimaSearchServlet將list.jsp返回給請求者。
<table width="100%"><%--設定此table和div同寬,使結果左對齊--%>
<c:forEach var="stu" items="${list}">
<tr>
<td>${stu.sname}</td>
</tr>
</c:forEach>
</table>
2.7案例3:jQuery實現省市聯動
2.7.1資料庫準備
準備兩張表:province和city,給city表的c_pid欄位新增外來鍵約束指向province表的唯一索引:主鍵pid。
2.7.2使用xml傳輸資料
-
依賴jar包
-
proCity_xml.jsp
<script>
$(function () {
$("#province").change(function () {
var choice=$(this).val();
if(choice!=""){
$.post("/StuSysMvc/ProCityServlet",{province:choice},function (data,status) {
$("#city").html("<option value=''>--請選擇--</option>");//清空city中的option
//從data資料裡找出所有的city,然後遍歷所有的city,每遍歷一個city就執行一次function方法
/*<list>
<city>
<cid>1<id>
<cname>鄭州</cname>
<cPid>1</cPid>
</city>
......
</list>*/
$(data).find("city").each(function () {
var cid=$(this).children("cid").text();
var cname=$(this).children("cname").text();
$("#city").append("<option value='"+cid+"'>"+cname+"</option>");
})
})
}
});
});
</script>
</head>
<body>
省份:<select name="province" id="province">
<option value="">--請選擇--</option>
<option value="1">河南</option>
<option value="2">廣東</option>
</select>
城市:<select name="city" id="city">
<option value="">--請選擇--</option>
</select>
</body>
- ProCityServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer pid = Integer.parseInt(request.getParameter("province"));
StudentService studentService=new StudentServiceImpl();
List<City> list = studentService.findCityByPid(pid);
//返回資料
//可以像仿百度提示那樣返回html,但最好採用返回xml或json
//1.返回xml
XStream xStream=new XStream();
//xStream.useAttributeFor(City.class,"cid");//將cid設定為city的屬性,寫在設定別名前後均可
xStream.alias("city",City.class);
//xStream.useAttributeFor(City.class,"cid");
String s = xStream.toXML(list);
response.setContentType("text/xml;charset=utf-8");//注意這裡是xml
response.getWriter().write(s);
}
xml資料如下:
修改別名:將com.itheima.entity.City改為city,並將cid設定為city的屬性:
2.7.3使用json傳輸資料
-
依賴jar包:
-
proCity_json.jsp
<script>
$(function () {
$("#province").change(function () {
var choice=$(this).val();
if(choice!=""){
$.post("/StuSysMvc/ProCityServlet",{province:choice},function (data,status) {
$("#city").html("<option value=''>--請選擇--</option>");
/*data:
[
{
"cPid":2,
"cid":5,
"cname":"廣州"
},
...
]
*/
//先遍歷,再追加
$(data).each(function (index,c) {//index:索引;c:遍歷到的元素
$("#city").append("<option value='"+c.cid+"'>"+c.cname+"</option>")
})
},"json")//最後一個引數為dataType,指定資料型別為json,預設智慧判斷(xml,json,script,html),但json資料不能識別出來,需要宣告一下
}
});
});
</script>
- ProCityServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer pid = Integer.parseInt(request.getParameter("province"));
StudentService studentService=new StudentServiceImpl();
List<City> list = studentService.findCityByPid(pid);
//返回資料
//2.返回Json
JSONArray jsonArray = JSONArray.fromObject(list);
/*
JSONArray:轉化為json陣列:[{"cPid":2,"cid":5,"cname":"廣州"},{"cPid":2,"cid":6,"cname":"東莞"},{"cPid":2,"cid":7,"cname":"深圳"},{"cPid":2,"cid":8,"cname":"江門"}]
JSONObject:轉化為接送資料:{"cPid":2,"cid":5,"cname":"廣州"}
*/
String s = jsonArray.toString();
System.out.println(s);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(s);*/
}