1. jQuery操作ajax
load()
: 加载HTML片段, 即把其他HTML页面文件加载进来, 加载方式: 异步, GET方式加载
load()
函数加载的外部代码片段, 会直接作为调用load()
方法的子元素, 不能反悔相应的代码片段字符串.
$.get(url, data, callback)
: 以get
的方式从服务器获取资源/数据
$.post(url, data, callback)
: 以post
的方式从服务器获取资源/数据, 使用方法跟get
很类似
$.getJSON(url, data, callback)
: 以get
的方式从服务器获取JSON
格式的数据, 并转换成js对象.
- 跟普通的
get
请求不同的点:getJSON()
方法会自动把返回的字符串转换为JSON对象, 再传入回调函数中, 即, 自动执行var data = JSON.parse(res)
语句, 得到的data
是一个JS对象数据.
$ajax()
: 能实现上面2到4的方法, 实际上掌握这个方法即可.
- 五个常用对象字面量参数:
type
: 请求类型, 即:GET
,POST
url
: 请求的urldata
: 发送的数据, 若是GET
请求, 数据可以放到url上, 而POST
请求必须放到data
这里dataType
: 期望服务器返回/相应的数据类型(大部分场景可以自己判断)success
:function(data) {// 回调函数...函数参数的data是服务器返回的数据}
- $.ajax()-jsonp: 使用
$.ajax()
发送跨域请求
url
参数中的jsonp
参数指定的是当前脚本中的一个回调函数, 一般不写死, 用?做占位符, 请求成功后, 会用success
指定的回调函数来填充?占位符.- 如果不想用
success
指定的回调函数来填充?占位符, 也可以用jsonpCallback
参数指定一个本地函数来填充?占位符.
- $.ajax()-jsonp: 使用
第一个按钮加载的外部HTML代码片段nav.html
<ul>
<li>首页</li>
<li>PHP</li>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
第二至第五个按钮发送的请求访问的模拟数据库查询文件users.php
<?php
// 模拟数据库
$users = [
['id' => 1, 'name' => 'zhangsan', 'age' => 33],
['id' => 2, 'name' => 'lisi', 'age' => 23],
['id' => 3, 'name' => 'wangwu', 'age' => 35],
['id' => 4, 'name' => 'zhaoliu', 'age' => 39],
];
$id = intval($_REQUEST['id']);
if(in_array($id, array_column($users, 'id'))) {
foreach($users as $user) {
if($user['id'] == $id) {
// 以自定义格式字符串返回(按钮2, 3)
// vprintf('%s : %s %s 岁', $user);
// 以JSON格式字符串返回(按钮4)
echo json_encode($user);
}
}
} else {
echo "<span style='color: red'>没有找到</span>";
}
第六/第七个按钮访问的查询数据库脚本文件
<?php
// 这里返回json数据, 而json只支持utf8编码
header('content-type: text/html;charset=utf-8');
// 模拟根据id值获取数据, 并调用回调函数处理数据
// 获取请求参数(jsonp指定一个回调函数名)
$callback = $_GET['jsonp'];
$id = $_GET['id'];
// 返回的处理结果数组
$res = [
'status' => '1',
'message' => '查询成功',
];
// 判断id值是否有效
if(!filter_var($id, FILTER_VALIDATE_INT, ['option' => ['min_range' => 1]])) {
$res['status'] = '0';
$res['message'] = 'ID值无效';
}
// 连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=phpedu;charset=utf8;port=3306', 'root', 'root');
// 查询
$stmt = $pdo->query("SELECT * FROM `player` WHERE `id` = {$id}");
// 判断是否查到值
if(!$stmt || $stmt->rowCount < 1) {
// 没查到的处理
$res['status'] = '0';
$res['message'] = 'ID值无效';
} else {
// 查到数据
$res['data'] = $stmt->fetch(PDO::FETCH_ASSOC);
}
// 打印回调
echo $callback . '(' . json_encode(json_encode($res)) . ')';
jQuery操作ajax实例文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>jQuery中操作ajax</title>
<!-- CDN方式引用, 即内容分发方式 -->
<!-- BootCDN或者又拍云的CDN的速度都可以 -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<!-- 本地引用 -->
<style>
body {
height: 100vh;
width: 100vw;
display: flex;
flex-flow: column nowrap;
justify-content: start;
}
body button {
margin-bottom: 10px;
border: 1px solid orangered;
background-color: wheat;
width: 280px;
}
body button:hover {
border: 1px solid orange;
background-color: papayawhip;
cursor: pointer;
}
</style>
</head>
<body>
<button type="button">1. load()请求数据</button>
<button type="button">2. $.get()请求数据</button>
<button type="button">3. $.post()请求数据</button>
<button type="button">4. $.getJSON()请求JSON数据</button>
<button type="button">5. $.ajax()请求数据</button>
<button type="button">6. $.ajax()-jsonp-跨域请求数据1</button>
<button type="button">7. $.ajax()-jsonp-跨域请求数据2</button>
</body>
<script>
var cl = console.log.bind(console);
// 1. load(): 加载HTML片段, 即把其他HTML页面文件加载进来, 加载方式: 异步, GET方式加载
$("button:first-of-type").click(function () {
alert(134);
cl(this);
// after()函数: 在当前元素后面增加一个指定元素(作为其兄弟元素),
// 然后获取当前元素的下一个兄弟元素, 在其中加载nav.html文件
$(this).after("<div>").next("div").load("nav.html");
});
// 2. $.get(url, data, callback): 以get的方式从服务器获取资源/数据
$("button:nth-of-type(2)").click(function (event) {
$.get(
"users.php",
// 因为是get请求, 所以, 可以在user.php后面增加?id=2, 也可以给第二个参数入参对象字面量来传递get请求参数
{ id: 2 },
function (data) {
// cl(data);
// 在当前元素后面新增一个div元素, 并把data作为其innerHTML属性值.
$(event.target).after("<div>").next().html(data);
}
);
});
// 3. $.post(url, data, callback): 以post的方式从服务器获取资源/数据, 使用方法跟get很类似
$("button:nth-of-type(3)").click(function (event) {
$.post("users.php", { id: 2 }, function (data) {
// cl(data);
// 在当前元素后面新增一个div元素, 并把data作为其innerHTML属性值.
$(event.target).after("<div>").next().html(data);
});
});
// 4. $.getJSON(url, data, callback): 接口大多返回的是JSON
$("button:nth-of-type(4)").click(function (event) {
$.getJSON("users.php?id=2", function (data) {
/* 跟普通的get请求不同的点: getJSON()方法会自动把返回的字符串转换为JSON对象,
再传入回调函数中, 即, 自动执行var data = JSON.parse(res)语句, 得到的
data是一个JS对象数据. */
// cl(data);
var res = data.id + ":" + data.name + ", " + data.age + "岁";
// 在当前元素后面新增一个div元素, 并把data作为其innerHTML属性值.
$(event.target).after("<div>").next().html(res);
});
});
// 5. $ajax(): 能实现上面2到4的方法, 实际上掌握这个方法即可.
/* 五个常用对象字面量参数:
type: 请求类型, 即: GET, POST
url: 请求的url
data: 发送的数据, 若是GET请求, 数据可以放到url上, 而POST请求必须放到data这里
dataType: 期望服务器返回/相应的数据类型(大部分场景可以自己判断)
success: function(data) {// 回调函数...入参的data是服务器返回的数据}
*/
// 实例:
$("button:nth-of-type(5)").click(function (event) {
// 发送POST请求
$.ajax({
type: "POST",
url: "users.php",
data: { id: 2 },
dataType: "json",
success: function (data) {
alert("success");
cl(data);
},
});
});
// 6. $.ajax()-jsonp-1: 发送跨域请求
/* "http://php.edu/0522/test2.php?jsonp=handle&id=2" */
$("button:nth-of-type(6)").click(function (event) {
// 发送POST请求
$.ajax({
type: "GET",
// jsonp参数指定的是当前脚本中的一个回调函数, 一般不写死, 用?做占位符,
// 请求成功后, 会用success(data)函数来填充?占位符.
url: "http://php.edu/0522/test2.php?jsonp=?&id=2",
// 返回的数据类型是jsonp
dataType: "jsonp",
success: function (data) {
// test2.php返回的是一个JSON字符串
cl(data);
// 转成js对象
var res = JSON.parse(data);
// 输出到页面中, 略
},
});
});
// 7. $.ajax()-jsonp-1: 发送跨域请求
/* "http://php.edu/0522/test2.php?jsonp=handle&id=2" */
$("button:nth-of-type(7)").click(function (event) {
// 发送POST请求
$.ajax({
type: "GET",
// jsonp参数指定的是当前脚本中的一个回调函数, 一般不写死, 用?做占位符,
// 请求成功后, 会用success(data)函数来填充?占位符.
url: "http://php.edu/0522/test2.php?jsonp=?&id=2",
// 返回的数据类型是jsonp
dataType: "jsonp",
// 不想用success(data)来填充?占位的话, 可以用jsonpCallback来指定一个函数, 来填充?占位
jsonpCallback: 'handle',
});
});
function handle(data) {
// test2.php返回的是一个JSON字符串
cl(data);
// 转成js对象
var res = JSON.parse(data);
// 输出到页面中, 略
}
</script>
</html>
2. 使用jQuery操作ajax实现无刷新分页小实战
实现思路:
- 把创建分页元素字符串的脚本封装起来, 根据传入的”当前页”, “总记录数”, “显示的页码个数”来创建分页元素字符串. 再传入一个回调函数作为页码点击事件的处理脚本.
- 处理脚本主要完成:
- 根据”当前页”和”总记录数”两个参数查询分页数据和记录总数
- 拼接查询结果字符串, 作为表格的表体内容, 并插入表格的表体(
<tbody>
元素)
- 拼接查询结果字符串, 作为表格的表体内容, 并插入表格的表体(
- 移除页面上已有的
.pagination
元素, 再插入新创建的分页元素.
- 移除页面上已有的
封装生成分页元素的pagination/pagination.js
var Pagination = {
// 第一页
start: 1,
// 一页可以容纳的记录数
pageSize: 3,
// 显示的页码个数
pageNumSize: 5,
// 显示的页码列表
pageNumList: [],
// 总页数
pageCount: 0,
// 页码左右偏移量
pageNumOffset: 0,
// 当前页码
currentPage: 1,
// 总记录数
rowCount: 0,
// 查询回调
search: "",
getPageInfo: function (pageObj = {}, search = "") {
// 初始化各种属性
// this.currentPage: currentPage;
// this.rowCount = rowCount;
// this.pageSize = pageSize;
// this.pageNumSize = pageNumSize;
$.extend(this, pageObj);
this.pageNumOffset = (this.pageNumSize - 1) / 2;
this.pageCount = Math.ceil(parseFloat(this.rowCount) / this.pageSize);
if (this.pageCount <= 1) {
return "";
}
/* 当传入的当前页码效于最小页码时,初始化为1;大于最大页码时,初始化为最大页码 */
this.currentPage =
this.currentPage < 1
? 1
: this.currentPage > this.pageCount
? this.pageCount
: this.currentPage;
// 回调
if (search != null) this.search = search;
// 计算显示的页码列表
this.getPageNumList();
// 生成分页数据
return this.createPageInfo();
},
getPageNumList: function () {
this.pageNumList = [];
// 如果要显示的页码数量>=总页码数量,则显示所有页码。
if (this.pageCount <= this.pageNumSize) {
for (var i = 1; i <= this.pageCount; i++) {
this.pageNumList.push(i);
}
return;
}
// 起始页码,取“当前页码-页码偏移量”和起始页码的最大值。
pageNumStart =
this.currentPage - this.pageNumOffset < this.start
? this.start
: this.currentPage - this.pageNumOffset;
// 结束页码,取“当前页码+页码偏移量”和总页码数的最小值。
pageNumEnd =
pageNumStart + this.pageNumSize - 1 > this.pageCount
? this.pageCount
: pageNumStart + this.pageNumSize - 1;
// 若结束页码等于总页码,则再计算一次起始页码(避免当前页到结束页码的差值小于页码偏移量的情况)
if (pageNumEnd === this.pageCount) {
// 起始页码,取“最大页码-要显示的页码数量+1”和起始页码的最大值。
pageNumStart =
this.pageCount - this.pageNumSize + 1 < this.start
? this.start
: this.pageCount - this.pageNumSize + 1;
}
// 生成要显示的页码数组
for (var i = pageNumStart; i <= pageNumEnd; i++) {
this.pageNumList.push(i);
}
},
createPageInfo: function () {
var pageHtml = '<div class="pagination">';
pageHtml += '<link rel="stylesheet" href="pagination/pagination.css">';
// 首页
var tmpHtml =
this.currentPage === 1
? '<span class="pageNum disabled">首页</span>'
: '<span class="pageNum" onclick="' +
this.search +
"(1, " +
this.pageNumSize +
')">首页</span>';
pageHtml += tmpHtml;
// 上一页
tmpHtml =
this.currentPage === 1
? '<span class="pageNum disabled">上一页</span>'
: '<span class="pageNum" onclick="' +
this.search +
"("+(this.currentPage - 1)+", " +
this.pageNumSize +
')">上一页</span>';
pageHtml += tmpHtml;
// 间隔符
tmpHtml = this.pageNumList[0] >= 2 ? "..." : "";
pageHtml += tmpHtml;
console.log(this.pageNumList.length);
// 显示的页码
this.pageNumList.forEach((pageNum) => {
tmpHtml =
pageNum == this.currentPage
? '<span class="pageNum active">' + pageNum + "</span>"
: '<span class="pageNum" data-pageNum="' +
pageNum +
'" onclick="' +
this.search +
"(" +
pageNum +
", " +
this.pageNumSize +
')">' +
pageNum +
"</span>";
pageHtml += tmpHtml;
});
// 间隔符
tmpHtml = this.pageNumList[this.pageNumSize - 1] <= this.pageCount - 1 ? "..." : "";
pageHtml += tmpHtml;
// 下一页
tmpHtml =
this.currentPage >= this.pageCount
? '<span class="pageNum disabled">下一页</span>'
: '<span class="pageNum" onclick="' +
this.search +
"(" +
(this.currentPage + 1) +
", " +
this.pageNumSize +
')">下一页</span>';
pageHtml += tmpHtml;
// 末页
tmpHtml =
this.currentPage >= this.pageCount
? '<span class="pageNum disabled">末页</span>'
: '<span class="pageNum" onclick="' +
this.search +
"(" +
this.pageCount +
", " +
this.pageNumSize +
')">末页</span>';
pageHtml += tmpHtml;
pageHtml += "</div>";
return pageHtml;
},
};
前端显示查询分页结果页面player.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>球员列表</title>
<!-- CDN方式引用, 即内容分发方式 -->
<!-- BootCDN或者又拍云的CDN的速度都可以 -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<!-- 本地引用 -->
<script src="pagination/pagination.js"></script>
<style>
table {
border: 0;
min-width: 800px;
margin: 0 auto 30px;
border-spacing: 0px;
}
table caption {
font-size: 1.5rem;
margin-bottom: 20px;
}
table thead tr {
background-color: lightskyblue;
}
table tbody tr:hover {
background-color: lightcyan;
}
table tr td,
th {
border: 1px solid #ccc;
padding: 0 10px;
height: 30px;
color: #666;
}
</style>
</head>
<body>
<table>
<caption>
球员列表
</caption>
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>球队</th>
<th>身高(cm)</th>
<th>体重(kg)</th>
<th>位置</th>
<th>创建时间</th>
<th>修改时间</th>
</tr>
</thead>
<tbody>
<!-- 将插入球员列表 -->
</tbody>
</table>
</body>
<script>
// 获取球员分页数据
function playerList(pageNum = 1, pageSize = 5) {
$.ajax({
type: "POST",
url: "player.php",
data: {
pageNum: pageNum,
pagSize: pageSize,
},
dataType: "json",
success: function (res) {
// 查询成功
if (res.status == "1") {
// 渲染分页球员数据
var dataStr = renderData(res.data.pageData, res.data.count);
$("tbody").html(dataStr);
// 获取分页元素字符串
var paginate = Pagination.getPageInfo(
{
currentPage: pageNum,
pageSize: pageSize,
// pageNumSize: pageSize,
rowCount: parseInt(res.data.count),
},
"playerList"
);
// 若页面中已存在分页元素, 则删除之
var $pagination = $('.pagination');
if($pagination.length > 0)
$pagination.parent().get(0).removeChild($pagination.get(0));
// 转换并插入最新生成的分页元素
$("body").append($(paginate));
}
},
});
}
// 渲染数据
function renderData(pageData, count) {
// var players = res.data.pageData;
// var count = res.data.count;
if (pageData.length > 0) {
var playerStr = "";
pageData.forEach((element) => {
playerStr += "<tr>";
playerStr += "<td>" + element.id + "</td>";
playerStr += "<td>" + element.name + "</td>";
playerStr += "<td>" + element.team + "</td>";
playerStr += "<td>" + element.height + "</td>";
playerStr += "<td>" + element.weight + "</td>";
playerStr += "<td>" + element.position + "</td>";
playerStr += "<td>" + element.create_time + "</td>";
playerStr += "<td>" + element.update_time + "</td>";
playerStr += "</tr>";
});
} else {
return '<tr><td colspan="8">啥也没查到...</td></tr>';
}
return playerStr;
}
// run~~!!!
playerList();
</script>
</html>
运行效果图:
3. 学习心得
- jQuery操作ajax, 简化了代码, 但是也隐藏了很多细节, 需要对比原生ajax请求来加深记忆.
- 无刷新分页的小实战, 是强迫自己以面向对象的思想, 封装分页拼装细节, 但是感觉还是把过程封装而已, 可复用性不强, 还需要加强自己的抽象总结能力.