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>