AJAX
作用:能够与服务器通信,能够进行异步请求。也就是在不重新加载整个页面的情况下,对网页的部 分内容进行局部更新。
三步骤:请求,响应,修改dom
Jquery的方式实现AJAX
-
$.get()
-
$.post()
url:请求的资源路径。
data:发送给服务器端的请求参数,格式可以是key=value,也可以是 js 对象。
callback:当请求成功后的回调函数,可以在函数中编写我们的逻辑代码。
type:预期的返回数据的类型,取值可以是 xml, html, js, json, text等。
-
$.ajax({url,date,type,datatype,success,erro})
url:请求的资源路径。
async:是否异步请求,true-是,false-否 (默认是 true)。
data:发送到服务器的数据,可以是键值对形式,也可以是 js 对象形式。
type:请求方式,POST 或 GET (默认是 GET)。
dataType:预期的返回数据的类型,取值可以是 xml, html, js, json, text等。
success:请求成功时调用的回调函数。
error:请求失败时调用的回调函数。
JSON
JSON:是一种轻量级的数据交换格式。
类型 | 语法 |
---|---|
对象类型 | {name:value,name:value,…} |
数组/集合类型 | [{name:value,…},{name:value,…}] |
混合类型 | {name: [{name:value,…},{name:value,…}]} |
name是字符串类型,value可以是任意类型
json转换
-
前端 JSON
- stringify()
- parse()
-
后端json转换工具
-
导入jar包
-
创建核心对象
-
调用方法完成转换
常用类
- ObjectMapper
- TypeReference
常用方法
- String writeValueAsString(Object obj)将java对象转换成json字符串
- T readValue(String json,Class valueType) 将json字符串转换成Java对象
- T readValue(String json,TypeReference valueTypeRef) 将json字符串转化成Java对象
-
案例1:搜索联想
流程
- 编写联想词
- 发起请求到后端获取数据
- 回调函数中操作dom显示数据到搜索框下
- 前端实现代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户搜索</title>
<style type="text/css">
.content {
width: 643px;
margin: 100px auto;
text-align: center;
}
input[type='text'] {
width: 530px;
height: 40px;
font-size: 14px;
}
input[type='button'] {
width: 100px;
height: 46px;
background: #38f;
border: 0;
color: #fff;
font-size: 15px
}
.show {
position: absolute;
width: 535px;
height: 100px;
border: 1px solid #999;
border-top: 0;
display: none;
}
</style>
</head>
<body>
<form autocomplete="off">
<div class="content">
<img src="img/logo.jpg">
<br/><br/>
<input type="text" id="username">
<input type="button" value="搜索一下">
<!--用于显示联想的数据-->
<div id="show" class="show"></div>
</div>
</form>
</body>
<script src="js/jquery-3.3.1.min.js"></script>
<script>
//1.为用户名输入框绑定鼠标点击事件
$("#username").mousedown(function () {
//2.获取输入的用户名
let username = $("#username").val();
//3.判断用户名是否为空
if(username == null || username == "") {
//4.如果为空,将联想框隐藏
$("#show").hide();
return;
}
//5.如果不为空,发送AJAX请求。并将数据显示到联想框
$.ajax({
//请求的资源路径
url:"userServlet",
//请求参数
data:{"username":username},
//请求方式
type:"POST",
//响应数据形式
dataType:"json",
//请求成功后的回调函数
success:function (data) {
//将返回的数据显示到show的div
let names = "";
for(let i = 0; i < data.length; i++) {
$("#show").html(data[i].name);
// names += "<div>"+data[i].name+"</div>";
}
//$("#show").html(names);
$("#show").show();
}
});
});
</script>
</html>
案例2:瀑布流无限加载数据分页
功能:
- $(function(){}) 页面加载事件
- $(window) 获取当前窗口对象
- scroll() 鼠标滚动事件
- $(window).height() 当前窗口高度
- $(window).scrollTop() 滚动条上下滚动得距离
- $(document).height() 当前文档的高度
如何确定当前显示的数据已经浏览完毕? 公式:(滚动条距底部的距离 + 滚动条上下滚动的距离 + 当前窗口的高度) >= 当前文档的高度
案例的实现
- 定义发送请求标记。
- 定义当前页码和每页显示的条数。
- 定义滚动条距底部的距离。
- 设置页面加载事件。
- 为当前窗口绑定滚动条滚动事件。
- 获取必要信息(当前窗口的高度,滚动条上下滚动的距离,当前文档的高度)。
- 计算当前展示数据是否浏览完毕。
- 判断请求标记是否为 true。
- 将请求标记置为 false,当前异步操作完成前,不能重新发起请求。
- 根据当前页和每页显示的条数来请求查询分页数据。
- 当前页码+1。
-
前端实现代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>网站首页</title> <link rel="stylesheet" href="css/tt.css"> </head> <body> <div class="top"> <span class="top-left">下载APP</span> <span class="top-left"> 北京 晴天</span> <span class="top-right">更多产品</span> </div> <div class="container"> <div class="left"> <a> <img src="img/logo.png"><br/> </a> <ul> <li> <a class="channel-item active" href="#"> <span> 推荐 </span> </a> </li> <li><a class="channel-item" href="#"> <span> 视频 </span> </a></li> <li><a class="channel-item" href="#"> <span> 热点 </span> </a></li> <li><a class="channel-item" href="#"> <span> 直播 </span> </a></li> <li><a class="channel-item" href="#"> <span> 图片 </span> </a></li> <li><a class="channel-item" href="#"> <span> 娱乐 </span> </a></li> <li><a class="channel-item" href="#"> <span> 游戏 </span> </a></li> <li><a class="channel-item" href="#"> <span> 体育 </span> </a></li> </ul> </div> <div class="center"> <ul class="news_list"> <li> <div class="title-box"> <a href="#" class="link"> 奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实11” <hr> </a> </div> </li> <li> <div class="title-box"> <a href="#" class="link"> 奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实1010” <hr> </a> </div> </li> </ul> <div class="loading" style="text-align: center; height: 80px"> <img src="img/loading2.gif" height="100%"> </div> <div class="content"> <div class="pagination-holder clearfix"> <div id="light-pagination" class="pagination"></div> </div> </div> <div id="no" style="text-align: center;color: red;font-size: 20px"></div> </div> </div> </body> <script src="js/jquery-3.3.1.min.js"></script> <script> //1.定义发送请求标记 let send = true; //2.定义当前页码和每页显示的条数 let start = 1; let pageSize = 10; //3.定义滚动条距底部的距离 let bottom = 1; //4.设置页面加载事件 $(function () { //5.为当前窗口绑定滚动条滚动事件 $(window).scroll(function () { //6.获取必要信息,用于计算当前展示数据是否浏览完毕 //当前窗口的高度 let windowHeight = $(window).height(); //滚动条从上到下滚动距离 let scrollTop = $(window).scrollTop(); //当前文档的高度 let docHeight = $(document).height(); //7.计算当前展示数据是否浏览完毕 //当 滚动条距底部的距离 + 当前滚动条滚动的距离 + 当前窗口的高度 >= 当前文档的高度 if((bottom + scrollTop + windowHeight) >= docHeight) { //8.判断请求标记是否为true if(send == true) { //9.将请求标记置为false,当前异步操作完成前,不能重新发起请求。 send = false; //10.根据当前页和每页显示的条数来 请求查询分页数据 queryByPage(start,pageSize); //11.当前页码+1 start++; } } }); }); //定义查询分页数据的函数 function queryByPage(start,pageSize){ //加载动图显示 $(".loading").show(); //发起AJAX请求 $.ajax({ //请求的资源路径 url:"newsServlet", //请求的参数 data:{"start":start,"pageSize":pageSize}, //请求的方式 type:"POST", //响应数据形式 dataType:"json", //请求成功后的回调函数 success:function (data) { if(data.length == 0) { $(".loading").hide(); $("#no").html("有崔子个底线..."); return; } //加载动图隐藏 $(".loading").hide(); //将数据显示 let titles = ""; for(let i = 0; i < data.length; i++) { titles +=`<li> <div class="title-box"> <a href="#" class="link"> ${data[i].title} <hr> </a> </div> </li>` /*"<li>\n" + " <div class=\"title-box\">\n" + " <a href=\"#\" class=\"link\">\n" + data[i].title + " <hr>\n" + " </a>\n" + " </div>\n" + " </li>";*/ } //显示到页面 $(".news_list").append(titles); //将请求标记设置为true send = true; } }); } </script> </html>
案例3:点击按钮分页
前端分页插件的使用
作用: 帮我们自动实现分页页码的生成
-
导包
- simplePagination.css
- jquery-3.3.1.min.js
- jquery.simplePagination.js
-
基本结构(存放页码的元素)
<div class="content"> <div class="pagination-holder clearfix"> <div id="light-pagination" class="pagination"></div> </div> </div>
-
设置参数就能显示对应的页码
//初始化分页插件 //1.找到存放页码的元素 //2.通过pagination方法设置总页数以及当前页码 $("#light-pagination").pagination({ pages:18, currentPage:8 });
业务分析
-
页面刷新直接向后端发起请求(当前页:1, 每页展示数据:10)
- 请求数据展示在页面
- 将分页插件初始化
-
业务返回数据
{ total: 100, //总记录数 list: [], //具体的数据 pageNum: 2, //当前页 pageSize: 10, //每页显示数 size: 10, startRow: 11, endRow: 20, pages: 10,//总页数 prePage: 1, //上一页页码 nextPage: 3, //下一页页码 isFirstPage: false, isLastPage: false, hasPreviousPage: true, hasNextPage: true, navigatePages: 8, navigateFirstPage: 1, navigateLastPage: 8 }
普通分页实现
- 页面加载时请求第一页的数据
- 服务端响应第一页的数据
- 将数据展示到对应的ul中
- 初始化分页插件
点击分页实现
- 拿到当前点击的页码
- 发起异步请求向服务端请求数据
- 展示在页面上
-
前端代码实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>网站首页</title> <link rel="stylesheet" href="css/tt.css"> <link rel="stylesheet" href="css/simplePagination.css"> </head> <body> <div class="top"> <span class="top-left">下载APP</span> <span class="top-left"> 北京 晴天</span> <span class="top-right">更多产品</span> </div> <div class="container"> <div class="left"> <a> <img src="img/logo.png"><br/> </a> <ul> <li> <a class="channel-item active" href="#"> <span> 推荐 </span> </a> </li> <li><a class="channel-item" href="#"> <span> 视频 </span> </a></li> <li><a class="channel-item" href="#"> <span> 热点 </span> </a></li> <li><a class="channel-item" href="#"> <span> 直播 </span> </a></li> <li><a class="channel-item" href="#"> <span> 图片 </span> </a></li> <li><a class="channel-item" href="#"> <span> 娱乐 </span> </a></li> <li><a class="channel-item" href="#"> <span> 游戏 </span> </a></li> <li><a class="channel-item" href="#"> <span> 体育 </span> </a></li> </ul> </div> <div class="center"> <ul class="news_list"> </ul> <div class="content"> <div class="pagination-holder clearfix"> <div id="light-pagination" class="pagination"></div> </div> </div> </div> </div> </body> <script src="js/jquery-3.3.1.min.js"></script> <script src="js/jquery.simplePagination.js"></script> <script> //1.定义当前页码和每页显示的条数 let start = 1; let pageSize = 10; //2.调用查询数据的方法 queryByPage(start,pageSize); //3.定义请求查询分页数据的函数,发起AJAX异步请求,将数据显示到页面 function queryByPage(start,pageSize) { $.ajax({ //请求的资源路径 url:"newsServlet2", //请求的参数 data:{"start":start,"pageSize":pageSize}, //请求的方式 type:"POST", //响应数据形式 dataType:"json", //请求成功后的回调函数 success:function (pageInfo) { //将数据显示到页面 let titles = ""; for(let i = 0; i < pageInfo.list.length; i++) { titles += "<li>\n" + " <div class=\"title-box\">\n" + " <a href=\"#\" class=\"link\">\n" + pageInfo.list[i].title + " <hr>\n" + " </a>\n" + " </div>\n" + " </li>"; } $(".news_list").html(titles); //4.为分页按钮区域设置页数参数(总页数和当前页) $("#light-pagination").pagination({ pages:pageInfo.pages, currentPage:pageInfo.pageNum }); //5.为分页按钮绑定单击事件,完成上一页下一页查询功能 $("#light-pagination .page-link").click(function () { //获取点击按钮的文本内容 let page = $(this).html(); //如果点击的是Prev,调用查询方法,查询当前页的上一页数据 if(page == "Prev") { queryByPage(pageInfo.pageNum - 1,pageSize); }else if (page == "Next") { //如果点击的是Next,调用查询方法,查询当前页的下一页数据 queryByPage(pageInfo.pageNum + 1,pageSize); } else { //调用查询方法,查询当前页的数据 queryByPage(page,pageSize); } }); } }); } </script> </html>