JQuery 史上最全知识汇总

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, 例如:

  • Google

  • 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>

猜你喜欢

转载自blog.csdn.net/weixin_43501566/article/details/105851812
今日推荐