十六、其他事件&正则表达式
1. 阻止事件冒泡
默认情况下,触发子元素的事件时,会同时触发父元素相同的事件,这就叫做事件冒泡
e.stopPropagation()=> 阻止事件冒泡 e.preventDefault()=>取消默认行为
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>阻止事件冒泡</title>
<style>
.one{
width: 200px;
height: 200px;
background-color: lightcoral;
}
.two{
width: 100px;
height: 100px;
background-color: lightblue;
}
</style>
</head>
<body>
<div class="one">
<div class="two"></div>
</div>
<script>
let one = document.querySelector('.one')
// one的点击事件
one.onclick = function(){
console.log('点击1');
}
// one的右键事件
one.oncontextmenu = function(e){
// 取消默认行为
e.preventDefault();
console.log('右击');
}
let two = document.querySelector('.two')
// two的点击事件
two.onclick = function(e){
// 阻止事件冒泡
e.stopPropagation();
console.log('点击2');
}
</script>
</body>
</html>
2. 添加事件的几种方式
1.在元素中通过onXXX定义事件,指定一个事件方法
2.先获取元素,再给元素绑定事件
3.通过addEventListener方法,给元素注册事件,传递两个参数:事件名和事件方法
4.通过removeEventListener方法,移除指定的事件方法,传递两个参数:事件名和事件方法
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>定义事件的三种方式</title>
<style>
#box {
width: 150px;
height: 150px;
border: 1px solid #ccc;
text-align: center;
line-height: 150px;
}
</style>
</head>
<body>
<button id="btn1">按钮1</button>
<!-- 定义事件的第二种方式:直接在元素身上通过onXXX属性指定事件方法 -->
<button id="btn2" onclick="btn2Click()">按钮2</button>
<hr>
<button id="btn3">添加功能1</button>
<button id="btn4">添加功能2</button>
<button id="btn5">添加功能3</button>
<button id="btn6">添加功能4</button>
<div id="box">大家好</div>
<button id="btn7">移除功能1</button>
<button id="btn8">移除功能2</button>
<button id="btn9">移除功能3</button>
<button id="btn10">移除功能4</button>
<script>
// 定义事件的一种方式:先获取元素,再给元素绑定事件
//获取元素
let btn1 = document.querySelector('#btn1')
//给元素绑定点击事件
btn1.onclick = function () {
console.log('大家好!我是按钮1');
}
function btn2Click() {
console.log('大家好!我是按钮2');
}
//获取box元素
let box = document.querySelector('#box')
//方法1
function fun1() {
console.log('执行方法1');
}
//方法2
function fun2() {
console.log('执行方法2');
}
//方法3
function fun3() {
console.log('执行方法3');
}
//方法4
function fun4() {
console.log('执行方法4');
}
//btn3按钮点击事件
btn3.onclick = function () {
// 定义事件的第三种方式:通过addEventListener()方法,添加事件监听。
// 这种方式的好处是,可以给同一个事件,添加多个事件方法。
box.addEventListener("click", fun1)
}
// 注意:如果要通过id选择器获取dom元素,可以直接根据id的名称获取元素。
// btn4按钮点击事件
btn4.onclick = function () {
box.addEventListener("click", fun2)
}
btn5.onclick = function () {
box.addEventListener("click", fun3)
}
btn6.onclick = function () {
box.addEventListener("click", fun4)
}
// 下面的点击事件,移除box的注册的事件
btn7.onclick = function(){
box.removeEventListener("click",fun1)
}
btn8.onclick = function(){
box.removeEventListener("click",fun2)
}
btn9.onclick = function(){
box.removeEventListener("click",fun3)
}
btn10.onclick = function(){
box.removeEventListener("click",fun4)
}
</script>
</body>
</html>
3. 页面的加载事件
1.window.onload页面加载事件
页面的加载事件,该事件会在页面中的所有内容都加载完毕后执行
注意:所有内容包括:标签结构,样式文件,图片文件,音频文件,视频文件...,如果网页内容过大,会导致该事件延迟执行
window.onload = function(){
alert('页面加载完成!')
}
2.DOMContentLoaded页面加载事件
只要页面中的DOM结构加载完毕后,就会立即执行
注意:该事件只能采用事件监听的方式添加,没有提供快捷方式
window.addEventListener('DOMContentLoaded',function(){
alert('页面结构加载完毕!')
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面加载事件</title>
</head>
<body>
<div>大家好!我是一个div</div>
<img id="img" src="https://img2.baidu.com/it/u=4235935096,1956031839&fm=26&fmt=auto">
<script>
// 页面加载事件,在页面中的所有的内容都加载完成后执行
// 注意:所有内容,包括:标签,文本,图片,视频,音频等等...
// 如果当前网页过大,那么该事件的执行会滞后。
window.onload = function(){
console.log('页面所有内容加载完成');
}
// DOMContentLoaded事件,在页面的DOM结构加载完成时,就立刻执行
// 注意:该事件必须要通过事件监听的方式添加,没有提供快捷方式。
window.addEventListener('DOMContentLoaded',function(){
console.log('页面DOM结构加载完成');
//给图片绑定点击事件
img.onclick = function(){
this.src = "https://img1.baidu.com/it/u=3832110760,1678331516&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=500"
}
})
</script>
</body>
</html>
4.正则表达式
正则表达式:其实就是一种匹配规则,用于检索字符串
定义正则表达式的两种方式:1.直接定义 2.构造函数定义
// 1.直接定义
let reg1 = /abc/
// 2.构造函数定义
let reg2 = new RegExp('abc')
let str = '欢迎学习abc正则表达式'
// test()方法,用于检查一个字符串中,是否有满足匹配规则的字符串。
console.log(reg1.test(str));
// 其实用字符串自己的includes()方法,也能解决上面的问题
console.log(str.includes('abc'));
1. 通配符
\w表示:字母、数字、下划线
\W 表示:除了字母、数字、下划线以外的字符
\d表示:数字
\D表示:非数字
^ 表示:以^符号后面的第一个字符开头
$表示:以表示:以符号前面的第一个字符结尾
{n}表示:重复n次
{n,m}表示:重复n到m次
[xyz]表示:其中任意一个字符
+ 表示:重复前一项1次或多次 等价于 {1,}
* 表示:重复前一项0次或多次 等价于 {0,}
?表示:重复前一项0次或1次 等价于 {0,1}
. 表示:除了换行符以外的任意一个字符
\. 表示:. \^ 表示:^ \-表示:-
可以用()将多个字符作为一个整体
\w 等价于 [0-9a-zA-Z_]
| 表示:或者
[\u4E00-\u9FA5] 是常用汉字的unicode编码范围
2.正则表达式配合字符串的方法&使用正则表达式验证表单
1.replace()方法
默认情况下,replace()方法,只会替换字符串中匹配的第一段内容
使用正则表达式,添加全局匹配修饰符g,可以替换匹配全部内容
使用正则表达式,添加忽略大小写修饰符i,在匹配内容时会忽略大小写
2.search()方法
可以通过正则表达式查找位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>正则表达式</title>
</head>
<body>
<script>
// 正则表达式:其实就是一种匹配规则,用于检索字符串
// 定义正则表达式的两种方式:1.直接定义 2.构造函数定义
// 1.直接定义
let reg1 = /abc/
// 2.构造函数定义
let reg2 = new RegExp("abc")
let str = '欢迎学习abc正则表达式'
// test()方法,用于检查一个字符串中,是否有满足匹配规则的字符串。
console.log(reg1.test(str));
// 其实用字符串自己的includes()方法,也能解决上面的问题
console.log(str.includes('abc'));
//那么正则表达式正则强大的地方是它可以写 通配符(拥有特殊含义的字符)
// \w 表示:字母、数字、下划线
let reg3 = /你\w好/
console.log(reg3.test("你好我好大家好"));
console.log(reg3.test("你3好我好大家好"));
// \W 表示:除了字母、数字、下划线以外的字符
let reg4 = /你\W好/
console.log(reg4.test("你9好我好大家好"));
console.log(reg4.test("你$好我好大家好"));
// \d 表示:数字
let reg5 = /你\d好/
console.log(reg5.test("你#好我好大家好"));
console.log(reg5.test("你7好我好大家好"));
// \D 表示:非数字
let reg6 = /你\D好/
console.log(reg6.test("你5好我好大家好"));
console.log(reg6.test("你*好我好大家好"));
// ^ 表示:以 ^ 符号后面的第一个字符开头
let reg7 = /^\d/
console.log(reg7.test("a21323"));
console.log(reg7.test("721323"));
// $表示:以符号前面的第一个字符结尾
let reg8 = /\d$/
console.log(reg7.test("a2132p"));
console.log(reg7.test("721321"));
// n{ X } 匹配包含 X 个 n 的序列的字符串。
//例如,/a{2}/ 不匹配 "candy," 中的 "a",但是匹配 "caandy," 中的两个 "a",且匹配 "caaaaaandy." 中的前两个 "a"。
let reg9 = /a{2}/
console.log(reg9.test("candy"));
console.log(reg9.test("caandy"));
console.log(reg9.test("caaaaaandy"));
// n{X,} X是一个正整数。前面的模式 n 连续出现至少 X 次时匹配。
//例如,/a{2,}/ 不匹配 "candy" 中的 "a",但是匹配 "caandy" 和 "caaaaaandy"和 "caaaaaaaaaaaaaaaandy" 中所有的 "a"。
let reg10 = /a{2,}/
console.log(reg10.test("candy"));
console.log(reg10.test("caandy"));
console.log(reg10.test("caaaaaandy"));
console.log(reg10.test("caaaaaaaaaaaaaaaandy"));
// n{ X, Y } 前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。
//例如,/a{2,6}/ 不匹配 "candy",匹配 "caandy," 中的两个 "a",匹配 "caaaaaandy" 中的6个 "a"。注意,当匹配 "caaaaaaaaaaaaaaaandy" 时,即使原始字符串拥有更多的 "a",匹配项也是 "aaaaaa"。
let reg11 = /a{2,6}/
console.log(reg11.test("candy"));
console.log(reg11.test("caandy"));
console.log(reg11.test("caaaaaandy"));
console.log(reg11.test("caaaaaaaaaaaaaaaandy"));
// [xyz] 表示:其中任意一个字符
let reg12 = /^a[adsdafa123]$/
console.log(reg12.test("ap"));
console.log(reg12.test("a2"));
// n+ 表示:匹配任何包含至少一个 n 的字符串。 等价于 n{ 1,}
// n* 表示:匹配任何包含零个或多个 n 的字符串。 等价于 n{ 0,}
// n? 表示:匹配任何包含零个或一个 n 的字符串。等价于 n{ 0, 1 }
let reg13 = /^s\d+$/
console.log(reg13.test("s121"));
console.log(reg13.test("s"));
let reg14 = /^w\d*$/
console.log(reg14.test("w"));
console.log(reg14.test("w123"));
let reg15 = /^w\d?$/
console.log(reg15.test("w"));
console.log(reg15.test("w1"));
console.log(reg15.test("w12"));
// .表示:除了换行符以外的任意一个字符
let reg16 = /abc.abc/
console.log(reg16.test("eeeabc\tabceee"));
console.log(reg16.test("eeeeabc\nabcee"));
// \.表示:.字符 \^表示:^ \$表示:$
let reg17 = /a\.b/
console.log(reg17.test("eeea.beee"));
console.log(reg17.test("eeeea0beee"));
let reg18 = /a\^b/
console.log(reg18.test("eeea^beee"));
console.log(reg18.test("eeea0beee"));
let reg19 = /a\$b/
console.log(reg19.test("eeea$beeee"));
console.log(reg19.test("eeea0beee"));
// 可以用()将多个字符作为一个整体
//abc@abc.com 或 abc.@abc.com.cn
//验证邮箱的正则表达式
let reg20 = /^\w+@\w+(\.\w+){1,2}$/
console.log(reg20.test("afaf@afaf.faad.cadd"));
console.log(reg20.test("afaf@afaf.faad"));
// \w 等价于[0 - 9a - zA - Z_]
let reg21 = /\w/
let reg22 = /[0-9a-zA-Z_]/
console.log(reg21.test("ee&2ee"));
console.log(reg22.test("ee&2ee"));
// | 表示:或者
let reg23 = /a|\d/
console.log(reg23.test("chsdrs1232"));
console.log(reg23.test("1232"));
console.log(reg23.test("sfeefasf"));
console.log(reg23.test("chsd"));
// [\u4E00 - \u9FA5] 是常用汉字的unicode编码范围
let reg24 = /[\u4E00-\u9FA5]/
console.log(reg24.test("我看着"));
console.log(reg24.test("你好啊"));
console.log(reg24.test("真实世界"));
// 验证年龄,0-120
//验证年龄的正则表达式
let reg25 = /^\d{1,2}$|^1[0-1]\d$|^120$/
console.log(reg25.test("0"));
console.log(reg25.test("99"));
console.log(reg25.test("100"));
console.log(reg25.test("119"));
console.log(reg25.test("120"));
console.log(reg25.test("130"));
let reg26 = /^a{2}$/
console.log(reg26.test("aa"));
let reg27 = /^a{2,6}$/
console.log(reg27.test("aaaaaa"));
let reg28 = /^a{2,}$/
console.log(reg28.test("aaaaaaaaaaaaaaaa"));
let reg29 = /^[0-9]$/ //查找0-9的字符
console.log(reg29.test("1"));
console.log(reg29.test("10"));
//出生日期的正则表达式
// 首先给出年份正则表达式的规则定义:年份由4位数字组成,只接受19,20开头的年份
// 根据以上规则,很容易写出年份的正则表达式
let year = /^(19|20)\d{2}$/
console.log(year.test("1900"));
console.log(year.test("1899"));
console.log(year.test("2099"));
console.log(year.test("2155"));
//月份正则
let month = /^((0?[1-9]|(1[0-2])))$/
console.log(month.test("10"));
console.log(month.test("0"));
console.log(month.test("13"));
//日期正则
let day = /^((0?[1-9])|([1-2][0-9])|30|31)$/
console.log(day.test("32"));
console.log(day.test("28"));
console.log(day.test("09"));
//组合校验
let pattern = /^(19|20)\d{2}\-((0?[1-9])|(1[0-2]))\-((0?[1-9])|([1-2][0-9])|30|31)$/;
//输出 true
console.log(pattern.test("1899-3-18"));
//输出 true
console.log(pattern.test("1900-4-31"));
//输出 true
console.log(pattern.test("2099-2-29"));
//输出 true
console.log(pattern.test("2100-2-29"));
//正则表达式配合字符串方法/
// 注意:正则修饰符g表示全局匹配,i表示忽略大小写匹配
let str = 'I like apple i like banana I like orange'
let str2 = str.replace("like", "喜欢")
console.log(str2);
let str3 = str.replace(/like/g, "喜欢")
console.log(str3);
//使用正则表达式忽略大小写,要想全部加上可以有两种方式:
//第一种:
let str4 = str3.replace(/I/gi, "我")
console.log(str4);
//第二种:
let str5 = str3.replace(/(I|i)/g, "我")
console.log(str5);
let str6 = "i like apple \n 我 喜欢 香蕉"
console.log(str6.search(/不?喜欢/));
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用正则表达式验证表单</title>
<style>
.ok {
color: green;
}
.err {
color: red;
}
</style>
</head>
<body>
<form action="">
<table>
<tr>
<td>学号:</td>
<td>
<input type="text" id="no" onblur="noCheck(this.value)">
<span id="msg_no"></span>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" id="password" onblur="passwordCheck(this.value)">
<span id="msg_password"></span>
</td>
</tr>
<tr>
<td>确认密码:</td>
<td>
<input type="password" id="password2" onblur="passwordCheck2(this.value)">
<span id="msg_password2"></span>
</td>
</tr>
<tr>
<td>姓名:</td>
<td>
<input type="text" id="name" onblur="nameCheck(this.value)">
<span id="msg_name"></span>
</td>
</tr>
<tr>
<td>性别:</td>
<td>
<input type="radio" value="0" name="gender" checked>男
<input type="radio" value="1" name="gender">女
</td>
</tr>
<tr>
<td>年级:</td>
<td>
<select id="grade" onchange="gradeCheck(this.value)">
<option value="0">请选择年级</option>//一定要加value
<option value="1">一年级</option>
<option value="2">二年级</option>
<option value="3">三年级</option>
</select>
<span id="msg_grade"></span>
</td>
</tr>
<tr>
<td>生日:</td>
<td>
<input type="text" name="" id="birthday" onblur="birthdayCheck(this.value)">
<span id="msg_birthday"></span>
</td>
</tr>
<tr>
<td>邮箱:</td>
<td>
<input type="text" id="email" onblur="emailCheck(this.value)">
<span id="msg_email"></span>
</td>
</tr>
<tr>
<td>电话:</td>
<td>
<input type="text" id="phone" onblur="phoneCheck(this.value)">
<span id="msg_phone"></span>
</td>
</tr>
<tr>
<td>身份证:</td>
<td>
<input type="text" id="status" onblur="statusCheck(this.value)">
<span id="msg_status"></span>
</td>
</tr>
<tr>
<td>地址:</td>
<td>
<input type="text" id="address" onblur="addressCheck(this.value)">
<span id="msg_address"></span>
</td>
</tr>
<tr>
<td></td>
<td>
<button type="submit">提交</button>
<button type="reset">重置</button>
</td>
</tr>
</table>
</form>
<script>
//定义一个验证表单输入内容的方法
function validateData(dom, dom_msg, reg, ok_msg, err_msg) {
if (reg.test(dom)) {
dom_msg.innerHTML = ok_msg
dom_msg.className = "ok"
return true
} else {
dom_msg.innerHTML = err_msg
dom_msg.className = "err"
return false
}
}
//验证学号的方法
function noCheck(dom) {
let msg_no = document.querySelector("#msg_no")
let reg_no = /^1\d{3}$/
return validateData(dom, msg_no, reg_no, "学号正确", "学号格式错误,必须是以1开头的四位数字")
}
//验证密码的方法
function passwordCheck(dom) {
let msg_password = document.querySelector("#msg_password")
let reg_password = /^\w{6,18}$/
return validateData(dom, msg_password, reg_password, "密码正确", "密码格式错误,必须是6-18位字母、数字、下划线组成的密码")
}
//验证确认密码的方法
function passwordCheck2(dom) {
let msg_password2 = document.querySelector("#msg_password2")
let value = document.querySelector("#password").value
let reg_password2 = /^\w{6,18}$/
if (dom === value && dom != "") {
msg_password2.innerHTML = "确认密码正确"
msg_password2.className = "ok"
return true
} else {
msg_password2.innerHTML = "两次密码输入不一致"
msg_password2.className = "err"
return false
}
}
//验证姓名的方法
function nameCheck(dom) {
let msg_name = document.querySelector("#msg_name")
let reg_name = /^[\u4E00-\u9FA5]{2,4}$/
return validateData(dom, msg_name, reg_name, "姓名正确", "姓名格式错误")
}
//验证生日的方法
function birthdayCheck(dom) {
let msg_birthday = document.querySelector("#msg_birthday")
let reg_birthday = /^(19|20)\d{2}\-(0?[13578]|1[02])\-(0?[1-9]|[1-2][0-9]|30|31)$|^(19|20)\d{2}\-(0?[469]|11)\-(0?[1-9]|[1-2][0-9]|30)$|^(19|20)\d{2}\-0?2\-(0?[1-9]|[1-2][0-9])$/
return validateData(dom, msg_birthday, reg_birthday, "生日正确", "生日格式错误必须是1900-2099年份的如:1999-10-12")
}
//验证年级的方法
function gradeCheck(dom) {
let msg_grade = document.querySelector("#msg_grade")
if (dom === "0") {
msg_grade.innerHTML = "请选择年级"
msg_grade.className = "err"
return false
} else {
msg_grade.innerHTML = "年级正确"
msg_grade.className = "ok"
return true
}
}
//验证邮箱的方法
function emailCheck(dom) {
let msg_email = document.querySelector("#msg_email")
//abc.scs@dss.com.cn
let reg_email = /^\w+@\w+((\.com)|(\.com\.cn))$/
return validateData(dom, msg_email, reg_email, "邮箱格式正确", "邮箱格式错误,必须要以.com或者.com.cn结尾")
}
//验证手机号的方法
function phoneCheck(dom) {
let msg_phone = document.querySelector("#msg_phone")
let reg_phone = /^1[356789]\d{9}$/
return validateData(dom, msg_phone, reg_phone, "电话格式正确", "电话格式错误,必须要以1开头,第二位为356789其中之一,长度为11位")
}
//验证身份的方法
function statusCheck(dom) {
let msg_status = document.querySelector("#msg_status")
let reg_status = /^34\d{16}$/
return validateData(dom, msg_status, reg_status, "身份格式正确", "身份格式错误,必须要以34开头,长度为18位,必须全部是数字")
}
//验证地址的方法
function addressCheck(dom) {
let msg_address = document.querySelector("#msg_address")
let reg_address = /[\u4E00-\u9FA5]/
return validateData(dom, msg_address, reg_address, "地址格式正确", "地址格式错误,必须是中文")
}
let form = document.querySelector("form")
//表单提交事件
form.onsubmit = function () {
//该方法返回值是true可以返回,否则不能返回
let no = document.querySelector("#no")
let password = document.querySelector("#password")
let password2 = document.querySelector("#password2")
let name = document.querySelector("#name")
let grade = document.querySelector("#grade")
let birthday = document.querySelector("#birthday")
let email = document.querySelector("#email")
let phone = document.querySelector("#phone")
let status = document.querySelector("#status")
let address = document.querySelector("#address")
if (noCheck(no.value) & passwordCheck(password.value) & passwordCheck2(password2.value) & nameCheck(name.value) & gradeCheck(grade.value) & birthdayCheck(birthday.value) & emailCheck(email.value) & phoneCheck(phone.value) & statusCheck(status.value) & addressCheck(address.value)) {
return true
} else {
return false
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>通过表单进行数据的增、删、改、查</title>
<style>
* {
margin: 0;
padding: 0;
outline: none;
}
#box {
width: 100vw;
overflow: hidden;
}
#box .title {
width: 100vw;
height: 60px;
text-align: center;
background-color: blueviolet;
color: white;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
#box .title .adminBtn {
position: absolute;
right: 16px;
}
#box .title button {
padding: 10px 20px;
border: none;
border-radius: 5px;
color: rgb(88, 97, 218);
cursor: pointer;
margin: 0 38px;
}
#box .title button:hover {
background-color: tomato;
color: white;
}
#header {
width: 100vw;
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid #ccc;
background-color: coral;
position: absolute;
top: 60px;
left: 0px;
box-sizing: border-box;
}
#header span {
color: rgb(23, 72, 231);
}
#header input {
width: 330px;
height: 28px;
border-radius: 5px;
border: none;
}
#header button {
padding: 5px 10px;
border: none;
border-radius: 5px;
color: rgb(235, 39, 39);
cursor: pointer;
margin: 0 8px;
}
#header button:hover {
background-color: red;
color: white;
}
#header .btn {
margin-right: 94px;
}
#box table {
border-collapse: collapse;
position: absolute;
top: 110px;
left: 0px;
width: 100vw;
}
th,
td {
padding: 10px 20px;
border: 1px solid #ccc;
color: rgb(27, 20, 20);
text-align: center;
font-size: 12px;
}
th {
background-color: cornflowerblue;
color: white;
}
td button {
padding: 5px 10px;
margin: 0 10px;
border: none;
border-radius: 5px;
color: rgb(235, 39, 39);
cursor: pointer;
}
td button:hover {
background-color: red;
color: white;
}
#information {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: cornflowerblue;
display: none;
}
#information table {
border-collapse: collapse;
}
#information h2 {
text-align: center;
color: rgb(238, 86, 15);
}
#information td {
color: white;
}
#information .close {
position: absolute;
top: 2px;
right: 5px;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
background-color: rgb(156, 163, 149);
border-radius: 50%;
color: white;
cursor: pointer;
}
</style>
</head>
<body>
<div id="box">
<div class="title">
<h2>高校学生管理系统</h2>
<div class="adminBtn">
<button>admin</button>
<button>退出</button>
</div>
</div>
<div id="header">
<div>
<span>请根据学生学号或者姓名查询(支持模糊查询):</span>
<input type="text" id="searchText">
</div>
<div class="btn">
<button id="search">查询</button>
<button id="addStu">添加</button>
</div>
</div>
<table>
<thead>
<tr>
<th>学生学号</th>
<th>学生姓名</th>
<th>学生年龄</th>
<th>学生性别</th>
<th>学生生日</th>
<th>学生电话</th>
<th>学生地址</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tbody"></tbody>
</table>
</div>
<div id="information">
<h2 id="title">添加学生信息</h2>
<table>
<tr>
<td>学生学号:</td>
<td>
<input type="number" id="stuNo"><br />
<span id="txt1"></span>
</td>
</tr>
<tr>
<td>学生姓名:</td>
<td>
<input type="text" id="stuName"><br />
<span id="txt2"></span>
</td>
</tr>
<tr>
<td>学生年龄:</td>
<td>
<input type="number" id="stuAge"><br />
<span id="txt3"></span>
</td>
</tr>
<tr>
<td>学生性别:</td>
<td>
<input type="radio" name="sex" value="男" checked>男
<input type="radio" name="sex" value="女">女
</td>
</tr>
<tr>
<td>学生生日:</td>
<td>
<input type="text" id="stuBornDate"><br />
<span id="txt4"></span>
</td>
</tr>
<tr>
<td>学生电话:</td>
<td>
<input type="number" id="stuTel"><br />
<span id="txt5"></span>
</td>
</tr>
<tr>
<td>学生地址:</td>
<td>
<input type="text" id="stuAddress"><br />
<span id="txt6"></span>
</td>
</tr>
<tr>
<td>操作:</td>
<td>
<button id="submit">提交</button>
<button id="concel">取消</button>
</td>
</tr>
</table>
<div class="close">X</div>
</div>
<script>
window.onload = function () {
//加载数据
loadData()
//查询点击事件
search.onclick = function (e) {
loadData()
if (tbody.innerHTML === "") {
alert("未查询到该学生")
} else {
alert("查询学生成功")
}
}
//通过回车键查询点击事件
window.onkeyup = function (e) {
if (e.keyCode === 13) {
loadData()
if (tbody.innerHTML === "") {
alert("未查询到该学生")
} else {
alert("查询学生成功")
}
}
}
//定义一个添加学生的点击事件
addStu.onclick = function () {
//将表单窗口显示出来
information.style.display = "block"
//修改表单窗口的标题
title.innerHTML = "添加学生信息"
//将表单的作用改为添加
isAdd = true
clearData()
}
//定义一个关闭表单窗口的点击事件
document.querySelector(".close").onclick = function () {
//将表单窗口改关闭
information.style.display = "none"
//去除表单数据
clearData()
}
//提交点击事件
submit.onclick = function () {
//验证学生学号的正则表达式
let regNo = /^[1-9]\d{3}$/
//验证学生姓名的正则表达式
let regName = /^[\u4E00-\u9FA5]{2,4}$/
//验证学生年龄的正则表达式
let regAge = /^\d{1,2}$|^1[0-1]\d$|^120$/
//验证学生生日的正则表达式
let regBornDate = /^(19|20)\d{2}\-(0?[13578]|1[02])\-(0?[1-9]|[1-2]\d|3[01])$|^(19|20)\d{2}\-(0?[469]|11)\-(0?[1-9]|[1-2]\d|30)$|^(19|20)\d{2}\-0?2\-(0?[1-9]|[1-2]\d)$/
//验证学生电话的正则表达式
let regTel = /^1[35789]\d{9}$/
//验证学生地址的正则表达式
let regAddress = /^[\u4E00-\u9FA5]{2,32}$/
//用正则表达式验证每个输入框里面内容的格式是否正确
let isok1 = regNo.test(stuNo.value)
let isok2 = regName.test(stuName.value)
let isok3 = regAge.test(stuAge.value)
let isok4 = regBornDate.test(stuBornDate.value)
let isok5 = regTel.test(stuTel.value)
let isok6 = regAddress.test(stuAddress.value)
//如果isAddd是true则是添加事件
if (isAdd) {
if (!isok1 || !isok2 || !isok3 || !isok4 || !isok5 || !isok6) {
alert("请输入正确的内容格式并且不能为空")
dataFalse()
} else {
//将表单里面数据通过一个对象的方法保存
let stu = {
no: stuNo.value,
name: stuName.value,
age: stuAge.value,
gender: [...document.getElementsByName("sex")].find(s => s.checked).value,
bornDate: stuBornDate.value,
tel: stuTel.value,
address: stuAddress.value
}
//将这个对象添加到数组中
stus.push(stu)
loadData()
clearData()
alert("添加学生成功")
}
//如果isAddd是false则是修改事件
} else {
if (!isok1 || !isok2 || !isok3 || !isok4 || !isok5 || !isok6) {
alert("请输入正确的内容格式并且不能为空")
dataFalse()
} else {
//通过索引找到当前要修改的学生
let stu = stus[stuIndex]
//把修改后的信息传给当前学生对应的属性
stu.no = stuNo.value
stu.name = stuName.value
stu.age = stuAge.value
stu.gender = [...document.getElementsByName("sex")].find(s => s.checked).value
stu.bornDate = stuBornDate.value
stu.tel = stuTel.value
stu.address = stuAddress.value
loadData()
clearData()
alert("修改学生成功")
}
}
}
//取消按钮的点击事件
concel.onclick = function () {
clearData()
}
}
//定义一个全局变量用于确定是否是添加还是修改
let isAdd = false
//定义一个全局变量用来接收修改的学生的索引
let stuIndex = -1
//定义一个学生数组用于存储数据
let stus = [
{
no: "1001",
name: "张三",
age: 22,
gender: "男",
bornDate: "1999-10-12",
tel: 15656330666,
address: "上海"
},
{
no: "1002",
name: "李四",
age: 29,
gender: "女",
bornDate: "1992-02-15",
tel: 13455552666,
address: "北京"
},
{
no: "1003",
name: "王五",
age: 32,
gender: "男",
bornDate: "1989-04-25",
tel: 18746332306,
address: "深圳"
},
{
no: "1004",
name: "小明",
age: 25,
gender: "女",
bornDate: "1996-07-14",
tel: 17979797113,
address: "武汉"
}
]
//定义一个创建元素的方法
function $create(tagName) {
return document.createElement(tagName)
}
//定义一个加载数据的方法
function loadData() {
//先清空tbody里面数据
tbody.innerHTML = ''
//获取搜索框里面值
let str = searchText.value
//先通学生的学号或者姓名过滤学生,再循环学生数组加载数据
stus.filter(s => s.no.includes(str) || s.name.includes(str)).forEach((s, index) => {
//创建一个tr,用于显示一个学生的信息
let tr = $create("tr")
let td1 = $create("td")
td1.innerHTML = s.no
let td2 = $create("td")
td2.innerHTML = s.name
let td3 = $create("td")
td3.innerHTML = s.age
let td4 = $create("td")
td4.innerHTML = s.gender
let td5 = $create("td")
td5.innerHTML = s.bornDate
let td6 = $create("td")
td6.innerHTML = s.tel
let td7 = $create("td")
td7.innerHTML = s.address
let td8 = $create("td")
let btn1 = $create("button")
btn1.innerHTML = "修改"
//给修改添加点击事件
btn1.onclick = function () {
updateStu(index)
}
let btn2 = $create("button")
btn2.innerHTML = "删除"
//给删除添加点击事件
btn2.onclick = function () {
deleteStu(index)
}
td8.appendChild(btn1)
td8.appendChild(btn2)
tr.appendChild(td1)
tr.appendChild(td2)
tr.appendChild(td3)
tr.appendChild(td4)
tr.appendChild(td5)
tr.appendChild(td6)
tr.appendChild(td7)
tr.appendChild(td8)
tbody.appendChild(tr)
})
}
//定义一个删除当前学生的方法
function deleteStu(index) {
if (confirm("是否确定删除?")) {
//从学生数组中删除当前学生数据
stus.splice(index, 1)
//再次加载数据显示
loadData()
clearData()
alert("删除学生成功")
} else {
return
}
}
//修改点击事件的方法
function updateStu(index) {
clearData()
//将表单窗口显示出来
information.style.display = "block"
//修改表单窗口的标题
title.innerHTML = "修改学生信息"
//将表单的作用改为修改
isAdd = false
//将要修改的学生索引传给全局变量索引,以便后面调用
stuIndex = index
//将要修改的学生信息以表单的形式保存并显示出来
stuNo.value = stus[stuIndex].no
stuName.value = stus[stuIndex].name
stuAge.value = stus[stuIndex].age,
[...document.getElementsByName("sex")].find(s => s.checked).checked = false,
[...document.getElementsByName("sex")].find(s => s.value === stus[stuIndex].gender).checked = true,
stuBornDate.value = stus[stuIndex].bornDate
stuTel.value = stus[stuIndex].tel
stuAddress.value = stus[stuIndex].address
}
//定义一个清除表单数据的方法
function clearData() {
//将表单里面保存的值全部赋值为空
stuNo.value = ""
stuName.value = ""
stuAge.value = ""
stuBornDate.value = ""
stuTel.value = ""
stuAddress.value = ""
txt1.innerHTML = ""
txt2.innerHTML = ""
txt3.innerHTML = ""
txt4.innerHTML = ""
txt5.innerHTML = ""
txt6.innerHTML = ""
}
//定义一个表单信息填写错误提示的方法
function dataFalse() {
txt1.innerHTML = "学号必须以1-9开头,共四位"
txt2.innerHTML = "名字必须为2-4位汉字"
txt3.innerHTML = "年龄必须为0-120"
txt4.innerHTML = "生日年份必须在1900-2099,格式为1970-(0)5-26"
txt5.innerHTML = "电话必须以1开头,以35789其中一个为第二位,一共11位"
txt6.innerHTML = "地址必须2-32的汉字"
txt1.style.color = "red"
txt2.style.color = "red"
txt3.style.color = "red"
txt4.style.color = "red"
txt5.style.color = "red"
txt6.style.color = "red"
}
</script>
</body>
</html>
网页显示为: