一.注册页
需求:
1.四个验证
2.除了密码可以与数据库的密码相同,其它的相同都要返回已注册
3.验证通过才能注册
4…验证通过,信息交往数据库
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/cookie.js"></script>
<script src="../js/ajax.js"></script>
<script src="../js/api.js"></script>
</head>
<body>
<p>用户名<input type="text"><span></span></p>
<p>密 码<input type="password"><span></span></p>
<p>电 话<input type="text"><span></span></p>
<p>邮 箱<input type="text"><span></span></p>
<p>   <button>注册</button>  <input type="reset"></p>
</body>
<script>
var inputList = document.querySelectorAll("input");
var spanList = document.querySelectorAll("span");
var btn = document.querySelector("button");
// 假设法
var userFlag = false;
var pwdFlag = false;
var phoneFlag = false;
var emailFlag = false;
// 用户名验证
inputList[0].onblur = function () {
// 失焦重置
userFlag = false;
// 正则规范
var reg = /^[a-zA-Z_$][\w$]{5,11}$/;
var user = inputList[0].value;
if (reg.test(user)) {
// ajax请求
register({ user }).then(result => {
var { status, detail } = result;
if (status) {
spanList[0].innerHTML = "√";
spanList[0].style.color = 'green';
userFlag = true;
} else {
spanList[0].innerHTML = detail;
spanList[0].style.color = 'red';
}
}).catch(err => {
console.log(err);
})
} else {
spanList[0].innerHTML = "用户名输入不规范";
spanList[0].style.color = 'red';
}
}
// 密码验证
inputList[1].onblur = function () {
// 失焦重置
pwdFlag = false;
// 正则规范
var reg = /^[\w$]{6,12}$/;
var pwd = inputList[1].value;
if (reg.test(pwd)) {
// 假设
var numFlag = false;
var smallFlag = false;
var bigFlag = false;
var speFlag = false;
// 正则规范
var numReg = /[0-9]/;
var smallReg = /[a-z]/;
var bigReg = /[A-Z]/;
var speReg = /[_$]/;
// 验证正确,flag成立
if (numReg.test(pwd)) {
numFlag = true;
}
if (smallReg.test(pwd)) {
smallFlag = true;
}
if (bigReg.test(pwd)) {
bigFlag = true;
}
if (speReg.test(pwd)) {
speFlag = true;
}
var sum = numFlag + smallFlag + bigFlag + speFlag;
spanList[1].innerHTML = "密码强度为:" + sum;
spanList[1].style.color = 'green';
pwdFlag = true;
} else {
spanList[1].innerHTML = "密码输入不规范";
spanList[1].style.color = 'red';
}
}
// 电话验证
inputList[2].onblur = function () {
// 失焦重置
phoneFlag = false;
// 正则规范
var reg = /^1[3-9]\d{9}$/;
var phone = inputList[2].value;
if (reg.test(phone)) {
// ajax请求
register({ phone }).then(result => {
var { status, detail } = result;
if (status) {
spanList[2].innerHTML = "√";
spanList[2].style.color = 'green';
phoneFlag = true;
} else {
spanList[2].innerHTML = detail;
spanList[2].style.color = 'red';
}
}).catch(err => {
console.log(err);
})
} else {
spanList[2].innerHTML = "电话输入不规范";
spanList[2].style.color = 'red';
}
}
// 邮箱验证
inputList[3].onblur = function () {
// 失焦重置
emailFlag = false;
// 正则规范
var reg = /^\w{6,18}@\w+\.com$/;
var email = inputList[3].value;
if (reg.test(email)) {
// ajax请求
register({ email }).then(result => {
var { status, detail } = result;
if (status) {
spanList[3].innerHTML = "√";
spanList[3].style.color = 'green';
emailFlag = true;
} else {
spanList[3].innerHTML = detail;
spanList[3].style.color = 'red';
}
}).catch(err => {
console.log(err);
})
} else {
spanList[3].innerHTML = "邮箱输入不规范";
spanList[3].style.color = 'red';
}
}
// 点击注册
btn.onclick = function () {
console.log(userFlag, pwdFlag, phoneFlag, emailFlag);
if (userFlag && pwdFlag && phoneFlag && emailFlag) {
// 获取去空格的value
var user = inputList[0].value.trim();
var pwd = inputList[1].value.trim();
var phone = inputList[2].value.trim();
var email = inputList[3].value.trim();
// ajax请求
insert({ user, pwd, phone, email }).then(result => {
var { status, detail } = result;
if (status) {
location.href = "login.html";
} else {
alert("注册数据有误!!!")
}
}).catch(err => {
console.log(err);
})
} else {
alert("注册信息不全!!!")
}
}
</script>
</html>
需要的接口:
1.链接数据库的接口
2.报错和查询数据库判断注册信息的接口
3.注册接口,前端传了什么值就验证什么
4.注册成功插入数据库的接口
二.登录页
需求:
1.链接数据库对照用户输入的用户名和密码,都正确登录成功
2.默认情况下用户登录后,直到浏览器关闭为止,cookie上都要留有痕迹,用户选择记住用户则需要设置cookie留存时间,一般是一个月。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/cookie.js"></script>
<script src="../js/ajax.js"></script>
<script src="../js/api.js"></script>
</head>
<body>
<p>用户名<input type="text"><span></span></p>
<p>密 码<input type="password"><span></span></p>
<p><input type="checkbox">是否记住此用户?</p>
<p><button>登录</button></p>
</body>
<script>
var inputList = document.querySelectorAll("input");
var spanList = document.querySelectorAll("span");
var btn = document.querySelector("button");
// 点击登录
btn.onclick = function () {
// 获取value
var user = inputList[0].value;
var pwd = inputList[1].value;
var check = inputList[2];
if (user && pwd) {
// ajax请求
login({ account: user, pwd }).then(result => {
var { status, detail, user } = result;
if (status) {
if (check.checked) {
setCookie("lgc", user, 30);
} else {
setCookie("lgc", user);
}
console.log("登录成功");
location.href = "index1.html";
} else {
alert(detail);
}
})
}
}
</script>
</html>
需要的接口:
多账户查询的接口
三.主页
需求:
1.取出cookie显示用户名在页面上
2.链接数据库,渲染页面
3.搜索,输入框的关键字传入后端链接数据库模糊查询,解析出的结果渲染到页面上
4.列名排序,升序,降序和下拉框限制每页数据,都是点击时把value值赋给对应的全局变量,再根据数据库解析的结果重新渲染页面。
5.分页效果,显示提示页码和最大页码,根据用户选择的每页数据量裁切数据,最后渲染页面。
6.上下翻页,页码临界值时限流,点击++/–,每点一下重新渲染页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="../css/index.css">
<link rel="stylesheet" href="../css/search.css">
<script src="../js/cookie.js"></script>
<script src="../js/ajax.js"></script>
<script src="../js/api.js"></script>
</head>
<body>
<div class="mark">
<a href="register.html">注册</a>
<a href="login.html">登录</a>
</div>
<div class="wrapAll w">
<form class="search_bar" onsubmit="return false">
<div class="searchBox">
<input type="text" class="searchCon">
<button class="searchBtn">搜索</button>
</div>
<div class="orderBox">
<!-- 排序的列(column)名 (id,chinese,math,english,total) -->
<div class="orderColBox">
<label>
学号
<input type="radio" checked name="orderCol" class="orderCol" value="id">
</label>
<label>
语文
<input type="radio" name="orderCol" class="orderCol" value="chinese">
</label>
<label>
数学
<input type="radio" name="orderCol" class="orderCol" value="math">
</label>
<label>
英语
<input type="radio" name="orderCol" class="orderCol" value="english">
</label>
<label>
总分
<input type="radio" name="orderCol" class="orderCol" value="total">
</label>
</div>
<!-- 排序的类型 升序 / 降序 -->
<div class="orderTypeBox">
<label>
升序
<input type="radio" checked name="orderType" class="orderType" value="asc">
</label>
<label>
降序
<input type="radio" name="orderType" class="orderType" value="desc">
</label>
</div>
<div class="showNumBox">
<select class="select">
<option value="5" selected>每页显示05条</option>
<option value="10">每页显示10条</option>
<option value="15">每页显示15条</option>
<option value="20">每页显示20条</option>
</select>
</div>
<input type="reset" class="resetBtn" value="重置">
</div>
</form>
<div class="wrapTable">
<table>
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>班级</th>
<th>语文</th>
<th>数学</th>
<th>英语</th>
<th>总分</th>
<th>编辑</th>
<th>删除</th>
</tr>
</thead>
<tbody class="tbody">
<!-- <tr>
<td>01</td>
<td>02</td>
<td>03</td>
<td>04</td>
<td>05</td>
<td>06</td>
<td>07</td>
<td>08</td>
<td>09</td>
</tr> -->
</tbody>
</table>
</div>
<div class="pageBox">
<button class="prev">上一页</button>
<span class="pageTips"></span>
<button class="next">下一页</button>
</div>
</div>
<div class="shadow">
<form class="detail" action="" autocomplete="off" onsubmit="return false">
<p><label>编号:<input type="text" name="id" disabled></label></p>
<p><label>姓名:<input type="text" name="NAME" disabled></label></p>
<p><label>班级:<input type="text" name="class" disabled></label></p>
<p><label>语文:<input type="text" name="chinese"></label></p>
<p><label>数学:<input type="text" name="math"></label></p>
<p><label>英语:<input type="text" name="english"></label></p>
<p><button class="subBtn">确定</button><button class="canBtn">取消</button></p>
</form>
</div>
</body>
<script>
var mark = document.querySelector(".mark");
var tbody = document.querySelector(".tbody");
var shadow = document.querySelector(".shadow");
var form = document.getElementsByClassName("detail")[0];
var subBtn = document.querySelector(".subBtn");
var canBtn = document.querySelector(".canBtn");
var searchBtn = document.querySelector(".searchBtn");
var searchCon = document.querySelector(".searchCon");
var orderCols = document.querySelectorAll(".orderCol");
var orderTypes = document.querySelectorAll(".orderType");
var pageTips = document.querySelector(".pageTips");
var select = document.querySelector(".select");
var prev = document.querySelector(".prev");
var next = document.querySelector(".next");
var key = ""; // 声明全局变量 记录搜索的关键词
var orderCol = "id"; // 声明全局变量 记录排序的列名 (id,chinese )
var orderType = "asc"; // 声明全局变量 记录排序的方式 (asc desc)
var showNum = 5; // 声明全局变量 默认每页显示多少数据
var pageIndex = 1; // 声明全局变量 默认页码
// 获取cookie
var cookie = document.cookie;
if (cookie) {
// 再从cookie中获取用户名
var user = getCookie("lgc")
if (user) {
mark.innerHTML = "欢迎您," + user + "<button οnclick='exit()'>退出</button>"
}
}
// 页面加载完毕,先渲染一遍表格
update();
// 搜索
searchBtn.onclick = function () {
// 搜索框赋值
key = searchCon.value.trim();
// 根据前端的传入的关键词重新渲染表格
update();
}
// 按列名排序
orderCols.forEach(function (item) {
item.onclick = function () {
// 单选框赋值
orderCol = this.value;
update();
}
})
// 升序,降序
orderTypes.forEach(function (item) {
console.log(item);
item.onclick = function () {
// 单选框赋值
orderType = this.value;
console.log(this);
update();
}
})
// 下拉框显示每页数据
select.onchange = function () {
showNum = this.value;
console.log(showNum);
update();
}
// 事件委托给tbody
tbody.onclick = function (e) {
var e = e || window.event;
var target = e.target || e.srcElement;
// 删除
if (target.className == "delete") {
var tr = target.parentElement.parentElement;
console.log(tr);
var id = tr.getAttribute("data-id");
console.log(id);
if (confirm("是否删除该数据?")) {
// ajax请求
deleteGrade({ id }).then(result => {
var { status, detail } = result;
if (status) {
tr.remove();
update();
} else {
alert(detail);
}
}).catch(err => {
console.log(err);
})
}
}
// 编辑
else if (target.className == "edit") {
shadow.style.display = "block";
var tr = target.parentElement.parentElement;
var id = tr.getAttribute("data-id");
// 根据id查询数据
searchGradeById({ id }).then(result => {
var { status, detail, data } = result;
if (status) {
console.log(form);
form.id.value = data.id;
form.NAME.value = data.NAME;
form.class.value = data.class;
form.chinese.value = data.chinese;
form.math.value = data.math;
form.english.value = data.english;
// for in遍历数据
// for (var key in data) { // key = 'id'/'name'/class
// key.toLowerCase();
// form[key].value = data[key];
// }
} else {
alert(detail);
}
}).catch(err => {
console.log(err);
})
}
}
// 取消
canBtn.onclick = function () {
shadow.style.display = "none";
}
// 确定
subBtn.onclick = function () {
var id = form.id.value;
var chinese = form.chinese.value;
var math = form.math.value;
var english = form.english.value;
console.log(id);
// 根据id查询数据
updateGradeById({ id, chinese, math, english }).then(result => {
var { status, detail, data } = result;
if (status) {
shadow.style.display = "none";
update();
} else {
alert(detail);
}
}).catch(err => {
console.log(err);
})
}
function update() {
// ajax请求数据
searchAllGradesOrder({ key, orderCol, orderType }).then(result => {
var list = result;
console.log(list); // list 总的数据
// 最大页码
var maxPage = Math.ceil(list.length / showNum);
console.log(maxPage);
// 显示页码
pageIndex = pageIndex > maxPage ? maxPage : pageIndex;
// 提示 裁切 渲染
tcx(maxPage, list);
// 下翻页
next.onclick = function () {
// 当显示页码大于最大页码,结束点击事件
if (pageIndex >= maxPage) {
return false;
}
pageIndex++;
tcx(maxPage, list);
}
// 上翻页
prev.onclick = function () {
// 当显示页码小于最小页码,结束点击事件
if (pageIndex <= 1) {
return false;
}
pageIndex--;
tcx(maxPage, list);
}
}).catch(err => {
console.log(err);
})
}
function tcx(maxPage, list) {
// 提示
pageTips.innerHTML = `${pageIndex} / ${maxPage}`;
// 每页数据的裁切 slice(indexStart, indexEnd)(0,4)
var subList = list.slice((pageIndex - 1) * showNum, pageIndex * showNum);
var html = "";
// 遍历总数据,渲染到表格中
subList.forEach(function ({ id, NAME, class: _class, chinese, math, english, total }) {
html += `
<tr data-id="${id}">
<td>${id}</td>
<td>${NAME}</td>
<td>${_class * 1}</td>
<td>${chinese * 1}</td>
<td>${math * 1}</td>
<td>${english * 1}</td>
<td>${(total * 1).toFixed(1)}</td>
<td><a href="javascript:;" class="edit">编辑</a></td>
<td><a href="javascript:;" class="delete">删除</a></td>
</tr>
`
})
tbody.innerHTML = html;
}
function exit() {
delCookie("lgc");
location.reload();
}
/*
*/
</script>
</html>
后端分页区别于前端的渲染函数:
function update() {
// ajax请求数据
searchGradeOrderLimit({ key, orderCol, orderType, pageIndex, showNum }).then(result => {
var { status, detail, count, maxPage, list } = result;
if (status) {
// 显示页码
pageTips.innerHTML = `${pageIndex} / ${maxPage}`;
// 根据前端传入的页码和每页显示的数据量,后端做出裁切($pageIndex - 1) * $showNum
var html = "";
// 遍历总数据,渲染到表格中
list.forEach(function ({ id, NAME, class: _class, chinese, math, english, total }) {
html += `
<tr data-id="${id}">
<td>${id}</td>
<td>${NAME}</td>
<td>${_class * 1}</td>
<td>${chinese * 1}</td>
<td>${math * 1}</td>
<td>${english * 1}</td>
<td>${(total * 1).toFixed(1)}</td>
<td><a href="javascript:;" class="edit">编辑</a></td>
<td><a href="javascript:;" class="delete">删除</a></td>
</tr>
`
})
tbody.innerHTML = html;
// 下翻页
next.onclick = function () {
// 当显示页码大于最大页码,结束点击事件
if (pageIndex >= maxPage) {
return false;
}
pageIndex++;
update();
}
// 上翻页
prev.onclick = function () {
// 当显示页码小于最小页码,结束点击事件
if (pageIndex <= 1) {
return false;
}
pageIndex--;
update();
}
}
}).catch(err => {
console.log(err);
})
}
需要的接口:
1.删除接口
2.根据id查询数据的接口
3.根据id更新数据的接口
4.前端/后端搜索,排序和限制页数的接口