jQuery
文章目錄
一、jQuery概述
1.1 jQuery簡介
jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框 架)。jQuery設計的宗旨是“Write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝JavaScript常用 的功能代碼,提供一種簡便的JavaScript設計模式,優化HTML文檔操作、事件處理、動畫設計和Ajax交互。
jQuery的核心特性可以總結爲:具有獨特的鏈式語法和短小清晰的多功能接口;具有高效靈活的css選擇器,並且可 對CSS選擇器進行擴展;擁有便捷的插件擴展機制和豐富的插件。jQuery兼容各種主流瀏覽器,如IE 6.0+、FF 1.5+、Safari 2.0+、Opera 9.0+等。
目前jQuery有三個大版本:
1.x:兼容ie678,使用最爲廣泛的,官方只做BUG維護,功能不再新增。因此一般項目來說,使用1.x版本就可以了,最終 版本:1.12.4 (2016年5月20日)
2.x:2013年2.0版本發佈,不兼容ie678,很少有人使用,官方只做BUG維護,功能不再新增。如果不考慮兼容低版本的瀏 覽器可以使用2.x,最終版本:2.2.4 (2016年5月20日)
3.x:不兼容ie678,只支持最新的瀏覽器。除非特殊要求,一般不會使用3.x版本的,很多老的jQuery插件不支持這個版 本。目前該版本是官方主要更新維護的版本。最新版本:3.2.1(2017年3月20日)
1.X大版本下,細分版本非常多,各個版本的函數都會有一定的差異。網上看到的很多教程大多是1.x版本的。jquery官方 手冊:http://api.jquery.com/
參考文檔:https://www.jquery123.com/ jQuery中文網、菜鳥教程
1.2 jQuery功能
jQuery是一個JavaScript函數庫。 jQuery是一個輕量級的"寫的少,做的多"的JavaScript庫。jQuery庫包含以下功能:
- HTML 元素選取
- HTML 元素操作
- CSS 操作
- HTML 事件操作
- JavaScript 特效和動畫
- HTML DOM 遍歷和修改
- AJAX
- Utilities
1.3 爲什麼要用jQuery
目前網絡上有大量開源的 JS 框架, 但是 jQuery 是目前最流行的 JS 框架,而且提供了大量的擴展。 很多大公司都在使 用 jQuery, 例如:
Microsoft
IBM
Netflflix
1.4 jQuery的兩種結構
jQuery一般分爲兩種結構,通常分爲調試版本和壓縮版本。
- 調試版本體積比較大,代碼命名規範,註釋全面,通常在開發階段使用,可以用來調試代碼。命名就是jquery-版本號.js。例如:jquery-1.11.1.js
- 壓縮版本體積比較小,大概是調試版本的三分之一,基本無法直接查看和讀取,變量全部使用a、b、c等簡單命名。通常是在代碼的生產階段使用,減少用戶下載的內容,提升用戶訪問的速度,命名一般是jquery-版本號.min.js。例如:jquery-1.11.1.min.js
二、jQuery的引用
jQuery是一個js的庫,在代碼中一般有兩種引用方式:
從 jquery.com 等網站下載,並使用HTML 的
三、jQuery的基本語法
3.1 基礎語法
通過 jQuery,您可以選取(查詢,query) HTML 元素,並對它們執行各種操作。
基礎語法: $(selector).action()
- 美元符號定義 jQuery
- 選擇符(selector)查找HTML 元素
- jQuery 的 action() 執行對元素的操作
實例:
$(this).hide() - 隱藏當前元素
$(“p”).hide() - 隱藏所有
元素
$(“p.test”).hide() - 隱藏所有 class=“test” 的
元素
$("#test").hide() - 隱藏所有 id=“test” 的元素
- 文檔準備就緒事件:
$(document).ready(function(){ // jQuery 代碼... }); // 上面代碼可以簡化爲: $(function(){ // jQuery 代碼... });
這是爲了防止文檔在完全加載(就緒)之前運行 jQuery 代碼,即在 DOM 加載完成後纔可以對 DOM 進行操作。如果在文檔沒有完全加載之前就運行函數,操作可能失敗。
- 衝突解決
如果在頁面上使用了多個js的庫,導致$的使用衝突,可以通過如下辦法解決:
$.noConflict(); jQuery(document).ready(function($){ $("button").click(function(){ $("p").text("jQuery 仍然在工作!"); }); });
3.2 選擇器
jQuery 選擇器允許對 HTML 元素組或單個元素進行操作。jQuery 中所有選擇器都以美元符號開頭:$()。
3.2.1 元素選擇器
jQuery 元素選擇器基於元素名選取元素。
語法爲:$(“標籤名稱”)
例如:選取頁面上所有的
標籤$(“div”)
3.2.2 id選擇器
jQuery #id 選擇器通過 HTML 元素的 id 屬性選取指定的元素。
頁面中元素的 id 應該是唯一的,所以您要在頁面中選取唯一的元素需要通過 #id 選擇器。
語法爲:$("#id名稱")
例如:頁面html元素爲:
jQuery選取代碼:$("#leftDiv")
3.2.3 class選擇器
jQuery 類選擇器可以通過指定的 class 查找元素。
語法如下:$(".class屬性名稱")
例如:頁面元素爲:
jQuery選取代碼爲:$(".leftPanel")
3.3.4 其他一些常見選擇器
層級選擇器:
語法 | 描述 |
---|---|
ancestor descendant | 在給定的祖先元素下匹配所有的後代元素 |
parent > child | 在給定的父元素下匹配所有的子元素 |
prev + next | 匹配所有緊接在 prev 元素後的 next 元素 |
prev ~ siblings | 匹配 prev 元素之後的所有 siblings 元素 |
內容選擇器:
語法 | 描述 |
---|---|
:first | 獲取第一個元素 |
:not(selector) | 去除所有與給定選擇器匹配的元素 |
:even | 匹配所有索引值爲偶數的元素,從 0 開始計數 |
:odd | 匹配所有索引值爲奇數的元素,從 0 開始計數 |
:eq(index) | 匹配一個給定索引值的元素 |
:gt(index) | 匹配所有大於給定索引值的元素 |
:lt(index) | 匹配所有小於給定索引值的元素 |
:last() | 獲取最後個元素 |
:contains(text) | 匹配包含給定文本的元素 |
:has(selector) | 匹配含有選擇器所匹配的元素的元素 |
:empty | 匹配所有不包含子元素或者文本的空元素 |
屬性選擇器:
語法 | 描述 |
---|---|
[attribute] | 匹配包含給定屬性的元素。 |
[attribute=value] | 匹配給定的屬性是某個特定值的元素 |
[attribute!=value] | 匹配所有不含有指定的屬性,或者屬性不等於特定值的元素 |
[attribute^=value] | 匹配給定的屬性是以某些值開始的元素 |
[attribute$=value] | 匹配給定的屬性是以某些值結尾的元素 |
[attribute*=value] | 匹配給定的屬性是以包含某些值的元素 |
可見性選擇器:
語法 | 描述 |
---|---|
:hidden | 匹配所有不可見元素,或者type爲hidden的元素 |
:visible | 匹配所有的可見元素 |
表單選擇器:
語法 | 描述 |
---|---|
:input | 匹配所有 input, textarea, select 和 button 元素 |
:text | 匹配所有的單行文本框 |
:password | 匹配所有密碼框 |
:radio | 匹配所有單選按鈕 |
:checkbox | 匹配所有複選框 |
:submit | 匹配所有提交按鈕 |
:button | 匹配所有按鈕 |
:file | 匹配所有文件域 |
:hidden | 匹配所有不可見元素,或者type爲hidden的元素 |
表單對象屬性選擇器:
語法 | 描述 |
---|---|
:enabled | 匹配所有可用元素 |
:disabled | 匹配所有不可用元素 |
:checked | 匹配所有選中的被選中元素(複選框、單選框等,不包括select中的option) |
:selected | 匹配所有選中的option元素 |
3.3 事件
頁面對不同訪問者的響應叫做事件。
事件處理程序指的是當 HTML 中發生某些事件時所調用的方法。
語法:
$("p").click(function(){ // 動作觸發後執行的代碼 });
實例:當點擊事件在某個
元素上觸發時,隱藏當前的
元素
$("p").click(function(){ $(this).hide(); });
常見的DOM事件:
鼠標事件 | 鍵盤事件 | 表單事件 | 文檔/窗口事件 |
---|---|---|---|
click | keypress | submit | load |
dbclick | keyup | change | resize |
mouseenter | keydown | focus | scroll |
mouseleave | blur | unload | |
hover |
3.4 效果
3.4.1 隱藏和顯示
jQuery使用 hide() 和 show() 方法來隱藏和顯示 HTML 元素。
基本語法:
$(selector).hide(speed,callback); 隱藏
$(selector).show(speed,callback); 顯示
可選的 speed 參數規定隱藏/顯示的速度,可以取以下值:“slow”、“fast” 或毫秒。
可選的 callback 參數是隱藏或顯示完成後所執行的函數名稱。
簡單案例:
$("#hide").click(function(){ $("p").hide(); }); $("#show").click(function(){ $("p").show(); });
3.4.2 淡入淡出
通過 jQuery可以實現元素的淡入淡出效果。
jQuery fadeIn() 用於淡入已隱藏的元素。
- 語法:$(selector).fadeIn(speed,callback);
$("button").click(function(){ $("#div1").fadeIn(); $("#div2").fadeIn("slow"); $("#div3").fadeIn(3000); });
jQuery fadeOut() 方法用於淡出可見元素。
- 語法:$(selector).fadeOut(speed,callback);
$("button").click(function(){ $("#div1").fadeOut(); $("#div2").fadeOut("slow"); $("#div3").fadeOut(3000); });
jQuery fadeToggle() 方法可以在 fadeIn() 與 fadeOut() 方法之間進行切換。
- 語法:$(selector).fadeToggle(speed,callback);
$("button").click(function(){ $("#div1").fadeToggle(); $("#div2").fadeToggle("slow"); $("#div3").fadeToggle(3000); });
jQuery fadeTo() 方法允許漸變爲給定的不透明度(值介於 0 與 1 之間)。
- 語法:$(selector).fadeTo(speed,opacity,callback);
$("button").click(function(){ $("#div1").fadeTo("slow",0.15); $("#div2").fadeTo("slow",0.4); $("#div3").fadeTo("slow",0.7); });
3.4.3 滑動
通過 jQuery可以在元素上創建滑動效果。
jQuery slideDown() 方法用於向下滑動元素。
- 語法:$(selector).slideDown(speed,callback);
$("#flip").click(function(){ $("#panel").slideDown(); });
jQuery slideUp() 方法用於向上滑動元素。
- 語法:$(selector).slideUp(speed,callback);
$("#flip").click(function(){ $("#panel").slideUp(); });
jQuery slideToggle() 方法可以在 slideDown() 與 slideUp() 方法之間進行切換。
- 語法:$(selector).slideToggle(speed,callback);
$("#flip").click(function(){ $("#panel").slideToggle(); });
3.4.4 動畫
jQuery animate() 方法用於創建自定義動畫。
- 語法:$(selector).animate({params},speed,callback);
- 必需的 params 參數定義形成動畫的 CSS 屬性。
- 可選的 speed 參數規定效果的時長。它可以取以下值:“slow”、“fast” 或毫秒。
- 可選的 callback 參數是動畫完成後所執行的函數名稱。
// 把 <div> 元素往右邊移動了 250 像素 $("button").click(function(){ $("div").animate({left:'250px'}); }); // 通過animate操作多個屬性 $("button").click(function(){ $("div").animate({ left:'250px', opacity:'0.5', height:'150px', width:'150px' }); });
四、DOM操作
4.1 jQuery和js中DOM的區別
jQuery將js中常用的DOM操作都封裝成了方法。
常見的有text()、html()、val()、attr()。
4.2 內容設置
text() - 設置或返回所選元素的文本內容
$("#btn1").click(function(){ $("#test1").text("Hello world!"); });
html() - 設置或返回所選元素的內容(包括 HTML 標記)
$("#btn2").click(function(){ $("#test2").html("<b>Hello world!</b>"); });
val() - 設置或返回表單字段的值
$("#btn3").click(function(){ $("#test3").val("Hello"); });
attr() 方法也用於設置/改變屬性值
$("button").click(function(){ $("#link1").attr("href","http://www.qfedu.com"); });
4.3 元素的添加和刪除
4.3.1 添加元素
- append() - 在被選元素的結尾插入內容
$("p").append("追加文本");
- prepend() - 在被選元素的開頭插入內容
$("p").prepend("在開頭追加文本");
- after() - 在被選元素之後插入內容
$("img").after("在後面添加文本");
- before() - 在被選元素之前插入內容
$("img").before("在前面添加文本");
- 區別:
- append/prepend 是在選擇元素內部嵌入。
- after/before 是在元素外面追加。
4.3.2 刪除元素
remove() - 刪除被選元素(及其子元素)
$("#div1").remove();
empty() - 從被選元素中刪除子元素
$("#div1").empty();
五、節點關係
5.1 parent
parent() 方法返回被選元素的直接父元素。該方法只會向上一級對 DOM 樹進行遍歷。
// 返回每個 <span> 元素的直接父元素 $(document).ready(function(){ $("span").parent(); });
5.2 children
children() 方法返回被選元素的所有直接子元素。該方法只會向下一級對 DOM 樹進行遍歷。
// 返回每個 <div> 元素的所有直接子元素 $(document).ready(function(){ $("div").children(); }); // 返回類名爲 "1" 的所有 <p> 元素,並且它們是 <div> 的直接子元素 $(document).ready(function(){ $("div").children("p.1"); });
5.3 siblings
siblings() 方法返回被選元素的所有同胞元素。
// 返回 <h2> 的所有同胞元素 $(document).ready(function(){ $("h2").siblings(); }); // 返回屬於 <h2> 的同胞元素的所有 <p> 元素 $(document).ready(function(){ $("h2").siblings("p"); });
5.4 next
next() 方法返回被選元素的下一個同胞元素。該方法只返回一個元素。
// 返回 <h2> 的下一個同胞元素 $(document).ready(function(){ $("h2").next(); });
5.5 find
find() 方法返回被選元素的後代元素,一路向下直到最後一個後代。
// 返回屬於 <div> 後代的所有 <span> 元素 $(document).ready(function(){ $("div").find("span"); });
5.6 案例
級聯和全選
六、AJAX
原生的ajax方法代碼比較複雜,jQuery中對AJAX操作也進行了封裝。
6.1 ajax
jQuery 底層 AJAX 實現。
語法:$.ajax(url, [settings]);
url:一個用來包含發送請求的URL字符串
settings:AJAX 請求設置(所有選項都是可選的)
url,發送請求的地址
type,請求方式 (“POST” 或 “GET”)
async,默認爲true,默認爲異步請求
contentType,請求內容編碼類型
data,發送到服務器的數據
dataType,預期服務器返回的數據類型
success,請求成功時會調用此函數
error,請求失敗時會調用此函數
headers,消息頭中的值設置$.ajax({ async: true, type: "POST", url: "test.do", contentType: "application/json" data: "name=John&age=18", dataType: "json", success: function(msg){ alert( "Data Saved: " + msg ); } });
6.2 get
通過 HTTP GET 請求從服務器上請求數據
語法:$.get(URL,callback);
第一個參數是我們希望請求的 URL。
第二個參數是回調函數。
$("button").click(function(){ $.get("test.do",function(data,status){ alert("數據: " + data + "\n狀態: " + status); }); });
6.3 post
通過 HTTP POST 請求從服務器上請求數據
語法:$.post(URL,data,callback);
必需的 URL 參數規定您希望請求的 URL。
可選的 data 參數規定連同請求發送的數據。
可選的 callback 參數是請求成功後所執行的函數名。
$("button").click(function(){ $.post("test.do", { name:"zhangsan", age:"18" }, function(data,status){ alert("數據: \n" + data + "\n狀態: " + status); }); });
七、表單校驗
jQuery Validate 插件爲表單提供了強大的驗證功能,讓客戶端表單驗證變得更簡單,同時提供了大量的定製選項,滿足應用程序各種需求。
使用前需要先導入對應的js庫(注意:jQuery的庫需要在前面導入):
<script src="jquery.js"></script> <script src="jquery.validate.min.js"></script>
7.1 默認校驗規則
序號 | 規則 | 描述 |
---|---|---|
1 | required:true | 必須輸入的字段。 |
2 | remote:“check.php” | 使用 ajax 方法調用 check.php 驗證輸入值。 |
3 | email:true | 必須輸入正確格式的電子郵件。 |
4 | url:true | 必須輸入正確格式的網址。 |
5 | date:true | 必須輸入正確格式的日期。日期校驗 ie6 出錯,慎用。 |
6 | dateISO:true | 必須輸入正確格式的日期(ISO),例如:2009-06-23,1998/01/22。只驗證格式,不驗證有效性。 |
7 | number:true | 必須輸入合法的數字(負數,小數)。 |
8 | digits:true | 必須輸入整數。 |
9 | creditcard: | 必須輸入合法的信用卡號。 |
10 | equalTo:"#field" | 輸入值必須和 #field 相同。 |
11 | accept: | 輸入擁有合法後綴名的字符串(上傳文件的後綴)。 |
12 | maxlength:5 | 輸入長度最多是 5 的字符串(漢字算一個字符)。 |
13 | minlength:10 | 輸入長度最小是 10 的字符串(漢字算一個字符)。 |
14 | rangelength:[5,10] | 輸入長度必須介於 5 和 10 之間的字符串(漢字算一個字符)。 |
15 | range:[5,10] | 輸入值必須介於 5 和 10 之間。 |
16 | max:5 | 輸入值不能大於 5。 |
17 | min:10 | 輸入值不能小於 10。 |
7.2 默認提示
messages: { required: "This field is required.", remote: "Please fix this field.", email: "Please enter a valid email address.", url: "Please enter a valid URL.", date: "Please enter a valid date.", dateISO: "Please enter a valid date ( ISO ).", number: "Please enter a valid number.", digits: "Please enter only digits.", creditcard: "Please enter a valid credit card number.", equalTo: "Please enter the same value again.", maxlength: $.validator.format( "Please enter no more than {0} characters." ), minlength: $.validator.format( "Please enter at least {0} characters." ), rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ), range: $.validator.format( "Please enter a value between {0} and {1}." ), max: $.validator.format( "Please enter a value less than or equal to {0}." ), min: $.validator.format( "Please enter a value greater than or equal to {0}." ) }
如果需要提示顯示中文,可以下載messages_zh.js,並導入到頁面:
<script src="messages_zh.js"></script>
7.3 示例
<script src="jquery.js"></script>
<script src="jquery.validate.min.js"></script>
<script src="messages_zh.js"></script>
<script>
$.validator.setDefaults({
submitHandler: function() {
alert("提交事件!");
}
});
$().ready(function() {
$("#commentForm").validate();
});
</script>
<form class="cmxform" id="commentForm" method="get" action="">
<fieldset>
<legend>輸入您的名字,郵箱,URL,備註。</legend>
<p>
<label for="cname">Name (必需, 最小兩個字母)</label>
<input id="cname" name="name" minlength="2" type="text" required>
</p>
<p>
<label for="cemail">E-Mail (必需)</label>
<input id="cemail" type="email" name="email" required>
</p>
<p>
<label for="curl">URL (可選)</label>
<input id="curl" type="url" name="url">
</p>
<p>
<label for="ccomment">備註 (必需)</label>
<textarea id="ccomment" name="comment" required></textarea>
</p>
<p>
<input class="submit" type="submit" value="Submit">
</p>
</fieldset>
</form>
八、自動填充
jQuery Autocomplete 插件根據用戶輸入值進行搜索和過濾,讓用戶快速找到並從預設值列表中選擇。通過給 Autocomplete 字段焦點或者在其中輸入字符,插件開始搜索匹配的條目並顯示供選擇的值的列表。通過輸入更多的字符,用戶可以過濾列表以獲得更好的匹配。
示例:(注意:此插件現在已經集成到jquery-ui.js中)
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jQuery UI Autocomplete</title> <link rel="stylesheet" href="jquery-ui.css"> <script src="jquery-1.10.2.js"></script> <script src="jquery-ui.js"></script> <script> $(function() { var availableTags = [ "ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Scheme" ]; $( "#tags" ).autocomplete({ source: availableTags }); }); </script> </head> <body> <div class="ui-widget"> <label for="tags">Tags: </label> <input id="tags"> </div> </body> </html>
九、重複驗證
jQuery Validate 插件爲表單提供了封裝AJAX驗證是否重複的功能。
示例:
$(function(){ $("#frm").validateForm({ rules:{ 'checkname.key':{ required:true, remote:{ type:"post", url:"check.do", data:{ "name":function(){ return $("#name").val(); }, }, }, }, }, messages:{ 'checkname.key':{ required:"此處不能爲空", remote:"該用戶名已存在!" } } }); })
十、Ajax操作DOM
下拉級聯案例:省、市、區級聯
核心代碼如下:
AJAX調用的三個Servlet對應的代碼
@WebServlet("/provinceList.do")
public class ProvinceListServlet extends HttpServlet{
private ProvinceService provinceService = new ProvinceService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Province> list = provinceService.findAll(); //獲取所有的省份信息
String jsonString = new Gson().toJson(list); // 將所有省份信息轉換成json字符串
resp.setContentType("application/json;charset=utf8"); // 設置響應信息格式和編碼
resp.getWriter().write(jsonString); // 將json數據輸出到響應流
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
@WebServlet("/cityList.do")
public class CityListServlet extends HttpServlet{
private CityService cityService = new CityService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id"); //獲取選擇的省份id
List<City> list = cityService.findAllByProvinceId(id); //根據id獲取相應的城市信息
String jsonString = new Gson().toJson(list); // 將所得城市信息轉換成json字符串
resp.setContentType("application/json;charset=utf8"); // 設置響應信息格式和編碼
resp.getWriter().write(jsonString); // 將json數據輸出到響應流
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
@WebServlet("/areaList.do")
public class AreaListServlet extends HttpServlet{
private AreaService areaService = new AreaService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id"); //獲取選擇的城市id
List<Area> list = areaService.findAllByCityId(id); //根據id獲取相應的地區信息
String jsonString = new Gson().toJson(list); // 將所得地區信息轉換成json字符串
resp.setContentType("application/json;charset=utf8"); // 設置響應信息格式和編碼
resp.getWriter().write(jsonString); // 將json數據輸出到響應流
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
index.html代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>省市區級聯</title>
</head>
<body>
<form id="myform" action="" method="get">
省:
<select id="provinceSelect">
<option value="">請選擇</option>
</select>
市:
<select id="citySelect">
<option value="">請選擇</option>
</select>
區:
<select id="areaSelect">
<option value="">請選擇</option>
</select>
</form>
</body>
</html>
<script src="js/jquery.js"></script>
<script>
$(function () {
loadProvince(); //加載所有的省份信息
$("#provinceSelect").change(loadCity); //給省份下拉框綁定下拉框事件
$("#citySelect").change(loadArea); //給城市下拉框綁定下拉框事件
});
// 加載所有的省份信息
function loadProvince() {
$.get("provinceList.do", function (data) {
var content = "<option value=\"\">請選擇</option>"; // 初始選項
$.each(data, function (index, obj) {
// 循環拼接選項信息
content += "<option value='"+obj.id+"'>"+obj.name+"</option>";
});
$("#provinceSelect").html(content); // 將選項信息添加到下拉框
});
}
// 根據所選的省份id加載對應的城市信息
function loadCity() {
var id = $("#provinceSelect").val(); // 獲取所選的省份id
$.get("cityList.do", {"id":id}, function (data) {
var content = "<option value=\"\">請選擇</option>"; // 初始選項
$.each(data, function (index, obj) {
// 循環拼接選項信息
content += "<option value='"+obj.id+"'>"+obj.name+"</option>";
});
$("#citySelect").html(content); // 將選項信息添加到下拉框
});
}
// 根據所選的城市id加載對應的地區信息
function loadArea() {
var id = $("#citySelect").val(); // 獲取所選的城市id
$.get("areaList.do", {"id":id}, function (data) {
var content = "<option value=\"\">請選擇</option>"; // 初始選項
$.each(data, function (index, obj) {
// 循環拼接選項信息
content += "<option value='"+obj.id+"'>"+obj.name+"</option>";
});
$("#areaSelect").html(content); // 將選項信息添加到下拉框
});
}
</script>
十一、綜合案例(商品增刪改查、分頁)
Java代碼,util包
public class Constants {
public static int PAGE_SIZE = 5; // 每頁顯示的條數
public static String SQL_PRODUCT_LIST = "SELECT id, name, price, type, detail FROM product ORDER BY createDate DESC limit ?,?"; // 分頁查詢
public static String SQL_PRODUCT_COUNT = "SELECT count(1) FROM product";
public static String SQL_PRODUCT_SAVE = "INSERT INTO product(name, price, type, detail, createDate) VALUES(?,?,?,?,?)";
public static String SQL_PRODUCT_UPDATE = "UPDATE product SET name = ?, price = ?, type = ?, detail = ?, createDate = ? WHERE id = ?";
public static String SQL_PRODUCT_DELETE = "DELETE FROM product WHERE id = ?";
public static String SQL_PRODUCT_BY_ID = "SELECT id, name, price, type, detail FROM product WHERE id = ?";
}
public class DBConnection {
public static Connection getConnection() throws Exception{
Class.forName("com.mysql.jdbc.Driver"); // 加載驅動
return DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8",
"root","root"); // 獲得連接
}
}
Java代碼,entity包
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
private Integer id;
private String name;
private int price;
private String type;
private String detail;
}
/**
* 分頁bean
*/
public class PageInfo {
private int count; // 條數
private int current; // 當前頁
private int pages; // 總頁數
private List list; // 當前頁顯示數據
private List showNumbers; // 分頁條顯示的頁碼
private int pre; // 前一頁
private int next; // 後一頁
private boolean hasPre; // 是否有前一頁
private boolean hasNext; // 是否有後一頁
private boolean isFirst; // 是否首頁
private boolean isLast; // 是否尾頁
private int first = 1; // 首頁
private int last; // 尾頁
public PageInfo(int count, List list, int current){
this.count = count;
this.list = list;
this.current = current;
if(count % Constants.PAGE_SIZE == 0){
this.pages = count / Constants.PAGE_SIZE;
}else {
this.pages = count / Constants.PAGE_SIZE + 1;
}
int begin = current - 5 < 1 ? 1 : current - 5;
int end = current + 5 > pages ? pages : current + 5;
showNumbers = new ArrayList(11);
for (int i = begin; i <= end; i++){
showNumbers.add(i);
}
isLast = current == pages;
last = pages;
isFirst = current == 1;
hasNext = current != pages;
next = current + 1;
hasPre = current > 1;
pre = current - 1;
}
public List getShowNumbers() {
return showNumbers;
}
public boolean getIsLast(){
return isLast;
}
public int getLast() {
return last;
}
public boolean getIsFirst(){
return isFirst;
}
public int getFirst() {
return first;
}
public boolean getHasNext(){
return hasNext;
}
public int getNext() {
return next;
}
public boolean getHasPre(){
return hasPre;
}
public int getPre() {
return pre;
}
public int getPages() {
return pages;
}
public int getCurrent() {
return current;
}
public List getList() {
return list;
}
public int getCount() {
return count;
}
}
/**
* 封裝json數據
*/
@Data
public class JsonResult {
private String code; // 消息code
private String desc; // 錯誤描述
private Object data; // 傳遞數據
/**
* 成功返回json數據構造器
* @param data
* @return
*/
public static JsonResult createSuccessResult(Object data){
JsonResult result = new JsonResult();
result.code = "10000";
result.data = data;
return result;
}
/**
* 失敗返回json數據構造器
* @param code
* @param desc
* @return
*/
public static JsonResult createFailResult(String code, String desc){
JsonResult result = new JsonResult();
result.code = code;
result.desc = desc;
return result;
}
}
Java代碼,dao包
public class ProductDAO {
/**
* 返回當前頁所有的商品信息
* @param page 當前頁碼
* @return
*/
public List<Product> findAll(int page){
List<Product> list = new ArrayList<>();
try(
Connection conn = DBConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(Constants.SQL_PRODUCT_LIST);
){
pstmt.setInt(1, (page - 1) * Constants.PAGE_SIZE);
pstmt.setInt(2, Constants.PAGE_SIZE);
try(
ResultSet rs = pstmt.executeQuery();
){
while (rs.next()){
Product product = new Product(rs.getInt("id"),
rs.getString("name"),
rs.getInt("price"),
rs.getString("type"),
rs.getString("detail"));
list.add(product);
}
}
}catch (Exception e){
e.printStackTrace();
}
return list;
}
/**
* 根據id查詢
* @param id
* @return
*/
public Product findById(int id){
try(
Connection conn = DBConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(Constants.SQL_PRODUCT_BY_ID);
){
pstmt.setInt(1, id);
try(
ResultSet rs = pstmt.executeQuery();
){
while (rs.next()){
return new Product(rs.getInt("id"),
rs.getString("name"),
rs.getInt("price"),
rs.getString("type"),
rs.getString("detail"));
}
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* 返回共有的條數
* @return
*/
public int count(){
try(
Connection conn = DBConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(Constants.SQL_PRODUCT_COUNT);
ResultSet rs = pstmt.executeQuery();
){
while (rs.next()){
return rs.getInt(1);
}
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
/**
* 商品添加
* @param product
* @return
*/
public int save(Product product){
try(
Connection conn = DBConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(Constants.SQL_PRODUCT_SAVE);
){
pstmt.setString(1, product.getName());
pstmt.setInt(2, product.getPrice());
pstmt.setString(3, product.getType());
pstmt.setString(4, product.getDetail());
pstmt.setTimestamp(5, new Timestamp(System.currentTimeMillis()));
return pstmt.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
/**
* 商品修改
* @param product
* @return
*/
public int update(Product product){
try(
Connection conn = DBConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(Constants.SQL_PRODUCT_UPDATE);
){
pstmt.setString(1, product.getName());
pstmt.setInt(2, product.getPrice());
pstmt.setString(3, product.getType());
pstmt.setString(4, product.getDetail());
pstmt.setTimestamp(5, new Timestamp(System.currentTimeMillis()));
pstmt.setInt(6, product.getId());
return pstmt.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
/**
* 商品刪除
* @param id
* @return
*/
public int delete(int id){
try(
Connection conn = DBConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(Constants.SQL_PRODUCT_DELETE);
){
pstmt.setInt(1, id);
return pstmt.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
}
Java代碼,service包
public class ProductService {
private ProductDAO productDAO = new ProductDAO();
/**
* 查詢當前頁所有數據
* @param page
* @return
*/
public JsonResult findAll(String page){
int nPage = 1;
try{
nPage = Integer.parseInt(page);
}catch (Exception e){
// 靜默處理
}
List<Product> list = productDAO.findAll(nPage);
int count = productDAO.count();
if (list.size() == 0){
return JsonResult.createFailResult("E10005", "沒有查詢到任何數據");
}else {
PageInfo pageInfo = new PageInfo(count, list, nPage);
return JsonResult.createSuccessResult(pageInfo);
}
}
/**
* 根據id查詢
* @param id
* @return
*/
public JsonResult findById(String id){
int nId = 0;
try{
nId = Integer.parseInt(id);
}catch (Exception e){
return JsonResult.createFailResult("E20002", "準備修改的數據需要正確的ID標識");
}
Product product = productDAO.findById(nId);
if (product == null){
return JsonResult.createFailResult("E10004", "查詢無此數據");
}else {
return JsonResult.createSuccessResult(product);
}
}
/**
* 商品添加
* @param product
* @return
*/
public JsonResult save(Product product){
int count = productDAO.save(product);
if (count > 0){
return JsonResult.createSuccessResult(null);
}else {
return JsonResult.createFailResult("E10001", "添加失敗");
}
}
/**
* 商品修改
* @param product
* @return
*/
public JsonResult update(Product product){
int count = productDAO.update(product);
if (count > 0){
return JsonResult.createSuccessResult(null);
}else {
return JsonResult.createFailResult("E10002", "修改失敗");
}
}
/**
* 商品刪除
* @param id
* @return
*/
public JsonResult delete(String id){
int nid = 0;
try {
nid = Integer.parseInt(id);
int count = productDAO.delete(nid);
if (count > 0){
return JsonResult.createSuccessResult(null);
}else {
return JsonResult.createFailResult("E10003", "刪除失敗");
}
}catch (Exception e){
return JsonResult.createFailResult("E20002", "刪除的數據需要正確的ID標識");
}
}
}
Java代碼,servlet包
/**
* 封裝servlet基類
*/
public class BaseServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String method = req.getParameter("m"); // 根據查詢參數m判斷方法的業務
// 默認爲查詢所有
if (method == null || method.trim().equals("")){
method = "list";
}
try {
// 通過反射調用對應的業務方法
this.getClass().getMethod(method, HttpServletRequest.class,
HttpServletResponse.class)
.invoke(this, req, resp);
}catch (Exception e){
e.getCause().printStackTrace();
}
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
@WebServlet("/product.do")
public class ProductServlet extends BaseServlet {
private ProductService productService = new ProductService();
private Gson gson = new Gson();
// 顯示所有商品
public void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String page = req.getParameter("page");
JsonResult jsonResult = productService.findAll(page);
String jsonString = gson.toJson(jsonResult);
resp.setContentType("application/json;charset=utf8");
resp.getWriter().write(jsonString);
}
// 顯示所有商品
public void findById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
JsonResult jsonResult = productService.findById(id);
String jsonString = gson.toJson(jsonResult);
resp.setContentType("application/json;charset=utf8");
resp.getWriter().write(jsonString);
}
public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String price =req.getParameter("price");
int nprice = 0;
try {
nprice = Integer.parseInt(price);
}catch (Exception e){
e.printStackTrace();
}
String type =req.getParameter("type");
String detail =req.getParameter("detail");
Product product = new Product(0, name, nprice, type, detail);
JsonResult jsonResult = productService.save(product);
String jsonString = gson.toJson(jsonResult);
resp.setContentType("application/json;charset=utf8");
resp.getWriter().write(jsonString);
}
public void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
int nid = 0;
try {
nid = Integer.parseInt(id);
String name = req.getParameter("name");
String price =req.getParameter("price");
int nprice = 0;
try {
nprice = Integer.parseInt(price);
}catch (Exception e){
e.printStackTrace();
}
String type =req.getParameter("type");
String detail =req.getParameter("detail");
Product product = new Product(nid, name, nprice, type, detail);
JsonResult jsonResult = productService.update(product);
String jsonString = gson.toJson(jsonResult);
resp.setContentType("application/json;charset=utf8");
resp.getWriter().write(jsonString);
}catch (Exception e){
e.printStackTrace();
JsonResult jsonResult = JsonResult.createFailResult("E20001", "修改的數據需要正確的ID標識");
}
}
public void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
JsonResult jsonResult = productService.delete(id);
String jsonString = gson.toJson(jsonResult);
resp.setContentType("application/json;charset=utf8");
resp.getWriter().write(jsonString);
}
}
index.html頁面代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>商品</title>
</head>
<body>
<div id="listDiv">
<a href="javascript:showAddDiv()">添加</a>
<table>
<tr>
<th>名稱</th>
<th>價格</th>
<th>類型</th>
<th>描述</th>
<th>操作</th>
</tr>
<tbody id="productBody">
</tbody>
</table>
<div id="pageDiv">
</div>
</div>
<div id="addDiv" style="display: none">
<form id="addForm">
商品名稱:<input type="text" name="name"/><br/>
商品價格:<input type="text" name="price"/><br/>
商品類型:<input type="text" name="type"/><br/>
商品描述:<input type="text" name="detail"/><br/>
<input type="button" value="添加" onclick="addProduct()"/>
<input type="button" value="返回" onclick="fnGoBack()"/>
<input type="reset" name="reset" style="display: none;" />
<br/>
</form>
</div>
<div id="updateDiv" style="display: none">
<form id="updateForm">
<input type="hidden" name="id">
商品名稱:<input type="text" name="name"/><br/>
商品價格:<input type="text" name="price"/><br/>
商品類型:<input type="text" name="type"/><br/>
商品描述:<input type="text" name="detail"/><br/>
<input type="button" value="修改" onclick="updateProduct()"/>
<input type="button" value="返回" onclick="fnGoBack()"/>
<br/>
</form>
</div>
</body>
</html>
<script src="js/jquery.js"></script>
<script>
$(function () {
loadData(1); // 加載第一頁數據
});
// 顯示列表
function showListDiv(){
showDiv("listDiv");
loadData(1);
}
// 顯示添加
function showAddDiv() {
$("#addForm :reset").trigger("click"); // 調用reset將add表單數據置空
showDiv("addDiv");
}
// 顯示修改
function showUpdateDiv() {
showDiv("updateDiv");
}
function showDiv(id) {
$("#" + id).show().siblings("div").hide(); // 顯示id對應的div,並將平級的其他div隱藏
}
// 返回時顯示列表
function fnGoBack() {
showDiv("listDiv");
}
// 添加商品
function addProduct() {
$.post("product.do?m=add", $("#addForm").serialize(), function (result) {
if(result.code == "10000"){
alert("添加成功");
showListDiv();
}else {
alert(result.desc);
}
});
}
// 預修改商品,根據id查詢並將數據顯示在表單裏
function preUpdateProduct(id) {
$.get("product.do", {"m":"findById","id": id}, function (result) {
if(result.code == "10000"){
$("#updateDiv input[name=id]").val(result.data.id);
$("#updateDiv input[name=name]").val(result.data.name);
$("#updateDiv input[name=price]").val(result.data.price);
$("#updateDiv input[name=type]").val(result.data.type);
$("#updateDiv input[name=detail]").val(result.data.detail);
showUpdateDiv();
}else {
alert(result.desc);
}
});
}
// 修改商品
function updateProduct() {
$.post("product.do?m=update", $("#updateForm").serialize(), function (result) {
if(result.code == "10000"){
alert("修改成功");
showListDiv();
}else {
alert(result.desc);
}
});
}
// 刪除商品
function deleteProduct(id) {
if (confirm("確認要刪除嗎?")){
$.post("product.do", {"m":"del", "id":id}, function (result) {
if(result.code == "10000"){
alert("刪除成功");
showListDiv();
}else {
alert(result.desc);
}
});
}
}
// 加載當前頁數據
function loadData(p) {
$.get("product.do", {"page":p}, function (result) {
if(result.code == "10000"){
var content = "";
// 加載表格中數據
$.each(result.data.list, function (index, obj) {
content += "<tr><td>"+obj.name+"</td><td>"+obj.price+"</td><td>"+obj.type+
"</td><td>"+obj.detail+"</td><td><a href='javascript:preUpdateProduct("+obj.id+")'>修改</a> <a href='javascript:deleteProduct("+obj.id+")'>刪除</a></td></tr>";
});
$("#productBody").html(content);
// 設置分頁信息
var pageContent = "一共有"+result.data.count+"條數據,共"+result.data.pages+"頁<br/>";
// 判斷首頁
if (result.data.isFirst){
pageContent += "首頁";
}else {
pageContent += "<a href='javascript:loadData(1);'>首頁</a>";
}
// 判斷上一頁
if (result.data.hasPre){
pageContent += "<a href='javascript:loadData("+result.data.pre+");'>上一頁</a>";
}else {
pageContent += "上一頁";
}
// 顯示分頁條中的頁碼
var arr = result.data.showNumbers;
for (var i = 0; i < arr.length; i++){
if(arr[i] == result.data.current){
pageContent += " " + arr[i] + " ";
}else {
pageContent += " <a href='javascript:loadData("+arr[i]+");'>"+arr[i]+"</a> ";
}
}
// 判斷下一頁
if (result.data.hasNext){
pageContent += "<a href='javascript:loadData("+result.data.next+");'>下一頁</a>";
}else {
pageContent += "下一頁";
}
// 判斷尾頁
if (result.data.isLast){
pageContent += "尾頁";
}else {
pageContent += "<a href='javascript:loadData("+result.data.last+");'>尾頁</a>";
}
$("#pageDiv").html(pageContent);
}else {
$("#productBody").empty();
alert(result.desc);
}
});
}
</script>