整体介绍
◆了解jQuery3的基本使用方法 ◆掌握Ajax处理流程与实现流程 ◆掌握jQueryr中Ajax方法的使用
JavaScript库
为了简化JavaScript开发,第三方厂商开发了JavaScript库
jQuery介绍
◆jQuery是一个轻量级JS库,使用十分简单 ◆jQuery的核心是选择器,用于获取页面元素 ◆jQuery提供了大量高效方法,开发速度大幅提升
jQuery下载与安装
jQuery官网:jquery.com,最新版本3.6.0 ◆jQuery采用独立JS文件发布:jquery-3.6.0js ◆lDE:Eclipse、Hbuilder、sublime、webstorm
Download jQuery | jQuery 学习中可以使用Download the uncompressed, development jQuery 3.6.0未压缩,源代码版 3.6.0.js 线上部署可以使用Download the compressed, production jQuery 3.6.0生产版本 3.6.0.min.js
.js版本是源代码的代码版本,笔记本打开易于阅读,但是文件大小比较大,200多k,所以不用于生产部署打包,而min.js是压缩打包过的,不易于阅读,但只有80多k,可以用于生产部署
min.js:
.js:
在webapps下新建js文件夹,在js目录下粘贴这两个文件,不同情况进行不同引用
jQuery选择器实验室
添加输入标签就选择相应的标签语句进行高亮
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery实验室</title>
<style>
.myclass {
font-style: italic;
color: darkblue;
}
/* 高亮css类 */
.highlight {
color: red;
font-size: 30px;
background: lightblue;
}
</style>
</head>
<body>
<div class="section">
<h2>jQuery选择器实验室</h2>
<input style="height: 24px" id="txtSelector" />
<button id="btnSelect" style="height: 30px">选择</button>
<hr />
<div>
<p id="welcome">欢迎来到选择器实验室</p>
<ul>
<li>搜索引擎:<a href="http://www.baidu.com">百度</a> <span> <a
style="color: darkgreen" href="http://www.so.com">360</a>
</span>
</li>
<li>电子邮箱:<a href="http://mail.163.com">网易邮箱</a> <span> <a
style="color: darkgreen" href="http://mail.qq.com">QQ邮箱</a>
</span>
</li>
<li>中国名校:<a href="http://www.tsinghua.edu.cn">清华大学</a> <span>
<a style="color: darkgreen" href="https://www.pku.edu.cn/">北京大学</a>
</span>
</li>
</ul>
<span class="myclass ">我是拥有myclass类的span标签</span>
<p class="myclass">我是拥有myclass的p标签</p>
<form id="info" action="#" method="get">
<div>
用户名:<input type="text" name="uname" value="admin" /> 密码:<input
type="password" name="upsd" value="123456" />
</div>
<div>
婚姻状况: <select id="marital_status">
<option value="1">未婚</option>
<option value="2">已婚</option>
<option value="3">离异</option>
<option value="4">丧偶</option>
</select>
</div>
<div class="left clear-left">
<input type="submit" value="提交" /> <input type="reset" value="重置" />
</div>
</form>
</div>
</div>
<script type="text/javascript" src="js/jquery-3.6.0.js" ></script>
<script type="text/javascript">
/*
id选择器使用"#id值"进行选择
css选择器使用".css类名"进行选择
$(".myclass").addClass("highlight");
*/
document.getElementById("btnSelect").onclick = function(){
var selector = document.getElementById("txtSelector").value;
//jquery的选择器方法
//选择器
$("*").removeClass("highlight");
$(selector).addClass("highlight");
}
</script>
</body>
</html>
基本选择器
Web页面开发的两个要素
在使用HTML开发页面时,有两个基本点:
- 选择HTML页面上在哪些元素
- 在这些元素上做哪些动作
jQuery选择器
◆jQuery选择器用于选中需要操作的页面元素 ◆语法1:jQuery(选择器表达式) ◆语法2:$(选择器表达式)
基本选择器
◆基本选择器是jQuery最基础也是最常用的选择器表达式
层叠与属性选择器
层叠选择器
◆层叠选择器是根据元素的位置关系来获取元素的选择器表达式
例如:
属性选择器
◆属性选择器是根据元素的属性值来选择元素的选择器表达式
例如:
搭配基本选择器使用:
在基本选择器中选中搜索框:
在属性选择器中:
属性选择器只有明确书写了属性名和属性值才会进行匹配
位置与表单选择器
位置选择器
位置选择器是指通过位置获取指定的元素,例如“获取第3个元素”
例如:
表单选择器
◆表单选择器是获取表单元素的简化形式,例如:获取所有文本框
例如:
无论是否书写了text这个选择器名,只要是个标准的文本框就会被选中,不像属性选择器必须有对应属性名和属性值
操作元素属性
Web页面开发的两个要素
在使用HTML开发页面时,有两个基本点:
- 选择HTML页面上在哪些元素
- 在这些元素上做哪些动作
上面的选择器学习完成第一步 下面学习进行第二步
操作元素属性
◆attr(nameproperties key)-获取或设置元素属性 ◆removeAttr(name)-移除元素属性
<script type="text/javascript" src="js/jquery-3.3.1.js"></script>
<script type="text/javascript">书写语句</script>
一个参数表示获取属性
var href_attr = $("a[href*='163']").attr("href");
alert(href_attr);
两个参数表示设置属性
$("a[href*='163']").attr("href" , "http://www.163.com");
如果获取多个属性,比如获取所有a标签
var attr = $("a").attr("href");
alert(attr);
会默认返回第一个属性值 注意获取多个属性值会默认返回第一个,而设置多个属性值会全部进行赋值设置
移除属性:移除所有超链接
$("a").removeAttr("href");
操作元素CSS样式
◆CSS()-获取或设置匹配元素的样式属性 ◆addClass()-为每个匹配的元素添加指定的类名 ◆removeClass0-从所有匹配的元素中删除全部或者指定的类
<script type="text/javascript" src="js/jquery-3.6.0.js"></script>
<script type="text/javascript">书写语句</script>
使用json格式添加CSS样式
$("a").css({"color" : "red" , "font-weight" : "bold" , "font-style" : "italic"});
像上一节一样添加高亮样式:
$("li").addClass("highlight");
<style>
.myclass {
font-style: italic;
color: darkblue;
}
/* 高亮css类 */
.highlight {
color: red;
font-size: 30px;
background: lightblue;
}
</style>
$("li").addClass("highlight myclass"); 用过空格+类名添加样式,可以无限添加
设置元素内容
◆val()-获取或设置输入项的值 ◆text()-获取或设置元素的纯文本 ◆html()-获取或设置元素内部的HTML
设置输入值:
$("input[name='uname']").val("administrator"); 设置文本框值为administrator
获取输入值:
var v = $("input[name='uname']").val();
alert(v);
//text与html方法最大的区别在于对于文本中的html标签是否进行转义
//即<b>标签是否转义出来
//$("span.myclass").text("<b>锄禾日当午,汗滴禾下土</b>");
$("span.myclass").html("<b>锄禾日当午,汗滴禾下土</b>");
获取html内容:
var vspan = $("span.myclass").text();
alert(vspan);
同理,使用text()获取的内容也有<b>标签,而使用html()没有 工作中一般使用text()
jQuery事件处理方法
◆on(“click”,function)-为选中的页面元素绑定单击事件 ◆click(function)-是绑定事件的简写形式 ◆处理方法中提供了event参数包含了事件的相关信息
<script type="text/javascript" src="js/jquery-3.3.1.js"></script>
<script type="text/javascript">
//onload是指在页面所有资源加载完成后执行
window.onload = function(){
//alert(1);
}
//ready()则是在页面dom被浏览器解释完成后执行
$(document).ready(function(){
alert("页面准备就绪");
})
//简化形式
$(function(){
$("p.myclass").on("click" , function(){
//$(this)是指当前事件产生的对象
$(this).css("background-color" , "yellow");
});
$("span.myclass").click(function(){
$(this).css("background-color" , "lightgreen");
})
$("input[name='uname']").keypress(function(event){
console.log(event);
if(event.keyCode == 32){
$(this).css("color" , "red");
}
})
})
</script>
当用户输入有空格时就变红:
$("input[name='uname']").keypress(function(event){
console.log(event);
if(event.keyCode == 32){
$(this).css("color" , "red");
}
})
使用event进行事件处理,输入admin+空格,观察出空格的keyCode为32
Ajax介绍
◆Asynchronous JavaScript And XML(异步的JavaScript和XML) ◆Ajax可以在不刷新页面的前提下,进行页面局部更新 ◆Ajax不是新的技术,Ajax并不是W3C的标准
Ajax使用流程
◆创建XmlHttpReqeust对象 ◆发送Ajax请求 ◆处理服务器响应
创建XmlHttpReqeust对象
◆XMLHttpRequest是Ajax的核心,Ajax使用该对象发起请求、接收响应 ◆XMLHttpRequest并不是W3C的标准,不同浏览器的创建方式不同
加载按钮:
<input id="btnLoad" type="button" value="加载"/>
<div id="divContent"></div>
//1. 创建XMLHttpRequest对象
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
console.log("XMLHttpRequest:",xmlhttp);
发送Ajax请求
◆xmlhttp.open()用于创建请求 ◆xmlhttp.send()用于发送请求
//2. 发送Ajax请求
xmlhttp.open("GET", "/content",true);
xmlhttp.send();
第三个参数代表是否采用异步 同级目录直接使用/content链接
src下新建ContentServlet.Java文件
@WebServlet("/content")
public class ContentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("<b style='color:red'>I'm server content</b>");
}
}
网络录制点击加载按钮 我们发现只出现content文件,请求方式和html一样,但是没有出现index.html文件,说明确实之发生了局部刷新,而没有全局刷新
得到响应但是该如何进行加载到浏览器界面?这时需要进行Ajax第三步
处理服务器响应
◆xmlhttp.onreadystatechange()事件用于监听Ajax的执行过程 ◆xmlhttp.readyState属性说明XMLHttpRequest当前状态
◆xmlhttp.status属性服务器响应状态码,200:成功404:未找到。…
//3. 处理服务器响应
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var t = xmlhttp.responseText;
console.log(t);
document.getElementById("divContent").innerHTML = document.getElementById("divContent").innerHTML + "<br/>" + t;
}
}
每点击一次就出现一次,而且是整个不刷新的状态直接获取内容
大部分服务器返回的不是HTML片段,AJAX获取到的而是JSON数据,下回讲解
同步与异步
//2. 发送Ajax请求
xmlhttp.open("GET", "/content",true);
xmlhttp.send();
true是同步,false是异步,默认异步
◆同步是在服务器未返回JSON前,JS程序一直处于阻塞等待的状态
◆异步是在服务器未返回JSON前,不阻塞程序,Ajax通过回调获取结果
利用Jackson实现JSON序列化输出
Ajax+JSON开发模式
Jackson
◆Jackson是国内外著名的Java开源JSON序列化组件 ◆Jackson国内拥有大量使用者,拥有API简单,效率高等优点 ◆Jackson也是众多Java框架的底层组件,掌握Jackson很重要
添加jackson的maven依赖,让其自动下载
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
记得在pom.xml文件下右键点击maven重新加载项目
由于国内外通信原因,可能无法下载,导致一串报红,可以添加阿里云镜像
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
然后继续在pom.xml文件下右键点击maven重新加载项目 这时,idea会在后台进行下载,下载成功后,不再爆红,在外部库即可观察到下载的依赖项
注意:当程序使用tomcat发布时,记得将添加的依赖加入到out文件夹下或者target文件夹下web-inf下的lib目录,否则无法运行,具体操作点击项目结构→工件→找到新添加的依赖→选中右键添加到lib目录
Ajax处理JSON数据
news.java文件
package com.imooc.Ajax.entity;
public class News {
private String title;
private String date;
private String source;
private String content;
public News(String title, String date, String source, String content) {
this.title = title;
this.date = date;
this.source = source;
this.content = content;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
NewsServlet.java文件
@WebServlet("/news")
public class NewsServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String t = request.getParameter("t");
List<News> list = new ArrayList<News>();
if(t.equals("tiobe")) {
list.add(new News("TIOBE:2018年编程语言排行趋势", "2018-5-1", "TIOBE", "..."));
list.add(new News("TIOBE:2019年编程语言排行趋势", "2019-5-1", "TIOBE", "..."));
list.add(new News("TIOBE:2020年编程语言排行趋势", "2020-5-1", "TIOBE", "..."));
list.add(new News("TIOBE:2021年编程语言排行趋势", "2021-5-1", "TIOBE", "..."));
}else if(t.equals("pypl")){
list.add(new News("PYPL:2018年编程语言排行趋势", "2018-5-1", "PYPL", "..."));
list.add(new News("PYPL:2019年编程语言排行趋势", "2019-5-1", "PYPL", "..."));
list.add(new News("PYPL:2020年编程语言排行趋势", "2020-5-1", "PYPL", "..."));
list.add(new News("PYPL:2021年编程语言排行趋势", "2021-5-1", "PYPL", "..."));
}
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(list);
response.setContentType("text/json;charset=utf-8");
// response.setContentType("application/json;charset=utf-8");
response.getWriter().println(json);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
在news.html的script标签对里:
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET", "/news");
xmlhttp.send();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var str = xmlhttp.responseText;
console.log(str);
此处只能获得json结构的字符串,需要转换为JSON对象
var json = JSON.parse(str);
console.log(json);
for (var i = 0; i < json.length; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
这时获取到的才是json数据 html渲染:获取到数据进行二次开发的过程 缺点:每发送一次ajax,就要遵循一次创建对象,发送请求,服务响应的过程,比较繁琐,下面学习ajax的封装js库
Axios快速入门
axios中文网|axios API 中文文档 | axios (axios-js.com)
在webapp下新建js目录,创建axios.js文件,将https://unpkg.com/[email protected]/dist/axios.min.js 里面内容全部复制粘贴进去,因为是min.js文件,是压缩过的,不具有可读性
发送get请求
引入js文件后
例如:执行 GET
请求
// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 上面的请求也可以这样做
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
预留一个对象axios,.get方法即执行get请求,‘/user’是预处理的url,params是请求参数,改为使用json格式进行表达,.then表示服务器成功响应返回后会执行里面代码,response是从服务器返回的对象,通过response就能拿到服务器返回的json数据,.catch是异常情况进行处理的代码
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/js/axios.js"></script>
</head>
<body>
<div id="container"></div>
<script>
axios.get('/news', {params:{"t":"pypl"}}).then(function (response) {
console.log(response);
var json = response.data;
for (var i = 0; i < json.length; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
}).catch(function (error) {
console.log(error);
});
</script>
发送post请求
执行 POST
请求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
与get请求方式不相同
axios.post("/news", "t=pypl&l=abc", {headers: {"content-type": "application/x-www-form-urlencoded"}})
url后面不跟json对象,而是标准的请求参数形式,多个参数使用&符号链接,第三个参数需要为header请求头,固定为{"content-type": "application/x-www-form-urlencoded"}
表示请求参数放置于请求体中
注意需要在servlet中重写post方法,否则返回405错误
axios提供一种面向对象的扩展方式进行post发送
const params = new URLSearchParams();
params.append("t", "pypl");
params.append("l", "abc");
调用方式也要发生改变:
axios.post("/news",params)
.then(function (response) {
console.log(response);
var json = response.data;
for (var i = 0; i < json.length; i++) {
var news = json[i];
var container = document.getElementById("container");
container.innerHTML = container.innerHTML + "<h2>" + news.title + "</h2>";
}
})
.catch(function (error) {
console.log(error);
});
此种方法可读性更好
实现二级联动菜单
在com.imooc.ajax.entity的文件目录下: 新建对channel的定义: Channel.java文件:
package com.imooc.ajax.entity;
public class Channel {
private String code;
private String name;
public Channel() {
}
public Channel(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在com.imooc.ajax.servlet目录下:
package com.imooc.ajax.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.ajax.entity.Channel;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/channel")
public class ChannelServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String level = request.getParameter("level");
String parent = request.getParameter("parent");
List<Channel> chlist = new ArrayList<>();
if(level.equals("1")){
chlist.add(new Channel("ai", "人工智能"));
chlist.add(new Channel("web", "前端开发"));
}else if(level.equals("2")){
if(parent.equals("ai")){
chlist.add(new Channel("dl", "深度学习"));
chlist.add(new Channel("cv", "计算机视觉"));
chlist.add(new Channel("nlp", "自然语言处理"));
}else if(parent.equals("web")){
chlist.add(new Channel("html", "HTML超文本标记语言"));
chlist.add(new Channel("css", "CSS级联样式表"));
chlist.add(new Channel("js", "JavaScript脚本"));
}
}
//完成JSON序列化工作
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(chlist);
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(json);
}
}
浏览器地址栏输入localhost:8080/ajax/channel?level=1 得到一级菜单数据
同理输入二级菜单
这时后端的交互数据已经完成,只需要前端做出页面交互就行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/js/axios.js"></script>
</head>
<body>
<select id="lv1" style="width: 200px;height: 30px">
<option value="-1" selected="selected">请选择</option>
</select>
<select id="lv2" style="width: 200px;height: 30px"></select>
</body>
</html>
一级和二级菜单需要产生两个ajax请求
<script>
var lv1 = document.getElementById("lv1");
axios.get("/channel" , {params:{"level" : 1}})
.then(function (response){
var json = response.data;
console.log(json);
for(var i = 0 ; i < json.length ; i++){
var channel = json[i];
lv1.options.add(new Option(channel.name, channel.code));
}
});
var lv2 = document.getElementById("lv2");
lv1.onchange = function(){
axios.get("/channel" , {params:{"level":2,"parent" : lv1.value}})
.then(function(response){
var json = response.data;
console.log(json);
lv2.length = 0;
for(var i = 0 ; i < json.length ; i++){
var channel = json[i];
lv2.options.add(new Option(channel.name,channel.code));
}
})
}
</script>
在每次加载二级菜单时,应该清除原有数据再进行加载,否则会导致结果叠加出现
清除数据语句:
lv2.length = 0;