APIs案例及知识点串讲(下)
案例一:学生信息表
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++) {//生成 trconst 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('')//把生成的字符串追加给tbodyconsole.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+1stuId: 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 = falsebtn.innerHTML = '同意'}}, 1000)
基本思路:
在间歇函数外先声明变量 i ,i 代表页面最开始从多少秒倒计时
间歇函数中一开始直接 i --,用模板字符串修改文字内容,当 i 为0时直接停止计时器