php彩票网站建设源码学院网站建设服务招生宣传
web/
2025/9/26 0:17:02/
文章来源:
php彩票网站建设源码,学院网站建设服务招生宣传,wordpress标签模板,网页设计公司员工一、window对象
BOM属于window对象
1.BOM#xff08;浏览器对象模型#xff09; bom里面包含着dom,只不过bom我们平时用得比较少#xff0c;我们经常使用的是dom操作#xff0c;因为我们页面中的这些标签都是在dom中取的#xff0c;所以我们操作dom多一点。 window对象…
一、window对象
BOM属于window对象
1.BOM浏览器对象模型 bom里面包含着dom,只不过bom我们平时用得比较少我们经常使用的是dom操作因为我们页面中的这些标签都是在dom中取的所以我们操作dom多一点。 window对象里面dom是核心document object model当然window对象里面除了dom对象之外还有很多其它很多对象如navigator(显示你用的什么浏览器的)locationlocation有很多的方法比如说我们的可以通过js的形式跳转页面下载xx的时候不用写个a写一个普通盒子就行了因为我们js也可以跳转页面实现下载的功能的通过js的方式跳转页面。因为我们有的情况下是让它自动跳转页面比如说我注册成功了我让它5s之后自动跳转到首页是自动跳转不需要a链接来点击history历史对象screen(屏幕。 最大的是window其次是document。 alert其实是window.alert(),console.log其实是window.console.log()。基本上我们所有的对象都是基于window的所以大多数情况下可以省略。
!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titlebom/title
/headbodyscript// document.querySelector()// 按理说这个更合适因为一层一层的去找但是我们都知道window是最大的没有比它更大的了所以window是可以省略的 // window.document.querySelector()// 验证一下console.log(document window.document)// 我们声明的这些函数或者全局变量其实都挂在window上我们调用的时候其实是window.fn()function fn() {console.log(11)}window.fn()// 我们全局声明的变量也是如此// var声明的是挂在window上不是constconst不行// const num 10// 所以var或者函数声明的这一些默认都挂在window下const和let就不是因为它们是挂在自己的作用域内var num 10console.log(window.num)/script
/body/html2.定时器—延时函数 这个定时器和之前我们学的定时器interval不同这个定时器只执行一次比如说弹出的一个小广告显示几秒之后自动关闭关闭之后就不再出来了而之前学的定时器是一直执行的比如说轮播图。第一个定时器是间歇定时器间隔多少秒执行一次而延时是多少秒之后执行一次然后就不再执行了。和前面间歇函数的写法一模一样只是名字和功能不一样而已。 定时器有两种间歇setInterval和延时(setTimeout 就执行一次为什么要清除因为延时函数后面会有一些特殊的使用方法它可以借助一种函数叫递归函数自己调自己可以来模拟定时器但是自己调自己很容易把自己调晕隔多少秒之后就来执行一次执行完之后再回来调一次自己又开始了。所以在特殊情况下我们需要清除。 平时我们只用一次的就不用去清除了但是在某些特殊情况下比如说setTimeout自己调自己用到递归函数的时候我们就必须要清除了。这个后面会讲。 按道理定时器都能开启和清除。setInteval返回的值是数字型的id1、2…是第几个定时器setTimeout返回的也是一个id(等待时间之后再回来执行回调函数
!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title延时函数/title
/headbodyscript// 到了2s之后打印1次之后就不会再继续打印了setTimeout(function () {console.log(时间到了)}, 2000)/script
/body/html案例 !DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title5秒自动关闭的广告/titlestyleimg {position: fixed;left: 0;bottom: 0;}/style
/headbodyimg src./images/ad.png altscript// 1.获取元素 将图片获取过来const img document.querySelector(img)// 2.开启定时器setTimeout(function () {img.style.display none}, 3000)/script
/body/html3.JS执行机制
JS的执行机制JS到底是怎么执行的。首先JS代码是从上往下执行的第二我们知道JS要解析JS有JS解析器浏览器有2个引擎第一个引擎叫渲染引擎可以渲染html,css第2个引擎是用来解析JS的叫JS解析器。在谷歌浏览器里面内置了一个V8引擎是我们浏览器的一个这个V8引擎是专门用来解析我们的JS的。 2个的结果都是1111,3333,2222 单线程有一个特点比如说有一个元素要进行删除操作必须要先添加再删除不能还没有就删除不能同时进行添加和删除操作这就是js的特点从上往下依次执行只能单线程不能多线程。单线程意味着我们所有的任务需要排队前面一个任务结束后面一个任务才会进行如果JS的执行时间过长这样就会造成页面的渲染不连贯。 如果遇到上面那种耗时的操作造成页面的阻塞js有解决这个问题利用了多核CPU的计算能力。JS本来是单线程的但是我们为了解决这个问题我们可以创建多个线程所以这里JS出现了同步和异步。 定时器是异步任务因为它是耗时的哪怕是耗0s也是耗时的。耗时的任务都是异步任务异步任务放在任务队列中的。需要注意的是我们JS是没有队列和栈的只是借助其他语言的队列和栈来更好的理解我们这门语言 什么是事件循环去面试一般都会问到 就是整个执行栈里面执行完了之后就去任务队列里面看把任务队列里面的拿过来再执行执行栈里面的这个异步任务执行完之后就又去任务队列里面拿如果再有就再拿过来执行反复这样转圈就是一个循环。这个我们称之为事件循环。
!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title事件循环/title
/headbodyscriptconsole.log(1)console.log(2)setTimeout(function () {console.log(3)})console.log(4)/script
/body/htmlJS是单线程的没有办法处理多线程但是浏览器可以处理多线程。 先把1放入执行栈再把2放入执行栈因为同步任务是立马就执行完的所以先打印1再打印2。这个点击和定时器都耗时是异步任务所以JS就不处理了提交给浏览器处理将这两个异步事件放到浏览器浏览器实时监测是先点击还是时间先到假如是时间先到就提交给任务队列执行栈在执行完同步任务之后就一直在等待所以当在任务队列里面看到时间之后就先执行时间如果一直没点击就不执行点击事件1234。如果在执行完1、2之后发现先点击了就先把点击推过去然后执行栈再取过来执行之后时间到了才是时间1243
4. location对象 !DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titlelocation/title
/headbodyscript// console.log(window.location)// console.log(location)// console.log(location.href)// 不一定点链接让页面跳转页面也可以自动跳转// 1. href 经常用href 利用js的方法跳转页面// 既然是属性那我们就可以赋值// 最典型的一个使用场景是当我注册成功之后会提示5s之后自动跳转回首页不需要点击自动跳转这是location.href的使用location.href http://www.baidu.com/script
/body/html这个经常见于注册一个账号注册成功后几秒后自动跳转回首页或者支付完之后多少秒跳转回首页。 我们应该用setInterval而不是setTimeout,因为里面的数字在变每隔1s就会换一次。
!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title5秒钟之后自动跳转页面/titlestylespan {color: red;}/style
/headbodya hrefhttp://www.itcast.cn支付成功span5/span秒钟之后跳转到首页/ascript// 1. 获取元素const a document.querySelector(a)// 2. 开启定时器// 3. 声明倒计时变量let num 5// timerId里面存的是一个序号 let timerId setInterval(function () {num--// 上来之后会立即变成4吗不会因为定时器1s之后才会调用这些代码a.innerHTML 支付成功span${num}/span秒钟之后跳转到首页// 倒计时成了0就应该跳转了并且关闭定时器// timeId里面存的是序号// 如果num 0 则停止定时器并且完成跳转功能if (num 0) {// 没有名字清除不了clearInterval(timerId)// 4. 跳转 location.hreflocation.href http://www.itcast.cn}}, 1000)/script
/body/html!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titlelocation属性和方法/title
/headbody!-- 表单一定要有name不然提交不了数据 --form actioninput typetext nameusernameinput typepassword namepwdbutton提交/button/form!-- 只有那一块变了后面vue会学到 点击之后是my就把my显示过来,是friend就把friend显示过来 --!-- 用哈希拿到#后面的值 知道是点的哪一个 --a href#/my我的/aa href#/friend关注/aa href#/download下载/abutton classreload刷新/button!--location 除了那些属性外还有一个方法 --scriptconst reload document.querySelector(.reload)reload.addEventListener(click, function () {// 类似于按下F5 刷新页面// location.reload()// 强制刷新 ctrlf5location.reload(true)})/script
/body/htmlspa单页面应用程序有很多都是一个页面它只是其中一块变了别的没变上面没刷新。这种应用后面会学因为它是一种非常好用的应用因为它不需要刷新整个页面加载资源就会比较少这种应用页面没有变它没有跳转页面就可以实现页面跳转它的实现原理是它是通过#后面的值来发生变化来发生判断的所以我们在获取的时候一定要拿到#后面的值后面还会讲。我们可以通过哈希来拿到这个值。 true强制执行比如说有些网页上面的小图标favicon已经引进来了但是图标一直不出来刷新也不管用这时候可以ctrlf5强制刷新所谓强制刷新就是不从本地里面去取数据了而是在线重新渲染重新拉下来这些数据
5. navigator对象 比如京东的页面PC端打开就是PC端移动端打开就是移动端。 这个代码不需要我们写正则都出来了不用去背要用的时候直接cv就行。 如果是手机端跳转到http://m.itcast.cn上去如果是pc端就不跳转。
!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title自动跳转到移动端/title!-- 拿过来之后直接放在最上面就行了 --!-- 这是立即函数加了一个! --script// 检测 userAgent浏览器信息!(function () {const userAgent navigator.userAgent// 验证是否为Android或iPhoneconst android userAgent.match(/(Android);?[\s\/]([\d.])?/)const iphone userAgent.match(/(iPhone\sOS)\s([\d_])/)// 如果是Android或iPhone则跳转至移动站点if (android || iphone) {// 只需要把它换成自己想要的地址就可以了location.href http://m.itcast.cn}})()// 写在上面也可以// 最后一个要加;// (function () { })(); 这个前面加不加!无所谓// 还有人喜欢这么写:这样写是错误的因为JS不会认为这是一个整体它会认为是调用的一个function函数// function(){}()// 但是如果加一个!或者或者~等等只要是一个算术表达式都能的它就会把前面当做一个整体了// !function () { }()/script
/headbody这是PC端的页面!-- script// (function () { })()/script --
/body/html6. history对象 !DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titlehistory对象/title
/headbodybutton后退/buttonbutton前进/buttonscriptconst back document.querySelector(button:first-child)// back的下一个兄弟const forward back.nextElementSibling// 回调函数back.addEventListener(click, function () {// 后退一步// 怎样实现后退复制有前进后退按钮的地址到一个页面中打开即可// history.back()// 单词难记推出了更好记的方法history.go(-1)})forward.addEventListener(click, function () {// 前进一步// 要是前进不了是因为没有再打开一个新的页面在前进后退按钮页面再打开另外一个地址// history.forward()history.go(1)// location.reload可以刷新页面})/script
/body/html二、本地存储 1. 本地存储介绍 本地存储是一个仓库用于存放数据你可以理解为“数据库”但是这个数据库比较特殊是放在浏览器里面的。以前我们也有一个小仓库存放数据叫变量变量是放在内存的内存有一个特点一刷新就没了但是有的数据我们不想丢失所以我们在浏览器里面添加了一个小仓库用于存放数据只要浏览器在它就在数据不会丢失。 本地存储一共有两个sessionStorage和localStorage每个都约5M左右。https://todomvc.com/examples/vanilla-es6/
2. 本地存储分类 大多数时候是可以共享的当然也有不能的情况当我们讲ajax的时候它如果涉及到跨域的问题是不能访问的后面会讲。 另外打开一个页面跟刚才的页面没有任何关系发现有storage但是发现没有这些数据原因是我们没有学过跨域比如说京东和百度的数据肯定是不能共享的他有不同的域名前面的域名不相同是不能取的。当我们打开history对象这个代码的页面F12点击storage我们还没有讲跨域讲了跨域之后就懂了
我们发现打印出的18是字符型的。由此可知本地存储只能存储字符串数据类型不管什么类型都给你转换成字符串类型。这个跟变量不一样。 localStorage关闭浏览器不会消失sessionStorage关闭浏览器就消失。和变量的区别是sessionStorage也是存到仓库里面去的只不过它关闭浏览器就会消失。sessionStorage和localStorage的用法一致存获取删除改。
!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titlelocalStorage存储/title
/headbodyscript// 要存储一个名字 uname// 键值对要加引号不加引号就当成变量来看了是个字符串 //属性名 值localStorage.setItem(uname, pink老师)// 2. 获取方式 都加引号console.log(localStorage.getItem(uname))// 3. 删除本地存储 只删除名字 手动删除// 能打印因为是先存再打印最后再删除的// localStorage.removeItem(uname)// 4. 改 如果原来有这个键则是改如果没有这个键则是增localStorage.setItem(uname, black)// 我要存一个年龄 18不用加引号因为是数字型localStorage.setItem(age, 18)// 除了数字型其他的都要加引号// 实在记不住全部都加上引号也行// 我们发现打印出的18是字符型的 由此可知本地存储只能存储字符串数据类型不管什么类型都给你转换成字符串类型console.log(localStorage.getItem(age))// sessionStorage和localStorage的用法一致/script
/body/html3. 存储复杂数据类型 一个一个地存太麻烦考虑存对象或者数组的形式
!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title本地存储复杂数据类型/title
/headbodyscriptconst obj {uname: pink老师,age: 18,gender: 女}/* //存储 复杂数据类型// 第一个obj是键 第二个obj是值因为是变量了所以就不加引号了localStorage.setItem(obj, obj) //直接采取这种格式我们得到的是[obj][obj]这种格式为解决这个问题我们把复杂数据类型转换成JSON字符串/*//这样也可只不过上面那种更好localStorage.setItem(obj, {uname: pink老师,age: 18,gender: 女})*/// 取 */// console.log(localStorage.getItem(obj))// 不能像上面那么写 我们应该转换完了再存// 1. 复杂数据类型存储必须转换为JSON字符串存储// 因为要转换所以JSON.stringfy()是个方法// 这个代码会把对象转换为字符串存进去也可以直接把obj里面的内容直接复制到方法的括号里面去localStorage.setItem(obj, JSON.stringify(obj))// 在本地存储里面只能存储字符串// 取// 打印出来是黑色的 所以是字符串而不是对象// console.log(localStorage.getItem(obj))// 也可以检测一下是不是字符串console.log(typeof localStorage.getItem(obj))// JSON对象 特点属性和值有引号而且引号统一是双引号// {uname:pink老师,age:18,gender:女} //看着像对象但它已经不是对象了它是字符串// 我们取过来的是字符串不能直接用这样就拿不到数据uname,age这些了那么反过来我们把这个字符串转化成对象,以后就可以拿过来数据直接渲染了// 2. 把JSON字符串转换为对象// 先获取再转换console.log(JSON.parse(localStorage.getItem(obj)))/* // 如果觉得看起来挺费劲可以这样const str localStorage.getItem(obj)console.log(JSON.parse(str)) *//script
/body/html三、综合案例
对象数组因为数据有很多条所以我们要把对象放到数组里面去 (2). 如果没有数据则用 空数组来代替 的具体实施 逻辑或中断如果有数据就把数据存进去返回的就是数组数组不为空那就是真的根据逻辑或中断的原则如果前面为真则后面就不执行了但是如果把本地存储里面的数据清空那它里面就没有内容没有内容就为空空就是假取出一个空字符串根据逻辑或中断的原则前面为假则执行后面的那么就把后面的空数组返回过来了。 我们可以把存储数据注释起来看看效果。 根据本地存储的原则即使已经注释起来了但是刚才已经存过了所以也有我们可以把它清空本地存储就没有数据了重新刷新一下页面再打开控制台就会发现返回的是一个空数组那说明我们写的程序是正确的因为一会儿我们渲染页面如果数组里面有数据就根据数组里面的数据渲染页面如果数组是空的那么渲染的页面也就是空的页面。 前面我们已经拿到了数据接下来我们根据数据渲染页面比如说我有几条数据就可以在下面渲染几行 以前我们用字符串拼接str这种效率并不高而我们以后的开发中利用的是map和join这两种数组方法来实现字符串拼接这种的效率会更高一些那么就意味着从今天开始以后所有的渲染页面拼接字符串统一使用数组的这两个方法来实现。因为这个方法需要以前拼接字符串str方式的铺垫前面的学习了后面再学习这个会更简单。 1.map的语法格式map里面有一个回调函数回调函数里面有2个参数这个写法和for each很像eleelement是数组元素index是数组索引号只不过map在使用的时候可以添加下面这一句话return ele ‘颜色’它的意思是让数组的每个元素进行添加颜色每循环一次就把当前的结果返回过来一共有3个数组元素所以循环了3次那拼接完map最大的特点是有返回值返回新的数组现在我们通过new arr把数组拿过来了返回的就是把数据处理之后的结果并且放到了一个数组里面。
2.map不仅可以遍历数组还可以处理数据比如说可以让数组里的每一个数据拼接字符串第一次循环让red加上颜色第二次循环让blue加上颜色…每次循环都有一个返回值返回到了数组。它的本质是这样子只要用到了map它的返回值就是数组先准备一个空数组第一次循环就可以把red颜色返回过来第二次循环就是blue颜色…,这样的话整个map执行完就会生成一个新的数组然后我们就可以拿到这个数组了。 分析我们前面已经能够拿到数据了 数组里面放着相关对象然后我们可以根据里面有几条数据生成几个tr。我们可以这么去做可以用map去遍历数组看看有几个对象然后根据对象去处理数据也就是说可以生成tr在生成tr的同时我们就就可以把拿到的数据的值放到相应的位置也就是说我在生成tr的时候把数据填充进去。第一次循环就生成一个tr但是如果数组里面有多条数据那么每次循环都有一个返回值放到数组里面去再生成第二个tr所以map方法最大的特点就是可以生成对应数据的tr然后再把数据填充进去。我们知道map方法最大的特点是有一个数组返回给我们等到map全部遍历完了就根据你有几条数据返回对应的数组所以map有一个数组返回给我们了但是虽然里面有相应的tr了它毕竟是个数组我们没有办法把数组直接追加给tbody所以我们还需要做一步通过join的方法把数组转换成字符串也就是说我们要的不是数组是字符串。我有2个tr全都连在一起就形成了一个字符串我们最后就可以把这个字符串追加给tbody有了这些tr页面之中就可以把它渲染出来了。这个就是我们说的通过map和join方法实现渲染页面的一个思路了。
!DOCTYPE html
html langenheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title数组map方法和join方法/title
/headbodyscriptconst arr [red, blue, pink]// 1.数组map方法 处理数据并且返回一个数组// 不要用map方法来遍历数组不然就违背了我们设计map方法的初衷了。map方法设计的主要原则是我想要得到一个数组返回一个数组就用map。在进行map遍历的时候可以让它处理一些数据然后再把处理的结果返回给我这才是map的正确处理方法。const newArr arr.map(function (ele, index) {// console.log(ele) // 数组元素// console.log(index) // 索引号return ele 颜色})console.log(newArr)// 2. 数组join方法 把数组转换为字符串// 小括号为空则默认逗号分隔因为我们都知道数组默认逗号分隔console.log(newArr.join()) // red颜色,blue颜色,pink颜色// 小括号是空字符串则元素之间没有分隔符console.log(newArr.join()) // red颜色blue颜色pink颜色console.log(newArr.join(|)) // red颜色|blue颜色|pink颜色/script
/body/html步骤 因为我们要做渲染所以我们还是封装成一个渲染函数叫做render因为我们后面不管是增加也好还是删除也好需要重新渲染页面所以我们封装成一个函数。 把字符串赋值给tbody之后tbody就可以把tr显示出来了。 前面已经把数据存到本地存储里面本地存储有数据有数据我们就可以通过map的方法来遍历arr数组在遍历的同时就可以return返回tr返回字符串在返回的同时把里面的相关数据换成了活的数据map最大的特点是返回的是一个数组那么就把return后面的东西返回给了数组装起来了简单的来说我们有一个数组return就把tr拿过来放到数组里面这样我们就可以拿到数组了经过刚才的验证我们发现数组里面确实存的是一个tr的字符串。 先把render函数封装一下然后通过map方法拿到返回值的数组接下来只需要把数组转换成字符串就可以追加给tbody了。在上面先把tbody获取一下。 共有数据几条是根据数组的长度得来的数组里面有几条数据就变成几所以我们只需要把盒子拿过来把它的值改成数组的长度就行了。 点击添加没有实现跳转说明阻止默认行为成功了接下来做非空判断如果前3个为空就不允许增加数据。终止程序并且返回一个提示框。首先把相关的数据获取过来在提交事件里面。 当我们新增一条数据的时候一定要把它存储到本地存储里面不然页面一刷新数据就丢失了。当它存储完毕之后就可以拿到本地存储的最新数据再去渲染我们的页面这样页面就会多一条数据又因为本地存储的数据不会丢失所以再刷新页面中的数据就不会消失了 。 页面一刷新代码从上往下去执行我们的初始值已经没有用到了刚开始的本地存储一定要注释起来要不然我们刚才录入的数据就会被覆盖掉了页面就只剩初始的那一条数据了。这句话只是为了测试用的。localStorage.setItem(‘data’, JSON.stringify(initData)) 这句话一读到的时候我就要去本地存储里面读最新的data数据我们前面已经把那两条数据存到data里面去了那arr取过来的就是最新的那两条数据有数据所以后面的空数组不执行。然后代码从上往下继续渲染函数刚开始不执行但是下面有一个渲染函数所以就回头调用一回头调用我们就拿arr里面的两条数据来做渲染所以只要往本地存储里面去存储了那本地存储里面存的就是最新的数据然后每次刷新页面我就要从本地存储里面取最新的数据然后赋值给arr那arr就可以来进行遍历渲染了这就是它的执行过程所以我们在做提交事件的时候千万不要忘了最后一条把最新的arr存到data里面新增业务完成。
删除业务 为什么给tbody注册点击事件呢因为我们会有新的数据产生如果直接给按钮注册点击事件我们用原先传统的方式是注册不上的而 事件委托可以给新增的这些数据添加点击事件又因为按钮有行都会变化的而tbody是不变的所以我们给他们的父亲tbody注册点击事件。这么多按钮如何知道点了哪一条数据呢知道当前按钮的索引号就可以了。map里面除了有一个ele参数以外还有一个index可以得到数组元素的索引号所以在遍历的时候就可以得到每一条数据的索引号了现在只需给a加上一个自定义属性就可以了 没有数据arr.length就是0,0当假来看则执行表达式2的那一个值如果里面有2条数据数字型的2当真看则执行表达式1的结果把结果返回过来再赋值给stuId。
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta nameviewport contentwidthdevice-width, initial-scale1.0 /meta http-equivX-UA-Compatible contentieedge /title学生就业统计表/titlelink relstylesheet href./iconfont/iconfont.csslink relstylesheet hrefcss/index.css /
/headbodyh1学生就业统计表/h1form classinfo autocompleteoffinput typetext classuname nameuname placeholder姓名 /input typetext classage nameage placeholder年龄 /input typetext classsalary namesalary placeholder薪资 /select namegender classgenderoption value男男/optionoption value女女/option/selectselect namecity classcityoption value北京北京/optionoption value上海上海/optionoption value广州广州/optionoption value深圳深圳/optionoption value曹县曹县/option/selectbutton classaddi classiconfont icon-tianjia/i添加/button/formdiv classtitle共有数据span0/span条/divtabletheadtrthID/thth姓名/thth年龄/thth性别/thth薪资/thth就业城市/thth录入时间/thth操作/th/tr/theadtbody!-- trtd1/tdtd迪丽热巴/tdtd23/tdtd女/tdtd12000/tdtd北京/tdtd2099/9/9 08:08:08/tdtda hrefjavascript:i classiconfont icon-shanchu/i删除/a/td/tr --/tbody/tablescript// 参考数据const initData [{stuId: 1,uname: 迪丽热巴,age: 22,salary: 12000,gender: 女,city: 北京,time: 2099/9/9 08:08:08}]// 这里是为了测试先存了一下我们看到我们正确的拿到了数据但是建议把这一行一定要把它注释起来因为我们页面第一次打开肯定是没有数据的所以我们拿个空数组去代替是没有问题的后面做增加等业务的时候就可以把最新的数据放到本地存储里面这样再打开页面的时候就可以从本地存储里面取真正的数据了。// 页面一打开从上往下依次去执行这里有一个对象数组下面一句话把这个数据存到本地存储里面那就意味着我们每次打开页面都会重新存储一下这个data数据把它存储到本地存储里面去如果后面的数据发生了变化我们一打开就又给我们覆盖掉了所以一定要把下面这句话注释起来因为本地存储已经存到浏览器里面去了本地存储aplication一直都是存在的所以我们没有必要打开页面又重新去填写了// localStorage.setItem(data, JSON.stringify(initData)) // 把这个解开之后就可以往本地存储里面去存这个数组了本地存储有了数据我们就可以来遍历这条数据了// 1. 渲染业务// 1.1 先读取本地存储的数据// (1). 本地存储有数据则记得转换为对象然后存储到变量里面后期用于渲染页面// 我们数组本质上也属于对象// (2). 如果没有数据则用 空数组来代替 const arr JSON.parse(localStorage.getItem(data)) || []console.log(arr)// 1.2 利用map和join方法来渲染页面const tbody document.querySelector(tbody)// 渲染页面需要封装一个函数function render() {// (1). 利用map遍历数组返回对应tr的数组// 每循环一次就返回一个tr,在返回的同时把相关的数据填充进去// map里面的第一个参数是ele(数组元素) 里面的每一条数组元素也就是数组对象// map在遍历数组结果发现只有一条数据它就会这么做map一旦遍历就会有一个空数组等着map的返回值一运行的时候就发现有一个return把tr返回在把tr返回的同时把里面的数据更换所以旧表整个tr装到了数组里面因为只有一条数据所以只遍历一次就结束了那我们就可以得到一个新的数组那我们就可以把这个数组拿到了// map的另一个参数:index可以得到数组元素的索引号所以我在遍历的时候就可以拿到每一条数据的索引号了现在只需要给a加一个自定义属性data-id 索引号const trArr arr.map(function (ele, index) {return trtd${ele.stuId}/tdtd${ele.uname}/tdtd${ele.age}/tdtd${ele.gender}/tdtd${ele.salary}/tdtd${ele.city}/tdtd${ele.time}/tdtda hrefjavascript: data-id${index}i classiconfont icon-shanchu/i删除/a/td/tr})console.log(trArr)// (2). 把数组转换为字符串 (join)// (3). 把生成的字符串换追加给tbody// 把多个tr转换成一个字符串tbody.innerHTML trArr.join()// 显示共有几条数据document.querySelector(.title span).innerHTML arr.length}// 在打印的时候千万别忘了调用一下render函数render()// 到浏览器里面看看能不能拿到数组里面存着的tr发现输出的是两个空数组可能有一个情况是本地存储里面没有拿到数据我没有遍历到,所以没有办法 往里面去存数据。到应用里面看看果然本地存储里面没有数据因为得到的是一个空数组所以当然本地存储里面存不进去了空数组没有办法遍历所以没有办法加tr// 2. 新增业务// 2.1 form表单注册提交事件阻止默认行为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()// 2.2 非空判断if (!uname.value || !age.value || !salary.value) {return alert(输入内容不能为空)}// 2.3 给 arr 数组追加对象里面存储表单获取过来的数据arr.push({// 新增一条新的数据所以ID号就是原来的数组的长度1因为push是后追加// 这种做法不可取因为如删除第一条数据之后再录入会出现ID号相同的情况// stuId: arr.length 1,// 处理 stuId: 数组最后一条数据的stuId 1// 还需考虑数据全部删除的情况// 全部删除之后再添加数据就报错了因为我们数组里面没有数据我们再用最后一条数据获取它的stuId就报错了所以我们要加一个判断条件如果没有数据就直接让它赋值为1就行了 arr.length判断数组有没有长度stuId: arr.length ? arr[arr.length - 1].stuId 1 : 1,uname: uname.value,age: age.value,salary: salary.value,gender: gender.value,city: city.value,// 用户录入了一条信息它就自动获取当前的时间time: new Date().toLocaleString()})// 2.4 渲染页面和重置表单 (reset() 方法)render()// form表单是info其实就是我们的this因为this指向我们函数的调用者也就是info。写this和info都可以this.reset() // 重置表单把表单输入框里面的值自动重置恢复到原来的样子清空内容// 2.5 把数组重新存入本地存储里面,记得转换为JSON字符串存储// 因为我们已经有data这个数据了一旦存了新的就把以前的覆盖掉了实现了替换这样就保证了data里面存的是最新的数据localStorage.setItem(data, JSON.stringify(arr))})// 3. 删除业务// 3.1 采用事件委托形式给tbody注册点击事件tbody.addEventListener(click, function (e) {// 判断是否点击的是删除按钮 A链接if (e.target.tagName A) {// alert(11)// 3.2 得到当前点击链接的索引号渲染数据的时候动态给a链接添加自定义属性例如 data-id0// 点击的那个对象有一个自定义属性叫data-id这样可以拿到当前的索引号console.log(e.target.dataset.id)// 确认框确认是否要真的删除// confirm会返回两个值如果点击确定就返回truetrue就表示我要执行里面的代码不用做删除如果用户点击的是取消就返回false,就不执行大括号里面的代码if (confirm(你确定要删除这条数据吗)) {// 3.3 根据索引号利用 splice 删除数组这条数据arr.splice(e.target.dataset.id, 1)// 3.4 重新渲染页面render()// 3.5 把最新 arr 数组存入本地存储// 不然删了之后本地存储里面也还是有数据localStorage.setItem(data, JSON.stringify(arr))}}})/script
/body/html下面这个案例未找到
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/81891.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!