主要内容:
- jQuery事件绑定
- 7种获得获得数据的方式,包括Ajax
- 实战:Ajax-post无刷新分页技术
1. jQuery事件绑定
- 通过事件绑定来进行匹对检验、提醒、提醒去除等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>事件</title>
</head>
<body>
<p>User Login:</p>
<!-- onsubmit="return false": 禁用表单的默认提交行为 -->
<form style="width: 200px; display: grid; gap: 10px;">
<input type="text" placeholder="UserName" autofocus />
<input type="password" placeholder="Password" />
<button>Submit</button>
</form>
<script src="../220818/lib/jquery-3.5.1.js"></script>
<script>
// 事件绑定,绑定一个禁用当前默认操作的事件
$("form").submit(function (ev) {
ev.preventDefault();
});
// 用户名文本框应该是失去焦点的进行验证
var user = $('input[type="text"]');
// blur()失去焦点时触发
user.blur(function () {
// 提示
var tips = "";
// 用户名列表 - 这个按理是跟数据库中的比较的
var users = ["admin", "peter", "zhu"];
// 非空验证
if ($(this).val().length === 0) {
tips = "用户名不能为空";
// 焦点重新定位到用户名文本框上
$(this).focus();
// 存在验证,必须在非空验证完成之后才可进行,如果在列表中没有,index就会是-1
} else if (users.indexOf($(this).val()) === -1) {
tips = "用户名不存在" + ' <button type="button">请注册</button>';
} else {
tips = '<i style="color:green;">用户名正确<i>';
$("input[type=password]").focus();
}
// 将提示信息添加到页面
// 防止重复添加 - 因此需要现有一个检查,如果没有再添加
// 一旦重新的时候,需要再将信息(span)删除掉
if ($(this).next().get(0).tagName !== "SPAN") {
$("<span>").html(tips).css("color", "red").insertAfter($(this));
}
// 如果输入错误,用户修改的时候,应该将提示信息删除
// keyDown(): 当用户按下键盘时触发
// user.keydown(function () {
// // remove()删除元素
// // next():获取下一个兄弟元素
// $(this).next("span").remove();
// });
// on(): 与原生 addEventListener()功能一样
user.on("input", function () {
$(this).next("span").remove();
});
});
</script>
</body>
</html>
2. 7种获得获得数据的方式,包括Ajax
- 中间用到的一个users.php
<?php
// 二维数组模拟数据表的查询结果
$users = [
['id' => 1, 'name' => '熊大', 'age' => 20],
['id' => 2, 'name' => '熊二', 'age' => 18],
['id' => 3, 'name' => '光头强', 'age' => 38],
];
// $_REQUEST = $_GET + $_POST + $_COOKIE
// $id = intval($_REQUEST['id']);
if (in_array($_REQUEST['id'], array_column($users, 'id'))) {
foreach ($users as $user) {
if ($user['id'] == $_REQUEST['id'] ) {
// vprintf('%s : %s %s 岁', $user);
// 除了json部分用下面这个外,其他都用上面的
// $_getJSON()返回返回json格式字符串
echo json_encode($user);
}
}
} else {
echo '<span style="color: red">没有找到</span>';
}
- demo2.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ajax</title>
<style>
body {
display: grid;
gap: 15px;
}
button {
text-align: left;
height: 26px;
width: 250px;
background-color: aquamarine;
}
button:hover {
background-color: #ddd;
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>
<script src="../220818/lib/jquery-3.5.1.js"></script>
<script>
// 1. $.load():获取html片断
$("button:first-of-type").click(function () {
$(this).after("<div>").next().load("nav.html");
});
// 将nva中的导航load过来
// 2. $.get()
$("button:nth-of-type(2)").click(function (ev) {
// http://php.cn/users.php?id=2
// 与之前的data: xhr.responseText有类似的功能,可以祛暑
$.get("users.php", { id: 3 }, function (data) {
console.log(data);
// console.log($(this)[0]);
console.log($(this) === $(ev.target));
// 这个地方的this跟后面不等,因为从上面一行可以看出来this好像是一个字符串之类。
$(ev.target).after("<div>").next().html(data);
});
});
// 3. $.post()
$("button:nth-of-type(3)").click(function (ev) {
$.post("users.php", { id: 7 }, function (data) {
// console.log(data);
$(ev.target).after("<div>").next().html(data);
});
});
// 4. $.getJSON()
$("button:nth-of-type(4)").click(function (ev) {
$.getJSON("users.php?id=3", function (data) {
// var data = JSON.parse(data);这步操作Jquery代劳了
// 我们操作的data已经是js对象
console.log(data);
var str = data.id + ": " + data.name + ", " + data.age + "岁";
$(ev.target).after("<div>").next().html(str);
});
});
// 5. $.ajax():终级杀器,只要掌握这一个就可以了
// $.ajax({
// // 请求类型
// type: "GET",
// // 请求的URL
// url: url,
// // 发送的数据
// data: data,
// // 希望服务器返回的类型
// dataType: "json",
// // 请求成功的回调
// success: callback,
// });
$("button:nth-of-type(5)").click(function (ev) {
// $.get("users.php", { id: 2 }, function (data) {
// console.log(data);
// // console.log($(this)[0]);
// console.log($(this) === $(ev.target));
// $(ev.target).after("<div>").next().html(data);
// });
$.ajax({
type: "GET",
url: "users.php",
data: { id: 2 },
dataType: "html",
success: function (data) {
console.log(data);
$(ev.target).after("<div>").next().html(data);
},
});
});
// 6. $.ajax() - jsonp - 1
$("button:nth-of-type(6)").click(function (ev) {
$.ajax({
type: "get",
// jsonp=? ?是回调函数的占位符
url: "http://php.io/test2.php?jsonp=?&id=1",
// dataType: 返回类型必须是jsonp
dataType: "jsonp",
success: function (data) {
var data = JSON.parse(data);
console.log(data);
},
});
});
// 7. $.ajax() - jsonp - 2
$("button:last-of-type").click(function (ev) {
$.ajax({
type: "get",
// jsonp=? ?是回调函数的占位符
url: "http://php.io/test2.php?jsonp=?&id=1",
// dataType: 返回类型必须是jsonp
dataType: "jsonp",
jsonpCallback: "handle",
});
});
function handle(data) {
var data = JSON.parse(data);
console.log(data);
var data =
"<p>" +
data.title +
"</p><p>" +
data.user.name +
",邮箱:" +
data.user.email +
"</p>";
$("button:last-of-type").after("<div>").next().html(data);
}
</script>
</body>
</html>
3. Ajax-post无刷新分页技术
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ajax-post无刷新分页技术</title>
<style>
table {
border-collapse: collapse;
border: 1px solid;
text-align: center;
margin: auto;
width: 500px;
}
table caption {
font-size: 1.2rem;
margin-bottom: 10px;
}
th,
td {
border: 1px solid;
padding: 5px;
}
thead tr:first-of-type {
background-color: #ddd;
}
p {
text-align: center;
}
p a {
text-decoration: none;
border: 1px solid;
padding: 0 8px;
}
.active {
background-color: #f00;
}
</style>
</head>
<body>
<table>
<caption>
用户信息表
</caption>
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>职位</th>
<th>手机号</th>
</tr>
</thead>
<tbody></tbody>
</table>
<!-- 分页条 -->
<p></p>
<script src="../0818/lib/jquery-3.5.1.js"></script>
<script>
// 默认是第一页
var page = 1;
// 默认显示的是第一页
getPageData(page);
// 获取分页数据的函数
function getPageData(page) {
$.ajax({
type: "post",
url: "page_data.php",
data: { page: page },
dataType: "json",
success: show,
});
}
// show()显示数据
function show(data) {
console.log(data);
// 将json中的数据解析出来填充到表格中
console.log(data.users);
// 1. 将当前面的数据渲染出来
var str = "";
data.users.forEach(function (user) {
str += "<tr>";
str += "<td>" + user.id + "</td>";
str += "<td>" + user.name + "</td>";
str += "<td>" + user.age + "</td>";
str += "<td>" + user.sex + "</td>";
str += "<td>" + user.position + "</td>";
str += "<td>" + user.mobile + "</td>";
str += "</tr>";
});
$("tbody").html(str);
// 2. 将分页条显示出来
var str = "";
for (var i = 1; i < data.pages; i++) {
str += '<a href="" data-index=' + i + ">" + i + "</a>";
}
$("p").html(str).find("a").first().addClass("active");
// 3. 添加分页点击事件
$("p a").click(function (ev) {
ev.preventDefault();
// 获取当前要显示的新页面,根据自定义属性
var page = $(this).attr("data-index");
// $("tbody").html("");
getPageData(page);
});
}
</script>
</body>
</html>
- page_data.php
<?php
// 1. 连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=liangtest', 'liang', '123456');
// 2. 获取页码
$page = $_POST['page'] ?? 1;
// 3. 每页显示数量
$num = 8;
// 4. 每页显示偏移量
$offset = ($page - 1) * $num;
// 5. 总页数
$sql = "SELECT CEIL(COUNT(`id`)/{$num}) AS `total` FROM `shao`";
// echo $sql;
$pages = $pdo->query($sql)->fetch()['total'];
// echo $pages;
// 6. 分页数据
$sql = "SELECT * FROM `shao` LIMIT {$num} OFFSET {$offset}";
$users = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
// ajax分页数据一定是返回二部分
// 1. 总页数, 提供给前端自动生成分页条
// 2. 分页数据
echo json_encode(['pages' => $pages, 'users' => $users]);
die;
4. 作业,实现高亮跟着点击走
将无刷新分页案例,添加当前页码高亮的功能
- 数据库连接操作的php文件
<?php
// 1. 连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=liangtest', 'liang', '123456');
// 2. 获取页码
$page = $_POST['page2'] ?? 1;
// 3. 每页显示数量
$num = 8;
// 4. 每页显示偏移量
$offset = ($page - 1) * $num;
// 5. 总页数
$sql = "SELECT CEIL(COUNT(`id`)/{$num}) AS `total` FROM `shao`";
// echo $sql;
$pages = $pdo->query($sql)->fetch()['total'];
// echo $pages;
// 6. 分页数据
$sql = "SELECT * FROM `shao` LIMIT {$num} OFFSET {$offset}";
$users = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
// ajax分页数据一定是返回二部分
// 1. 总页数, 提供给前端自动生成分页条
// 2. 分页数据
echo json_encode(['pages' => $pages, 'users' => $users]);
die;
- 前端的html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ajax-post无刷新分页技术</title>
<style>
table {
border-collapse: collapse;
border: 1px solid;
text-align: center;
margin: auto;
width: 500px;
}
table caption {
font-size: 1.2rem;
margin-bottom: 10px;
}
th,
td {
border: 1px solid;
padding: 5px;
}
thead tr:first-of-type {
background-color: #ddd;
}
p {
text-align: center;
}
p a {
text-decoration: none;
border: 1px solid;
padding: 0 8px;
}
.active {
background-color: #f00;
}
</style>
</head>
<body>
<table>
<caption>
用户信息表
</caption>
<thead>
<tr>
<th>id</th>
<th>date</th>
<th>title</th>
<th>label</th>
<th>others</th>
</tr>
</thead>
<tbody></tbody>
</table>
<!-- 分页条 -->
<p></p>
<script src="../220818/lib/jquery-3.5.1.js"></script>
<script>
// 默认是第一页
var page1 = 1;
getData(page1);
// 获取分页数据的函数
function getData(page1) {
$.ajax({
type: "post",
url: "my.php",
data: {page2: page1},
// 关键:这个地方的page1发送到php sever那边的。
// page1其实是一个数值,需要通过前面的page2过去。
// page2必须跟php文件中的$_post后面的变量保持一致
dataType: "json",
success: dataShow,
});
}
// dataShow()显示数据
function dataShow(data1) {
console.log(data1.pages);
console.log(data1.users);
var str = "";
data1.users.forEach(function (user) {
str += "<tr>";
str += "<td>" + user.id + "</td>";
str += "<td>" + user.date + "</td>";
str += "<td>" + user.title + "</td>";
str += "<td>" + user.label + "</td>";
str += "<td>" + user.others + "</td>";
str += "</tr>";
});
$("tbody").html(str);
}
// 2. 将分页条显示出来(这部分原来是在上面的dataShow函数中的,自己拿出来了)
// 但问题来了?????? 这个时候就无法用data1.pages了。后面需要看下function中的变量如何拿出来用。
var str = "";
for (var i=1; i <= 22; i++){
str += '<a href="" data-index=' + i + '>' + i + '</a>';
// $('p').html(str).find("a").eq(page1-1).addClass('active');
$('p').html(str).find("a").first().addClass('active');
}
// 3. 添加分页点击事件(这部分同样原来是在上面的dataShow函数中的,自己拿出来了)
// 拿出来的的原因是下面的getData本来就是调用dataShow的,结果dataShow里面又调取getData,感觉是一个死循环
// 刚开始老师的first高亮一直去不掉原因也是这个。
$("p a").click(function (ev) {
ev.preventDefault();
page1 = $(ev.target).attr("data-index");
getData(page1);
$("p a").removeClass("active");
$(ev.target).addClass("active");
});
</script>
</body>
</html>