案例一:学生信息表
CSS代码
<style>
* {
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;
}
</style>
HTML代码
<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>
</tbody>
</table>
JS代码
<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 = []
// 表单提交事件
const info = document.querySelector('.info')
info.addEventListener('submit', function (e) {
// 阻止默认行为:取消表单默认提交事件
e.preventDefault()
//这里进行表单验证 如果不通过,直接中断,不需要添加数据
for (let i = 0; i < items.length; i++) {
if (items[i].value === '') return alert('输入内容不能为空')
}
//创建新的对象
const obj = {
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()
})
//渲染函数 因为增加和删除都需要渲染
function render() {
// 先清空tbody以前的行 把最新数组里面的数据渲染完毕
tbody.innerHTML = ''
for (let i = 0; i < arr.length; i++) {
//生成 tr
const tr = document.createElement('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>
`
//追加元素
tbody.appendChild(tr)
}
}
//删除操作
//事件委托
tbody.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {
// 删除arr 数组里面对应的数据
arr.splice(e.target.dataset.id, 1)
//重新渲染一遍
render()
}
})
</script>
案例叮嘱:
1.首先明确核心思路,我们采取对数组的增加和删除操作,然后根据数组数据渲染界面 ,因此第一步是声明一个空数组,又因为增加和删除操作都需要渲染,所以我们封装一个渲染函数以便使用时调用
2.①注意该事件是表单提交事件,而不是点击事件
②我们需要阻止表单默认提交事件这种默认行为
阻止默认行为
我们某些情况下需要阻止默认行为的发生,比如阻止链接的跳转和表单域的跳转
③用户输入的数据不能为空,所以我们需要进行表单验证(注意书写的位置,应该放到新增数据的前面,阻止默认行为的后面),观察发现所有需要填写的表单,他们共同特点都有name属性,所以我们先用属性选择器抓取他们,遍历伪数组,如果有一项值为空就return返回提示输入为空中断程序
3.点击录入模块
创建新的对象,里面存储表单获取过来的数据,并且用arr.push(元素)追加给数组,提交完之后需要清空表单重置(注意此处使用reset属性),最后一定要记得调用封装好的渲染函数
对象由属性和方法组成
属性:信息或叫特征(名词) 方法:功能或叫行为(动词)方法是依附在对象中的函数
4.点击删除模块
采用事件委托形式能简化代码,直接委托给tobody
不过存在问题如何获取当前删除的数组数据?采用自定义属性方式
前面渲染数据的时候,动态给a链接添加自定义属性data-id=“0”,这样点击当前对象就知道索引号了
使用arr.splice()方法删除,删除之后需要重新渲染数据
案例二:学生就业统计表
CSS代码
<style>
* {
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;
}
</style>
HTML代码
<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>
</tbody>
</table>
JS代码
<script>
//如果有就返回对象,没有就声明一个空的数组
const arr = JSON.parse(localStorage.getItem('data')) || []
const tbody = document.querySelector('tbody')
//利用map和join方法来渲染页面
function render() {
//利用map遍历数组,返回对应tr的数组
const trArr = arr.map(function (ele, index) {
return `
<tr>
<td>${ele.stuId}</td>
<td>${ele.uname}</td>
<td>${ele.age}</td>
<td>${ele.gender}</td>
<td>${ele.salary}</td>
<td>${ele.city}</td>
<td>
<a href="javascript:" data-id="${index}">删除</a>
</td>
</tr>
`
})
//利用join把数组转化为字符串
tbody.innerHTML = trArr.join('')
//把生成的字符串追加给tbody
console.log(trArr)
}
render()
//录入模块
const info = document.querySelector('.info')
const uname = document.querySelector('.uname')
const age = document.querySelector('.age')
const salary = document.querySelector('.salary')
const gender = document.querySelector('.gender')
const city = document.querySelector('.city')
info.addEventListener('submit', function (e) {
//阻止默认行为
e.preventDefault()
//非空判断
if (!uname.value || !age.value || !uname.value) {
return alert('输入内容不能为空')
}
//给arr数组追加对象
arr.push({
//处理stuId:数组最后一条数据的stuId+1
stuId: arr.length ? arr[arr.length - 1].stuId + 1 : 1,
uname: uname.value,
age: age.value,
gender: gender.value,
salary: salary.value,
city: city.value
})
render()
//重置表单
this.reset()
//把数组重新存入本地存储里面
localStorage.setItem('data', JSON.stringify(arr))
})
//点击删除模块
//事件委托
tbody.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {
//确认框确认是否要真的删除
if (confirm('您确定要删除这条数据吗?')) {
arr.splice(e.target.dataset.id, 1)
render()
//把数组重新存入本地存储里面
localStorage.setItem('data', JSON.stringify(arr))
}
}
})
</script>
案例叮嘱:
1.首先明确核心思路,我们采取本地存储的方法,然后根据数据渲染界面 ,因此第一步是我们先找本地存储里面查找是否有数据,如果有数据先进行渲染页面,如果没有数据,我们放一个空数组,用来存放数据,又因为增加和删除操作都需要渲染,所以我们封装一个渲染函数以便使用时调用
本地存储
localStorage
作用: 可以将数据永久存储在本地(用户的电脑),除非手动删除,否则关闭页面也会存在
特性:
· 可以多窗口(页面)共享(同一浏览器可以共享)
· 以键值对的形式存储使用
注意:
· 参数中除了数字都要加引号
· 改 如果原来有这个键,则是改,如果没有这个键是增
· 本地存储只能存储字符串数据类型
存储复杂数据类型
本地只能存储字符串,无法存储复杂数据类型
JSON 对象 属性和值有引号,而是引号统一是双引号
STEP1:复杂数据类型—>JSON字符串,再存储到本地
语法:JSON.stringify(复杂数据类型)
STEP2:取出来的字符串—>对象
语法:JSON.parse(JSON字符串)
2.我们使用map方法遍历数组,直接返回整个tr,里面包含所有修改后的tr标签,里面更换数据,修改后的数组通过join方法转换为字符串
3.录入模块
①跟上一个案例一样我们需要阻止表单默认提交事件这种默认行为,然后利用||逻辑运算符的逻辑中断确保输入内容不能为空
②用arr.push(元素)追加给数组,提交完之后需要清空表单重置(注意此处使用reset属性),然后要记得调用封装好的渲染函数,最后一定要把数组重新存入本地存储里面
4.点击删除模块
采用事件委托形式能简化代码,直接委托给tobody
不过存在问题如何获取当前删除的数组数据?采用自定义属性方式
前面渲染数据的时候,动态给a链接添加自定义属性data-id=“0”,这样点击当前对象就知道索引号了
使用arr.splice()方法删除,删除之后需要重新渲染数据,最后一定要把数组重新存入本地存储里面
5.关于stuId处理的细节问题
因为stuId的值直接影响着自定义属性值的获取,会影响数组后续的删除操作,为了保证正确性,最好的做法是:新增加序号应该是最后一条数据的序号+1数组[数组的长度-1].stuId+1,但是要判断,如果没有数据则是直接赋值为1,否则就采用上面的做法
案例三:倒计时
let i = 60
let n = setInterval(function () {
i--
btn.innerHTML = `我已经阅读用户协议(${i})`
if (i === 0) {
clearInterval(n)
btn.disabled = false
btn.innerHTML = '同意'
}
}, 1000)
基本思路:
在间歇函数外先声明变量 i ,i 代表页面最开始从多少秒倒计时
间歇函数中一开始直接 i --,用模板字符串修改文字内容,当 i 为0时直接停止计时器