一、日期对象
日期对象(Date) 是 JavaScript 中用于处理时间和日期的内置对象,能够获取、操作和格式化时间信息。常用于动态显示时间、倒计时功能、时间戳转换等场景
• 实例化
• 日期对象方法
• 时间戳
1.实例化日期对象
通过 new Date()
创建日期对象,支持获取当前时间或指定时间:
语法:
// 获取当前时间
const now = new Date();
// 获取指定时间(如:2008年8月8日)
const date = new Date("2008-8-8");
console.log(date); // 输出:Fri Aug 08 2008 00:00:00 GMT+0800 (中国标准时间)
示例代码:
<!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>Document</title>
</head>
<body>
<script>
// 实例化 new
// 1. 得到当前时间
const date = new Date()
console.log(date)
// 2. 指定时间
const date1 = new Date('2022-5-1 08:30:00')
console.log(date1)
</script>
</body>
</html>
运行结果:
2. 日期对象方法
通过日期对象的方法获取具体时间单位的值:
使用场景:因为日期对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
方法 | 作用 | 返回值范围 |
---|---|---|
getFullYear() |
获取四位年份 | 如:2023 |
getMonth() |
获取月份 | 0~11(0代表1月) |
getDate() |
获取月份中的某一天 | 1~31 |
getDay() |
获取星期 | 0~6(0代表周日) |
getHours() |
获取小时 | 0~23 |
getMinutes() |
获取分钟 | 0~59 |
getSeconds() |
获取秒 | 0~59 |
注意:月份和星期的返回值需要转换(如:getMonth() + 1
表示实际月份)。
<!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>Document</title>
</head>
<body>
<script>
// 获得日期对象
const date = new Date()
// 使用里面的方法
console.log(date.getFullYear())
console.log(date.getMonth() + 1) // 月份要 + 1
console.log(date.getDate())
console.log(date.getDay()) // 星期几
</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>Document</title>
<style>
div {
width: 300px;
height: 40px;
border: 1px solid pink;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div></div>
<script>
const div = document.querySelector('div')
function getMyDate() {
const date = new Date()
let h = date.getHours()
let m = date.getMinutes()
let s = date.getSeconds()
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
return `今天是: ${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}号 ${h}:${m}:${s}`
}
div.innerHTML = getMyDate()
setInterval(function () {
div.innerHTML = getMyDate()
}, 1000)
</script>
</body>
</html>
因为写了setInterval,所以会自动更新
⑵.案例:页面显示时间,写法2
<!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>Document</title>
<style>
div {
width: 300px;
height: 40px;
border: 1px solid pink;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div></div>
<script>
const div = document.querySelector('div')
// 得到日期对象
const date = new Date()
div.innerHTML = date.toLocaleString() // 2022/4/1 09:41:21
setInterval(function () {
const date = new Date()
div.innerHTML = date.toLocaleString() // 2022/4/1 09:41:21
}, 1000)
// div.innerHTML = date.toLocaleDateString() // 2022/4/1
// div.innerHTML = date.toLocaleTimeString() // 2022/4/1
</script>
</body>
</html>
核心用法对比
const date = new Date();
// 1. 日期部分
div.innerHTML = date.toLocaleDateString();
// 输出示例:2023/10/1 (中文环境)
// 2. 时间部分
div.innerHTML = date.toLocaleTimeString();
// 输出示例:下午3:30:45 (中文环境)
进阶技巧
1.指定语言环境
// 显示英文格式
date.toLocaleDateString('en-US'); // "10/1/2023"
date.toLocaleTimeString('en-US'); // "3:30:45 PM"
// 显示日文格式
date.toLocaleDateString('ja-JP'); // "2023年10月1日"
2.自定义格式
const options = {
year: 'numeric', month: 'long', day: 'numeric', // 日期部分
hour: '2-digit', minute: '2-digit', second: '2-digit' // 时间部分
};
date.toLocaleDateString('zh-CN', options); // "2023年10月1日"
date.toLocaleTimeString('zh-CN', options); // "15:30:45"
3. 时间戳
时间戳是从 1970年1月1日00:00:00 UTC 到当前时间的毫秒数,常用于计算时间差(如倒计时)。
使用场景: 如果计算倒计时效果,前面方法无法直接计算,需要借助于时间戳完成
算法:
将来的时间翟 - 现在的时间翟 = 剩余时间毫秒数
剩余时间毫秒数 转换为 剩余时间的 年月日时分秒 就是 倒计时时间
比如 将来时间戳 2000ms - 现在时间戳 1000ms = 1000ms
1000ms 转换为就是 0小时0分1秒
获取时间戳的三种方式:
语法:
// 方式1:getTime()
const date = new Date();
console.log(date.getTime());
// 方式2:+new Date()(推荐)
console.log(+new Date()); // 当前时间戳
console.log(+new Date("2024-1-1")); // 指定时间的时间戳
// 方式3:Date.now()(仅当前时间)
console.log(Date.now());
示例代码:
<!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>Document</title>
</head>
<body>
<script>
// 1. getTime()
const date = new Date()
console.log(date.getTime())
// 2. +new Date()
console.log(+new Date())
// 3. Date.now()
console.log(Date.now());
// 2. +new Date()
console.log(+new Date())
console.log('-----------------');
console.log(+new Date('2022-4-1 18:30:00'))
// 我要根据日期 Day() 0 ~ 6 返回的是 星期一
const arr = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
// const date = new Date()
console.log(arr[new Date().getDay()])
</script>
</body>
</html>
案例:毕业倒计时效果
<!DOCTYPE html>
<!-- 定义 HTML 文档的语言为英语 -->
<html lang="en">
<!-- 文档的元数据部分,包含字符编码、兼容性设置、视口设置等 -->
<head>
<!-- 设置字符编码为 UTF-8 -->
<meta charset="UTF-8" />
<!-- 设置文档在 Internet Explorer 中的兼容性模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- 设置视口的宽度为设备宽度,初始缩放比例为 1.0 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 设置文档的标题 -->
<title>Document</title>
<!-- 内部样式表,用于定义页面元素的样式 -->
<style>
/* 倒计时容器样式 */
.countdown {
/* 容器宽度 */
width: 240px;
/* 容器高度 */
height: 305px;
/* 文本居中对齐 */
text-align: center;
/* 行高为 1 */
line-height: 1;
/* 文本颜色为白色 */
color: #fff;
/* 背景颜色为棕色 */
background-color: brown;
/* 隐藏溢出内容 */
overflow: hidden;
}
/* 倒计时容器中类名为 next 的元素样式 */
.countdown .next {
/* 字体大小为 16px */
font-size: 16px;
/* 上下外边距为 25px 和 14px,左右外边距为 0 */
margin: 25px 0 14px;
}
/* 倒计时容器中类名为 title 的元素样式 */
.countdown .title {
/* 字体大小为 33px */
font-size: 33px;
}
/* 倒计时容器中类名为 tips 的元素样式 */
.countdown .tips {
/* 上外边距为 80px */
margin-top: 80px;
/* 字体大小为 23px */
font-size: 23px;
}
/* 倒计时容器中 small 标签的样式 */
.countdown small {
/* 字体大小为 17px */
font-size: 17px;
}
/* 倒计时容器中类名为 clock 的元素样式 */
.countdown .clock {
/* 宽度为 142px */
width: 142px;
/* 上下外边距为 18px 和 0,左右外边距自动居中 */
margin: 18px auto 0;
/* 隐藏溢出内容 */
overflow: hidden;
}
/* 倒计时容器中类名为 clock 的元素内的 span 标签和 i 标签的样式 */
.countdown .clock span,
.countdown .clock i {
/* 以块级元素显示 */
display: block;
/* 文本居中对齐 */
text-align: center;
/* 行高为 34px */
line-height: 34px;
/* 字体大小为 23px */
font-size: 23px;
/* 向左浮动 */
float: left;
}
/* 倒计时容器中类名为 clock 的元素内的 span 标签的样式 */
.countdown .clock span {
/* 宽度为 34px */
width: 34px;
/* 高度为 34px */
height: 34px;
/* 圆角半径为 2px */
border-radius: 2px;
/* 背景颜色为 #303430 */
background-color: #303430;
}
/* 倒计时容器中类名为 clock 的元素内的 i 标签的样式 */
.countdown .clock i {
/* 宽度为 20px */
width: 20px;
/* 取消斜体样式 */
font-style: normal;
}
</style>
</head>
<!-- 文档的可见内容部分 -->
<body>
<!-- 倒计时容器 -->
<div class="countdown">
<!-- 显示日期信息 -->
<p class="next">今天是2222年2月22日</p>
<!-- 显示倒计时标题 -->
<p class="title">下班倒计时</p>
<!-- 显示倒计时的时分秒 -->
<p class="clock">
<!-- 显示小时 -->
<span id="hour">00</span>
<!-- 分隔符 -->
<i>:</i>
<!-- 显示分钟 -->
<span id="minutes">25</span>
<!-- 分隔符 -->
<i>:</i>
<!-- 显示秒数 -->
<span id="scond">20</span>
</p>
<!-- 显示下课时间 -->
<p class="tips">18:30:00下课</p>
</div>
<!-- 内部脚本,用于实现页面的交互功能 -->
<script>
// 随机颜色函数
// 1. 自定义一个随机颜色函数
function getRandomColor(flag = true) {
if (flag) {
// 3. 如果是true 则返回 #ffffff
let str = '#';
let arr = [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f',
];
// 利用for循环随机抽6次 累加到 str里面
for (let i = 1; i <= 6; i++) {
// 每次要随机从数组里面抽取一个
// random 是数组的索引号 是随机的
let random = Math.floor(Math.random() * arr.length);
// str = str + arr[random]
str += arr[random];
}
return str;
} else {
// 4. 否则是 false 则返回 rgb(255,255,255)
let r = Math.floor(Math.random() * 256); // 55
let g = Math.floor(Math.random() * 256); // 89
let b = Math.floor(Math.random() * 256); // 255
return `rgb(${r},${g},${b})`;
}
}
// 页面刷新随机得到颜色
const countdown = document.querySelector('.countdown');
countdown.style.backgroundColor = getRandomColor();
// 函数封装 getCountTime
function getCountTime() {
// 1. 得到当前的时间戳
const now = +new Date();
// 2. 得到将来的时间戳
const last = +new Date('2022-4-1 18:30:00');
// console.log(now, last);
// 3. 得到剩余的时间戳 count 记得转换为 秒数
const count = (last - now) / 1000;
// console.log(count);
// 4. 转换为时分秒
// h = parseInt(总秒数 / 60 / 60 % 24) // 计算小时
// m = parseInt(总秒数 / 60 % 60); // 计算分数
// s = parseInt(总秒数 % 60);
// let d = parseInt(count / 60 / 60 / 24) // 计算当前秒数
let h = parseInt(count / 60 / 60 % 24);
h = h < 10 ? '0' + h : h;
let m = parseInt(count / 60 % 60);
m = m < 10 ? '0' + m : m;
let s = parseInt(count % 60);
s = s < 10 ? '0' + s : s;
console.log(h, m, s);
// 5. 把时分秒写到对应的盒子里面
document.querySelector('#hour').innerHTML = h;
document.querySelector('#minutes').innerHTML = m;
document.querySelector('#scond').innerHTML = s;
}
// 先调用一次
getCountTime();
// 开启定时器
setInterval(getCountTime, 1000);
</script>
</body>
</html>
二、节点操作
• DOM 节点
• 查找节点
• 增加节点
• 删除节点
1.DOM节点
2.查找节点
⑴.父节点查找:
<!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>Document</title>
</head>
<body>
<div class="yeye">
<div class="dad">
<div class="baby">x</div>
</div>
</div>
<script>
const baby = document.querySelector('.baby')
console.log(baby) // 返回dom对象
console.log(baby.parentNode) // 返回dom对象
console.log(baby.parentNode.parentNode) // 返回dom对象
</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>Document</title>
<style>
.box {
position: relative;
width: 1000px;
height: 200px;
background-color: pink;
margin: 100px auto;
text-align: center;
font-size: 50px;
line-height: 200px;
font-weight: 700;
}
.box1 {
position: absolute;
right: 20px;
top: 10px;
width: 20px;
height: 20px;
background-color: skyblue;
text-align: center;
line-height: 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<script>
// // 1. 获取事件源
// const box1 = document.querySelector('.box1')
// // 2. 事件侦听
// box1.addEventListener('click', function () {
// this.parentNode.style.display = 'none'
// })
// 1. 获取三个关闭按钮
const closeBtn = document.querySelectorAll('.box1')
for (let i = 0; i < closeBtn.length; i++) {
closeBtn[i].addEventListener('click', function () {
// 关闭我的爸爸 所以只关闭当前的父元素
this.parentNode.style.display = 'none'
})
}
</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>Document</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
const ul = document.querySelector('ul') // ul
console.log(ul.children) // 得到伪数组 选择的是 亲儿子
const li2 = document.querySelector('ul li:nth-child(2)')
console.log(li2.previousElementSibling) // 上一个兄弟
console.log(li2.nextElementSibling) // 下一个兄弟
</script>
</body>
</html>
3.增加节点
⑴.创建节点
⑵.追加节点
<!DOCTYPE html>
<html>
<head>
<title>添加节点示例</title>
</head>
<body>
<ul id="list">
<li>项目1</li>
<li>项目2</li>
</ul>
<button onclick="addItem()">添加新项目</button>
<script>
function addItem() {
// 1. 创建新节点
const newLi = document.createElement('li');
// 2. 设置内容
newLi.textContent = `新项目-${Date.now()}`;
// 3. 插入到列表末尾
document.getElementById('list').appendChild(newLi);
}
</script>
</body>
</html>
⑶.学成在线案例渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>学车在线首页</title>
<link rel="stylesheet" href="./css/style.css">
<style>
</style>
</head>
<body>
<!-- 4. box核心内容区域开始 -->
<div class="box w">
<div class="box-hd">
<h3>精品推荐</h3>
<a href="#">查看全部</a>
</div>
<div class="box-bd">
<ul class="clearfix">
</ul>
</div>
</div>
<script>
// 1. 重构
let data = [
{
src: 'images/course01.png',
title: 'Think PHP 5.0 博客系统实战项目演练',
num: 1125
},
{
src: 'images/course02.png',
title: 'Android 网络动态图片加载实战',
num: 357
},
{
src: 'images/course03.png',
title: 'Angular2 大前端商城实战项目演练',
num: 22250
},
{
src: 'images/course04.png',
title: 'Android APP 实战项目演练',
num: 389
},
{
src: 'images/course05.png',
title: 'UGUI 源码深度分析案例',
num: 124
},
{
src: 'images/course06.png',
title: 'Kami2首页界面切换效果实战演练',
num: 432
},
{
src: 'images/course07.png',
title: 'UNITY 从入门到精通实战案例',
num: 888
},
{
src: 'images/course08.png',
title: 'Cocos 深度学习你不会错过的实战',
num: 590
},
]
const ul = document.querySelector('.box-bd ul')
// 1. 根据数据的个数,创建 对应的小li
for (let i = 0; i < data.length; i++) {
// 2. 创建新的小li
const li = document.createElement('li')
// 把内容给li
li.innerHTML = `
<a href="#">
<img src=${data[i].src} alt="">
<h4>
${data[i].title}
</h4>
<div class="info">
<span>高级</span> • <span>${data[i].num}</span>人在学习
</div>
</a>
`
// 3. ul追加小li
ul.appendChild(li)
}
</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>Document</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
const ul = document.querySelector('ul')
// 1 克隆节点 元素.cloneNode(true)
const li1 = ul.children[0].cloneNode(true)
console.log(li1)
// 2. 追加
ul.appendChild(ul.children[2].cloneNode(true))
</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>Document</title>
<style>
.box {
display: none;
}
</style>
</head>
<body>
<div class="box">123</div>
<ul>
<li>没用了</li>
<li>123</li>
</ul>
<script>
const ul = document.querySelector('ul')
// 删除节点 父元素.removeChlid(子元素)
ul.removeChild(ul.children[0])
</script>
</body>
</html>
三. M端事件
目标:了解M端常见的事件
移动端也有自己独特的地方。比如触屏事件 touch(也称触摸事件),Android 和 IOS 都有。
触屏事件 touch(也称触摸事件),Android 和 IOS 都有。
ouch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔 )对屏幕或者触控板操作。
常见的触屏事件如下:
四、插件
插件: 就是别人写好的一些代码,我们只需要复制对应的代码,就可以直接实现对应的效果
学习插件的基本过程
Ø 熟悉官网,了解这个插件可以完成什么需求 https://www.swiper.com.cn/
Ø 看在线演示,找到符合自己需求的demo https://www.swiper.com.cn/demo/index.html
Ø 查看基本使用流程 https://www.swiper.com.cn/usage/index.html
Ø 查看APi文档,去配置自己的插件 https://www.swiper.com.cn/api/index.html
Ø 注意: 多个swiper同时使用的时候, 类名需要注意区分
1. 本地文件
五、案例 学生信息表案例
index.css
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
color:#721c24;
}
h1 {
text-align: center;
color:#333;
margin: 20px 0;
}
table {
margin:0 auto;
width: 800px;
border-collapse: collapse;
color:#004085;
}
th {
padding: 10px;
background: #cfe5ff;
font-size: 20px;
font-weight: 400;
}
td,th {
border:1px solid #b8daff;
}
td {
padding:10px;
color:#666;
text-align: center;
font-size: 16px;
}
tbody tr {
background: #fff;
}
tbody tr:hover {
background: #e1ecf8;
}
.info {
width: 900px;
margin: 50px auto;
text-align: center;
}
.info input, .info select {
width: 80px;
height: 27px;
outline: none;
border-radius: 5px;
border:1px solid #b8daff;
padding-left: 5px;
box-sizing: border-box;
margin-right: 15px;
}
.info button {
width: 60px;
height: 27px;
background-color: #004085;
outline: none;
border: 0;
color: #fff;
cursor: pointer;
border-radius: 5px;
}
.info .age {
width: 50px;
}
index.html
<!DOCTYPE html>
<!-- 声明 HTML 文档的语言为英语 -->
<html lang="en">
<head>
<!-- 设置字符编码为 UTF-8 -->
<meta charset="UTF-8" />
<!-- 设置视口的宽度为设备宽度,初始缩放比例为 1.0 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 设置文档在 Internet Explorer 中的兼容性模式 -->
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<!-- 设置文档的标题 -->
<title>学生信息管理</title>
<!-- 引入外部 CSS 文件 -->
<link rel="stylesheet" href="css/index.css" />
</head>
<body>
<!-- 页面标题 -->
<h1>新增学员</h1>
<!-- 新增学员的表单,关闭自动完成功能 -->
<form class="info" autocomplete="off">
<!-- 姓名输入框 -->
姓名:<input type="text" class="uname" name="uname" />
<!-- 年龄输入框 -->
年龄:<input type="text" class="age" name="age" />
<!-- 性别选择下拉框 -->
性别:
<select name="gender" class="gender">
<option value="男">男</option>
<option value="女">女</option>
</select>
<!-- 薪资输入框 -->
薪资:<input type="text" class="salary" name="salary" />
<!-- 就业城市选择下拉框 -->
就业城市:<select name="city" class="city">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
<option value="曹县">曹县</option>
</select>
<!-- 录入按钮 -->
<button class="add">录入</button>
</form>
<!-- 就业榜标题 -->
<h1>就业榜</h1>
<!-- 就业榜表格 -->
<table>
<!-- 表格头部 -->
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>薪资</th>
<th>就业城市</th>
<th>操作</th>
</tr>
</thead>
<!-- 表格主体 -->
<tbody>
<!--
<tr>
<td>1001</td>
<td>欧阳霸天</td>
<td>19</td>
<td>男</td>
<td>15000</td>
<td>上海</td>
<td>
<a href="javascript:">删除</a>
</td>
</tr>
-->
</tbody>
</table>
<script>
// 获取元素
// 获取姓名输入框元素
const uname = document.querySelector('.uname');
// 获取年龄输入框元素
const age = document.querySelector('.age');
// 获取性别选择下拉框元素
const gender = document.querySelector('.gender');
// 获取薪资输入框元素
const salary = document.querySelector('.salary');
// 获取就业城市选择下拉框元素
const city = document.querySelector('.city');
// 获取表格主体元素
const tbody = document.querySelector('tbody');
// 获取所有带有 name 属性的元素
const items = document.querySelectorAll('[name]');
// 声明一个空的数组,增加和删除操作都对这个数组进行操作
const arr = [];
// 1. 录入模块
// 1.1 表单提交事件
// 获取表单元素
const info = document.querySelector('.info');
// 为表单添加提交事件监听器
info.addEventListener('submit', function (e) {
// 阻止表单提交的默认行为,防止页面跳转
e.preventDefault();
// 这里进行表单验证,如果不通过,直接中断,不需要添加数据
// 遍历所有带有 name 属性的元素
for (let i = 0; i < items.length; i++) {
// 如果某个元素的值为空
if (items[i].value === '') {
// 弹出提示框,提示输入内容不能为空
return alert('输入内容不能为空');
}
}
// 创建新的对象,用于存储学生信息
const obj = {
// 学号,为数组长度加 1
stuId: arr.length + 1,
// 姓名,从姓名输入框获取
uname: uname.value,
// 年龄,从年龄输入框获取
age: age.value,
// 性别,从性别选择下拉框获取
gender: gender.value,
// 薪资,从薪资输入框获取
salary: salary.value,
// 就业城市,从就业城市选择下拉框获取
city: city.value
};
// 将新对象追加到数组中
arr.push(obj);
// 清空表单,重置输入框和下拉框的值
this.reset();
// 调用渲染函数,更新表格显示
render();
});
// 2. 渲染函数,因为增加和删除都需要渲染
function render() {
// 先清空 tbody 以前的行,把最新数组里面的数据渲染完毕
tbody.innerHTML = '';
// 遍历 arr 数组
for (let i = 0; i < arr.length; i++) {
// 生成 tr 元素
const tr = document.createElement('tr');
// 设置 tr 元素的内容,包含学生信息和删除链接
tr.innerHTML = `
<td>${arr[i].stuId}</td>
<td>${arr[i].uname}</td>
<td>${arr[i].age}</td>
<td>${arr[i].gender}</td>
<td>${arr[i].salary}</td>
<td>${arr[i].city}</td>
<td>
<a href="javascript:" data-id=${i}>删除</a>
</td>
`;
// 将 tr 元素追加到 tbody 中
tbody.appendChild(tr);
}
}
// 3. 删除操作
// 3.1 事件委托,将事件绑定到 tbody 上
tbody.addEventListener('click', function (e) {
// 如果点击的元素是 a 标签
if (e.target.tagName === 'A') {
// 得到当前元素的自定义属性 data-id
// 从数组中删除对应的数据
arr.splice(e.target.dataset.id, 1);
// 重新渲染表格
render();
}
});
</script>
</body>
</html>
问题1:
// 清空表单,重置输入框和下拉框的值
this.reset();
问题2:
// 先清空 tbody 以前的行,把最新数组里面的数据渲染完毕
tbody.innerHTML = '';
每次调用 render
函数时,都会先清空表格的所有行,然后重新遍历数组生成新的内容。以下是具体过程和原因:
清空表格
tbody.innerHTML = '';
会直接移除<tbody>
中所有已存在的行。这样做是为了确保每次渲染时,表格不会残留旧数据,保证显示的内容完全基于最新的数组数据。