API(Application Programming Intertace ,应用程序接口),预先定义的接口(一般是函数)
一、 DOM —一套操作网页内容的函数
DOM(Document Object Mode)一般指文档对象模型,文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口(api)。
- 什么是DOM树
将html文档以树状结构表现出来
作用:体现了标签与标签之间的关系
- 什么是DOM对象
浏览器内存在以 js对象(dom对象) 的形式存储
DOM工作原理
1.浏览器将html文件读取到内存中 2.生成dom树 3.根据dom树渲染到页面
网页所有内容都在document里面
1.获取页面元素
- document.querySelector(‘选择器’) 标签、类、id
功能: 根据选择器获取满足条件的第一个元素
参数: string css选择器字符串
返回值: DOM对象 | null
选择器存在返回第一个元素
选择器不存在会获取null
let box = document.querySelector('.box') //变量名尽量与选择器一样box.style.color = 'red'
document.querySelectorAll(‘选择器’)
1.功能: 根据选择器获取满足条件所有的元素
2.参数: string css选择器字符串
3.返回值: 一定会得到数组(伪数组),不能使用数组的方法—[DOM对象1,DOM对象2]let boxList = document.querySelectorAll('.box') //变量名加List后缀boxList[1].style.color = 'green'
区别 document.querySelector(‘选择器’) 的到对象,可以直接操作、修改 document. querySelectorAll(‘选择器’) 得到的是数组,不可以直接操作、修改, 数组[下标].属性
document.body 可以直接获取body body具有唯一性
2.操作元素属性
2.1 操作元素内容—元素.innerText && 元素.innerHTML
操作内容之前,首先得获取元素 — document.querySelector(‘选择器’)
1.元素.innerText:获取元素所有的文本
2.元素.innerHTML:获取元素内容(文本+标签)—能解析标签
两者的异同点:
相同点:都获取的是字符串
不同点: 获取的内容不同
innerText:获取文本,重新赋值后无法解析字符串的标签,
innerHTML:获取文本,重新赋值后可以解析字符串的标签,
// 获取元素里面的文本(字符串) 元素.innerTextbox.innerText = '<a href="http://jd.com">京东</a><strong>我是强壮的标签</strong>'// 获取元素里面的文本+标签 元素.innerHTMLbox.innerHTML = '<a href="http://jd.com">京东</a><strong>我是强壮的标签</strong>'
2.2 操作元素属性(HTML属性)
首先得拿到元素—document.querySelector(‘选择器’)
语法:
元素.href ==>a标签的herf
元素.src ==>img标签的src
<a href="http://www.baidu.com">百度</a><br><img src="./images/hmewm.jpg" alt=""><script>//获取元素let a = document.querySelector('a')let img = document.querySelector('img')//查看元素属性console.log(a.href)console.log(img.src)//更改属性内容a.href = 'http://taobao.com' //更改过后再次点击,跳到淘宝网站(本身自带点击事件)img.src = './images/bgs.png' //因没有添加事件,直接更改了</script>
2.3操作元素样式—CSS
1.3.1 style操作样式
修改一个样式
首先得拿到元素—document.querySelector(‘选择器’)
语法:
查看:元素.style.样式名
style是对象
修改:元素.style.样式名 = ‘’
如果有这个样式,重新赋值,如果没有,添加新的样式
<div class="box" style="width: 200px; height: 200px; background-color: green;"></div><script>//获取元素let box = document.querySelector('.box')//查看元素的样式console.log(box.style);//修改元素的样式box.style.backgroundColor = 'orange'//自动转成rgb格式</script>
注意:样式有 margin- border- font- bgc- ,在dom语法中都需要转成驼峰命名backroundColor,因为 - 不符合js语法规范
1.3.2 className操作样式
语法:
元素.className=’类名’ 会覆盖原先的类 —-不用(out)
<style>.one {height: 200px !important;}</style><div class="box" style="width: 200px; height: 100px;background-color: green;"></div><script>let div = document.querySelector('div')console.log(div);div.className = 'one'</script>
1.3.3 classList操作样式 —获取类名
修改多个样式
首先得拿到元素—document.querySelector(‘选择器’)
语法:
操作类名,不会覆盖原来的类名
新增类名:元素.classList.add(‘类名’)
移除类名:元素.classList.remove(‘类名’)
切换类名:元素.classList.toggle(‘类名’)
包含类名:元素.classList.contains(‘类名’)
有这个类名,就删掉,没有的话,就增加
一次可以写多个类名 元素.classList.add(‘类名1’,’类名2’,’类名3’···)
<style>.box {background-color: red;margin: 0 auto;}.rad {border-radius: 50%;border: 1px solid #000;}.bor {width: 200px;height: 200px;}</style><body><div></div><script>//1.获取元素let div = document.querySelector('div')// 新增类名:元素.classList.add('类名')div.classList.add('box', 'rad', 'bor')//<div class="box rad bor"></div>// 移除类名:元素.classList.remove('类名')div.classList.remove('box')//<div class="rad bor"></div>// 切换类名:元素.classList.toggle('类名')div.classList.toggle('box')//此时没有box类名,就增加<div class="box rad bor"></div>div.classList.toggle('box')//此时有box类名,就移除 <div class="rad bor"></div></script></body>
1.3.4 操作表单元素属性
1.表单获取文本用 元素.value —常用
2.表单中的布尔类型属性有
disabled; 是否禁用 0
checked : 默认选中(单选框和多选框)
selected : 默认选中
<script>//1.获取元素let inputList = document.querySelectorAll('input')let optionList = document.querySelectorAll('option')console.dir(inputList) //伪数组console.dir(optionList) //伪数组//2.获取表单的文本 元素.value// console.log(inputList[0].value);inputList[0].value = '你好呀' //更改表单文本//3.更改表单属性inputList[0].disabled = 'true' //禁用表单inputList[0].disabled = '' //可用表单inputList[4].checked = ''inputList[5].checked = 'true' //默认选中//3.1更改下拉列表属性optionList[0].selected = 'true'</script>
2.4attribute语法操作自定义属性
1 标准属性: W3C中的标准属性,浏览器可以识别 2 自定义属性: 浏览器不能识别样式的属性,用户自定义添加(用于存储一些数据)
attribute语法场景 : 操作元素行内自定义属性
获取属性: 元素.get Attribute(‘属性名’)
设置属性: 元素.setAttribute(‘属性名’,属性值)
移除属性: 元素.removeAttribute(‘属性名’)
<script>/*1. 隔行变色,单行是绿色 双行是黄色2.移入li li变红3.移除li li变回原来的颜色*/let liList = document.querySelectorAll('ul li')console.log(liList);for (let i = 0; i < liList.length; i++) {if (i % 2 == 0) {liList[i].style.backgroundColor = 'green'} else {liList[i].style.backgroundColor = 'orange'}//2.移入事件liList[i].onmouseenter = function () {//背包思想 。 给每一个li元素添加一个自定义属性用于存储自己原先的颜色this.setAttribute('aaa', this.style.backgroundColor)this.style.backgroundColor = 'red'}//3.移出事件liList[i].onmouseleave = function () {this.style.backgroundColor = this.getAttribute('aaa')}}</script>
案例排他思想案例
<script>//排他思想/*都需要有点击事件 ,点击任意一个所有的样式清空 ,再给点击的按钮添加属性*///获取元素let btnList = document.querySelectorAll('button')console.log(btnList);/* btnList[0].onclick = function () {btnList[0].style.backgroundColor = 'pink'} *///注册5个事件btnList[0].style.backgroundColor = 'pink'for (let i = 0; i < btnList.length; i++) {btnList[i].onclick = function () {//1.无论点击谁所有的样式为空for (let j = 0; j < btnList.length; j++) {btnList[j].style.backgroundColor = ''console.log(j);}//2.再吧被点击的增加样式this.style.backgroundColor = 'pink'}}//给按钮添加移入事件for (let i = 0; i < btnList.length; i++) {btnList[i].onmouseenter = function () {btnList[i].style.color = 'green'}btnList[i].onmouseleave = function () {btnList[i].style.color = ''}}</script>
案例:开关思想
<script>/*1.点击全选/全部选 列表选项为全选/全部选的checked属性2.单击列表选项时,只要有一个checked为false all的值为false*///获取元素let checkAll = document.querySelector('#checkAll')let inputList = document.querySelectorAll('.check')console.log(checkAll);console.log(inputList);//1.点击全选/全部选 列表选项为全选/全部选的checked属性checkAll.onclick = function () {//列表选项为全选/全部选的checked属性for (let i = 0; i < inputList.length; i++) {inputList[i].checked = this.checked}}//2.累加inputList[i]为true的和 与 inputList[i]的长度相等 则checkAll为true 否则 为falsefor (let i = 0; i < inputList.length; i++) {inputList[i].onclick = function () {/* let sum = 0for (let j = 0; j < inputList.length; j++) {if (inputList[j].checked) {sum++}}checkAll.checked = inputList.length == sum ? true : false */// 3.单击列表选项时,只要有一个input的checked值为false all的值为falselet flag = truefor (let j = 0; j < inputList.length; j++) {if (inputList[j].checked == false) { //inputList[j].checked == false返回的是trueflag = falsebreak}}checkAll.checked = flag}}</script>
3.操作节点
网页的内容由节点组成(node) 元素节点,属性节点,文本节点,注释节点
dom节点操作语法:元素节点
3.1 查找节点
1.查找元素子节点: 父元素.children| 父元素.children[下标]
2.查找父节点 : 元素.parentNode(常用) | 元素.parentElement
3.查找兄弟节点
3.1上一个兄弟元素 : 元素.preveiousElementSibling
3.2下一个兄弟元素 : 元素.nextElementSibling
<script>let ul = document.querySelector('ul')let liT = document.querySelector('#li2')//1.查找子节点console.log(ul.children);//2.查找父节点console.log(liT.parentNode);//3.查找兄弟节点//3.1查找前一个元素节点console.log(liT.previousElementSibling);//3.2查找后一个兄弟元素节点console.log(liT.nextElementSibling);</script>
3.2新增节点
1.创建节点 let li= document.createElement(‘标签名’)
2.设置节点内容 根据需求添加内容
3.追加到页面
3.1追加到ul父元素里的最后面 : 父元素.appendChild(子元素)
3.2追加到指定位置 : 父元素.insertBefore(创建的子元素子元素,要添加到哪个元素的前面) 例如 : ul.insertBefore(li,li2.nextElementSibling)
<script>let ul = document.querySelector('ul')let liList = document.querySelectorAll('li')//1 创建节点let h4 = document.createElement('h4')//2 设置内容h4.innerText = '我是标题'//3 追加到页面ul.appendChild(h4)ul.insertBefore(h4, liList[0])</script>
3.3 克隆节点
克隆节点 又叫 复制节点
元素.cloneNode(布尔类型)
false:不克隆后代元素
ture:克隆所有后代后代 包括自己
<script>document.querySelector('.btn').onclick = function () {//1.克隆节点let copyBox = document.querySelector('.box').cloneNode(true)//2.追加到页面document.body.insertBefore(copyBox, document.body.children[1])}</script>
3.4 删除节点
父元素.removeChild(子元素)
只能删除自己的子元素
<script>let ul = document.querySelector('ul')let li2 = document.querySelector('#li2')document.querySelector('.btn').onclick = function () {ul.removeChild(li2)ul.removeChild(ul.children[3])}</script>
3.5日期对象Date
<script>/*1.js内置对象Date :内置对象 : 由js作者提前写好的,我们直接拿来使用即可。*///1.创建日期对象let d=new Date()console.log(d)//2.1 转换日期格式console.log(d.toLocaleString()) //2021/12/15 下午4:46:16console.log(d.toLocaleDateString()) //2021/12/15console.log(d.toLocaleTimeString()) //下午4:46:16//2.2 获取年月日时分秒console.log(d.getFullYear()) //2021// 1-12月对应0-11下标console.log(d.getMonth()) //11下标, 12月console.log(d.getDate()) //15// 星期天 - 星期六 0-6console.log(d.getDay()) //3console.log(d.getHours()) //16console.log(d.getMinutes()) //47console.log(d.getSeconds()) //48//2.3 获取时间戳/*1.时间戳 : 从1970年1月1日格林威治 到现在 秒数2.时间戳作用 : 兼容世界时区*/console.log(+d) // 日期对象转数字console.log(Date.now()) // 时间戳</script>
案例:微信发布
<script>// maxlength 是一个表单属性, 作用是给表单设置一个最大长度// 模拟数据let dataArr = [{uname: '司马懿',imgSrc: './images/9.5/01.jpg'},{uname: '女娲',imgSrc: './images/9.5/02.jpg'},{uname: '百里守约',imgSrc: './images/9.5/03.jpg'}]/*需求分析:找交互1.文本框输入事件: 获取用户输入文本长度 赋值给 span标签2.发布按钮点击事件:(1) 检测内容是否为空, 为空则不添加内容(2) 根据用户输入内容,生成li元素(3) 将新生成的li元素追加到最前面(4) 重置输入框: 文本 和 数量都要重置3.删除按钮点击事件: 点删除,移除自身所在的li元素* 本案例难点: 动态添加的元素不能直接注册事件* 分析原因: 删除按钮一开始页面是没有的,因此无法获取。 只有用户点击发送按钮,才会动态新增。* 解决方案:* 1.在新增li元素的后面,获取删除按钮并注册事件* 2.事件委托技术(实际开发解决方案,明天学习)*/let area = document.querySelector('#area') //文本框let useCount = document.querySelector('#useCount') //字数let send = document.querySelector('#send')let ul = document.querySelector('#list')let del = document.querySelector('.the_del')// 1.文本框输入事件: 获取用户输入文本长度 赋值给 span标签area.oninput = function () {useCount.innerText = this.value.length}//2.发布按钮点击事件:// (1) 检测内容是否为空, 为空则不添加内容// (2) 根据用户输入内容,生成li元素// (3) 将新生成的li元素追加到最前面send.onclick = function () {// console.log(1)// (1) 检测内容是否为空, 为空则不添加内容if (area.value.trim() == '') {alert('请输入内容哟')return}// (2) 根据用户输入内容,生成li元素// 创建节点let li = document.createElement('li')//设置内容//设置下标为一个随机数let i = parseInt(Math.random() * dataArr.length - 1)console.log(i);li.innerHTML = `<div class="info"><img class="userpic" src=${dataArr[i].imgSrc} /><span class="username">${dataArr[i].uname}</span><p class="send-time">${new Date().toLocaleString()}</p></div><div class="content">${area.value}</div><span class="the_del">X</span>`//追加到页面 父元素.insertBefore(追加的元素,追加到哪个元素的前面)ul.insertBefore(li, ul.children[0])//文本域的内容为空 span标签的文本变0area.value = ''useCount.innerText = 0}// 3.删除按钮点击事件: 点删除,移除自身所在的li元素//事件委托// (1) 给父元素添加点击事件ul.onclick = function (e) {console.log(e.target);if (e.target) {ul.removeChild(e.target.parentNode)}}</script>
案例:图片切换
<script>/*1.点击上一张 跳转到前一张2.点击下一张 跳转到后一张*/let img = document.querySelector('img')let prev = document.querySelector('#prev')let next = document.querySelector('#next')//1.声明个数组,保存图片的路径let imgArr = ["./images/01.jpg","./images/02.jpg","./images/03.jpg","./images/04.jpg","./images/05.jpg"]//2.声明一个变量来存储此时显示的图片(数组的下标)let index = 0//3点击上一张 跳转到前一张prev.onclick = function () {// 如果此时是第一张, 再次点击上一张则跳到最后一张index == 0 ? index = imgArr.length - 1 : index--img.src = imgArr[index]console.log(index)}// 4.点击下一张 跳转到后一张next.onclick = function () {// 如果此时是最后一张, 再次点击下一张则跳到第一张index == imgArr.length - 1 ? index = 0 : index++img.src = imgArr[index]console.log(index)}</script>
二、 事件
实现交互功能 只要是是标签都能注册事件,一个标签可以注册多个事件
1.事件三要素
事件三要素:
事件源:哪个元素
事件类型:当干什么的时候 例如:单击 双击 移入 移除
事件处理函数:做什么事情 或者说发生什么变化
2.注册事件
dom注册事件有两种语法
注册事件:给元素添加交互功能 事件源.事件类型 = 事件处理函数 box.onclick = function (){} 事件工作原理: 注册事件:其本质就是给对象添加方法,函数在声明的时候不会立即执行——相当于声明函数 触发事件:点击元素的时候,浏览器会自动捕捉到交互,主动帮我们调用这个方法——相当于调用函数
2.1 . 点语法不能注册”同名”事件
1.1注册 box.onclick = function(){ alert(1)}
box.onclick = function(){ alert(2)}
上面的会被覆盖
1.2移除 :box.onclick = null
2.2 addEventListener 可以注册多个”同名“事件
2.1注册 事件源.addEventListener(‘事件类型’,事件处理函数)—没有’on‘
box.addEventListener(‘click’,function(){})
2.2移除 box.removeEventListener(‘click’,fn)
只能移除具名事件
<script>let box = document.querySelector('#box')//注册事件/* box.onclick = function () {alert('好好学习')alert('天天向上')} */// fn:函数堆地址 fn():函数返回值let fn = function () {alert('好好学习')}box.addEventListener('click', fn)box.addEventListener('click', function () {alert('天天向上')})box.removeEven</script>
3.事件类型
3.1鼠标事件
鼠标单击:onclick
鼠标双击:ondblclick
鼠标移入和移出:onmouseenter | onmouseleave 推荐
onmouseover | onmouseout 000000….
鼠标移动:onmousemove
3.2键盘事件
键盘输入:oninput
成为焦点:onfocus
失去焦点:onblur
键盘按下:onkeydown
键盘松开:onkeyup
3.3网页事件window
网页鼠标移动:window.onmousemove
网页滚动:window.onscroll
网页尺寸变化:window.onresize
4.事件对象
存储与事件(鼠标、键盘)相关数据
4.1获取事件对象
1.事件对象 : 存储与事件相关的数据。 当我们触发事件的时候,浏览器会自动捕捉触发时的鼠标(坐标点)和键盘信息(按键),存入一个对象中,称之为事件对象。
事件对象: 存储与事件触发相关的数据
事件对象是浏览器自动存储的,我们只需要获取即可
2.获取事件对象 : 给事件处理函数添加形参 event | ev | e
<script>/*1.复习鼠标事件onclick : 鼠标单击ondblclick : 鼠标双击onmouseenter: 鼠标移入onmouseleave: 鼠标移出onmousemove : 鼠标移动2.页面鼠标移动 : window.onmousemove*///给页面注册鼠标移动window.onmousemove = function(e){console.log(e.pageX,e.pageY)let img = document.querySelector('img')//获取事件对象的page坐标, 赋值给图片的定位属性即可(需要注意left有单位px)img.style.left = e.pageX + 'px'img.style.top = e.pageY + 'px'}</script>
4.2事件对象常用属性或方法
获取鼠标出发点到页面左上角距离 e.pageX / e.pageY
获取案件字符串 ’Enter‘ e.key
获取键盘ASCII码 enter键13 e.keyCode
阻止默认事件(行为) e.preventDefault()
应用场景:
a : 点击默认跳转到href属性链接
form : 点击默认跳转到action属性对应的链接
事件触发源。 获取真正触发事件的子元素,用于事件委托 e.target
阻止事件流 (冒泡 + 捕获都能阻止) e.stopPropagation()
5.事件冒泡
事件冒泡 : 触发子元素事件,所有的父级元素‘同名事件’会被依次触发 元素->父元素->body->html->document->window
<script>/*1.事件冒泡 : 当触发子元素的事件的时候, 所有的父级元素‘同名事件’都会被依次触发元素->父元素->body->html->document->window2.事件委托 :事件委托原理 :事件冒泡*///子元素document.querySelector('.son').onclick = function(){alert('我是子元素')}//父元素document.querySelector('.father').onclick = function(){alert('我是父元素')}//bodydocument.body.onclick = function(){alert('我是body')}//htmldocument.documentElement.onclick = function(){alert('我是html')}//documentdocument.onclick = function(){alert('我是document')}//windowwindow.onclick = function(){alert('我是window')}</script>
6.事件委托
给父元素注册事件,委托子元素处理
事件委托的原理就是事件冒泡
事件委托应用场景 :
(1)实际开发最多: 给动态新增的子元素注册事件
(2)性能优化 : 如果所有的子元素都需要注册同名事件,只需要给父元素注册
事件委托注意点 :
(1)事件委托不能通过this找到子元素。 (this指向父元素)
(2)事件委托需要通过什么属性找到子元素: e.target
//需求:给每一个li元素注册点击事件let ul = document.querySelector('ul')//2.事件委托 : 给父元素注册事件,委托给子元素处理ul.onclick = function(e){/* this : 事件源,父元素ule.target : 真正点击的子元素*/alert(e.target.innerText)console.log(e)}/* 如果一个元素是动态新增的 : 一开始没有,页面加载后使用dom新增语法添加的 */document.querySelector('.btn').onclick = function(){let li = document.createElement('li')li.innerText = '我是新来的'ul.appendChild(li)}
案例:DOM综合表格案例
<script>/* 思路分析1.点击录入 :(注意点form表单中的按钮需要阻止默认事件)1.1 非空判断 : 姓名、年龄、薪资不能为空1.2 新增tr元素* (1)创建tr (2)设置内容 (3)添加到table>tbody1.3 清空form表单2.点击删除 : 使用事件委托技术2.1 点击删除, 删除tr标签 ( 删除按钮的父元素的td, td的父元素是tr)3.上移4.下移*///1.获取元素let uname = document.querySelector('.uname')let age = document.querySelector('.age')let gender = document.querySelector('.gender')let salary = document.querySelector('.salary')let city = document.querySelector('.city')let add = document.querySelector('.add')//2.1 点击录入add.onclick = function(e){/* 注意点:form表单元素中的按钮需要阻止默认条件 */e.preventDefault()//3.1 非空判断 : 姓名、年龄、薪资不能为空if( uname.value.trim() == '' || age.value.trim() == '' || salary.value.trim() == ''){alert('输入框不能为空')}else{//3.2 新增元素//(1)创建空tr标签let tr = document.createElement('tr')//(2)设置内容tr.innerHTML = `<td>1001</td><td>${ uname.value }</td><td>${ age.value }</td><td>${ gender.value }</td><td>${ salary.value }</td><td>${ city.value }</td><td><a href="javascript:" class="up">上移</a><a href="javascript:" class="down">下移</a><a href="javascript:" class="delete">删除</a></td>`//(3)添加到tbodydocument.querySelector('tbody').appendChild(tr)}//3.3 表单清空 form.reset()document.querySelector('form').reset()}//2.2 使用事件委托给删除按钮注册点击事件document.querySelector('tbody').onclick = function(e){//点击tbody任意区域都会触发点击事件, 真正委托的是删除按钮let tr = e.target.parentNode.parentNode//3.1 多分支判断到底是哪一个按钮: 删除、上移、下移if( e.target.classList.contains('delete') ){//(1)删除this.removeChild( tr )}else if( e.target.classList.contains('up') ){//(2)上移//判断tr是不是第一个儿子if( tr.previousElementSibling ){//有哥哥可以上移//上移:移到tr哥哥的前面this.insertBefore(tr,tr.previousElementSibling)}else{alert('已经是第一个了')}}else if( e.target.classList.contains('down') ){//(3)下移//判断tr是不是最后一个儿子if( tr.nextElementSibling ){//下移: 移到 弟弟的弟弟的前面this.insertBefore( tr, tr.nextElementSibling.nextElementSibling )}else{alert('已经是最后一个了')}}}</script>
事件流三个阶段
事件流三个阶段 e.eventPhase<br /> 1-捕获阶段<br /> 2-目标阶段<br /> 3-冒泡阶段
三、 网页特效(尺寸、定时器)
1.定时器
定时器语法 :
setInterval永久定时器
setInterval : 永久定时器。 一旦开启永久重复执行,只能手动清除
开启: let timeID = setInterval( function(){}, 间隔时间 )
清除: clearInterval( timeID )
setTimeout一次定时器
setTimeout() : 一次定时器。 间隔时间只会执行一次,之后自动清除
开启: let timeID = setTimeout( function(){}, 间隔时间 )
清除: clearTimeout( timeID )
案例 :倒计时秒杀
<script>/* 秒杀思路1.页面一加载,开启间隔 1s 的永久定时器1.1 获取当前页面span标签的文本 h m s (转number)1.2 s--1.3 如果 s < 0,s = 59,m--1.4 如果 m < 0, m = 59,h--1.5 如果h m s < 10 , 则需要补01.6 将计算之后的结果重新赋值给元素的innerText//只是修改h m s的值,并没有修改页面元素的内容1.7 清除定时器:h == 0 && m == 0 && s == 0*/let timeID = setInterval( function(){//1.1 获取当前页面span标签的文本 h m s (转number)let h = +document.querySelector('#hour').innerTextlet m = +document.querySelector('#minute').innerTextlet s = +document.querySelector('#second').innerText//1.2 s--s--//1.3 如果 s < 0,s = 59,m--if(s < 0 ){s = 59m--}//1.4 如果 m < 0, m = 59,h--if(m < 0 ){m = 59h--}//1.5 如果h m s < 10 , 则需要补0h = h < 10 ? '0' + h : hm = m < 10 ? '0' + m : ms = s < 10 ? '0' + s : s//1.6 将计算之后的结果重新赋值给元素的innerTextdocument.querySelector('#hour').innerText = hdocument.querySelector('#minute').innerText = mdocument.querySelector('#second').innerText = s//1.7 清除定时器:h == 0 && m == 0 && s == 0if( h == 0 && m == 0 && s == 0){clearInterval(timeID)}},1000)</script>
2.三大家族—offset scroll clinet
特点: 1.获取的是数字类型(number) 2.只能获取,不能设置 (scrollTop | scrollLeft可以设置)
2.1 offset 获取’元素自身’的真是宽高与位置
offsetWidth/Height —获取’自身’宽高
offsetLeft/Top —获取’自身’位置
2.2 scroll 获取’元素内容’的真实宽高与位置
scrollWidth/Height —获取元素’内容’的宽高
scrollLeft/Top —元素内容滚动出去的距离
2.3 client 获取元素’可视区域’的宽高与位置
clientWidth/Height
clientLeft/Top
获取网页滚动距离
document.documentElement.scrollTop = 400
<script>/* 学习目标:获取网页滚动距离1.给网页注册滚动事件 : window.onscroll2.获取网页滚动距离 : document.documentElement.scrollLeftdocument.documentElement.scrollTop*///1.给页面注册滚动条事件window.onscroll = function(){//2.获取页面滚动距离 : html标签console.log( document.documentElement.scrollLeft,document.documentElement.scrollTop );};</script>
案例:电梯导航
<script>let asideList = document.querySelectorAll('.aside>.item')let conList = document.querySelectorAll('.content>div')console.log(asideList, conList);// 1.点击左边侧边栏for (let i = 0; i < conList.length; i++) {asideList[i].onclick = function () {console.log(i);//清除类名有active的元素 ,给点击的元素添加activedocument.querySelector('.active').classList.remove('active')this.classList.add('active')//并让网页跳转到对应的图片document.documentElement.scrollTop = conList[i].offsetTopconsole.log(conList[i].offsetTop);}}//2.网页滚动事件window.onscroll = function () {console.log(document.documentElement.scrollTop)for (let i = 0; i < conList.length; i++) {console.log(conList[i].offsetTop);if (conList[i].offsetTop >= document.documentElement.scrollTop) {document.querySelector('.item.active').classList.remove('active')asideList[i].classList.add('active')break}}}</script>
案例:轮播图
<script>//获取元素let indicatorList = document.querySelectorAll('.indicator li') //导航列表let slidesList = document.querySelectorAll('.slides li') //大图片let h3 = document.querySelector('.extra h3')let next = document.querySelector('.extra .next') //下一页let prev = document.querySelector('.extra .prev') //上一页let n = 0 //保存图片下标let main = document.querySelector('.main')console.log(indicatorList)console.log(slidesList)console.log(h3, next, prev)//鼠标移入indicator里的lifor (let i = 0; i < indicatorList.length; i++) {indicatorList[i].onmouseenter = function () {lunbo(i)//点击和移动事件的下标要一致n = i}}//鼠标点击下一页next.onclick = function () {// 如果下标等于数组的最后一个 否则i++n == slidesList.length - 1 ? n = 0 : n++lunbo(n)}//鼠标点击上一页prev.onclick = function () {// 如果下标等于第一个的时候 变到左后一个 否则i--n == 0 ? n = slidesList.length - 1 : n--lunbo(n)}//封装函数--排他思想function lunbo(index) {//1.修改自身的样式document.querySelector('.indicator .active').classList.remove('active')indicatorList[index].classList.add('active')//2。修改对应的图片document.querySelector('.slides .active').classList.remove('active')slidesList[index].classList.add('active')h3.innerHTML = `第${index+1}张图的描述信息`}// 定时器let timeID = setInterval(function () {//调用下一页,定时器会触发next.onclick()}, 500)//鼠标移入盒子 清除定时器main.onmouseenter = function () {clearInterval(timeID)}//鼠标移出盒子 恢复定时器main.onmouseleave = function () {timeID = setInterval(function () {//调用下一页next.onclick()}, 500)}</script>
四、BOM —一套操作浏览器窗口的函数
BOM(Browser Object Model) 是指浏览器对象模型,是用于描述这种对象与对象之间层次关系的模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。
1.五个对象
1.1 window浏览器窗口
1. window特点1. 是JS中的顶级对象,所有的全局函数和全局对象都是window的成员1. window对象的成员在使用时可以省略window2. window对象方法1. 打开新窗口:window.open():可以四个参数
window.open(‘http://www.baidu.com','_blank','left=300,top=100,width=500,height=500‘)
2. 关闭窗口: window.close()3. window对象事件1. **window.onload() -->DOM树+外部资源 加载完毕后执行**1. window.onbeforeunload():页面关闭前
1.2location:浏览器地址栏
- 跳转网页:可以回退
location.href =’url’ —属性
location.assign(‘url) —方法
- 替换网页:不能回退
location.replace(url)
- 刷新网页
1.3history:历史记录
history三个方法:
history.back() : 返回上一页 等价于 history.go(-1)
history.forward() : 前进下一页 等价于 history.go(1)
history.go( 数字 ) : 到历史记录的具体哪一页
正数: 前进 1:前进1页 2:前进2页
0 :刷新页面
负数: 回退 -1:回退1页 -2:回退2页
1.4navigator:浏览器信息
console.log( navigator.userAgent )//用户代理: 浏览器型号,内核。 计算机操作系
1,5screen:屏幕分辨率
2.存储对象localStorage与sessionStroage
1.localStorage硬盘存储(存储在本地)
1.localStorage对象作用 : 存储数据
经典应用: 免登录
2.localStorage语法 :
存数据: localStorage.setItem(‘属性名’,属性值)
取数据: localStorage.getItem(‘属性名’)
删数据: localStorage.removeItem(‘属性名’)
* 清空数据: localStorage.clear()
3.localStorage注意点 :
3.1 永久存储 : 除非手动清除,否则一直存在
3.2 只能存储字符串类型,如果存储其他类型,编译器会自动toString()转成字符串来存储
2.sessionStroage 内存存储(临时存储)
1.sessionStorage对象作用 : 存储数据<br /> 2.sessionStorage语法 :<br /> * 存数据: sessionStorage.setItem('属性名',属性值)<br /> * 取数据: sessionStorage.getItem('属性名')<br /> * 删数据: sessionStorage.removeItem('属性名')<br /> * 清空数据: sessionStorage.clear()<br /> 3.sessionStorage注意点 : <br /> 3.1 临时存储 : 只要页面关闭了,就自动清除了<br /> 3.2 只能存储字符串类型,如果存储其他类型,编译器会自动toString()转成字符串来存储
3.localStorage和sessionStorage的注意点
1.localStorage和sessionStorage的区别?
相同点: 作用相同,都是存储数据
不同点:存储方式不同
localStorage : 硬盘存储(永久存储)
应用场景: 免登录
sessionStorage : 内存存储 (临时存储)
应用场景: 页面间传值
2.localStorage和sessionStorage在用的时候有什么注意点吗?
只能存储字符串类型数据, 如果存储其他类型则编译器自动调用toString()转成字符串
3.如何解决storage存储对象只能存储字符串问题? (如何存储引用类型)
使用json格式存储
3,JSON格式数据介绍
1.json是什么? : json是一种数据格式,本质是字符串类型
实际开发中,网页中的数据都是来源于网络服务器。 而服务器不是js语言开发,而是其他编程语言 : java、c++、python、go、c#、.net …. 而且后台也不是只为前端服务,也要为安卓端和ios 端服务器。
不同的编程语言,数据类型不同。他们是不互通的。后来人们就发明了一种通用的数据格式,让所有的编程语言都支持。这就是json格式。
2.json作用 ? : 数据跨平台传输问题
3.json语法 ? : 本质是字符串
3.1 json转js : let js对象 = JSON.parse(json格式)
3.2 js转json : let json格式 = JSON.stringify(js对象)
<script>/*json转js 返回js对象 let obj = JSON.parse(json格式)js转json 返回JSON格式 let objJSON = JSON.stringify(js对象)*/// js对象let obj = {name: 'pengyuyan',age: 18}// 1.js转JSONlet JSON1 = JSON.stringify(obj)// JSON格式 本质是字符串let objJSON = '{"name":"zhang","age":"80"}'// 2.JSON转jslet js = JSON.parse(objJSON)</script>
案例:保存用户信息
<script>/*1.分析需求(交互):点击登录按钮 : (1)判断用户名密码长度 : 全部大于6 登录成功(2)如果登录成功(2.1)将用户名和密码写入本地存储,下一次登录时直接显示用户名和密码(2.2)跳转网页 http://www.itheima.com2.思路分析(事件三要素)获取元素:事件源:注册事件:事件类型事件处理:*/let login = document.querySelector('.input_sub') //登录let text = document.querySelector('.input_txt') //账号let pass = document.querySelector('.input_pass') //密码console.log(login, text, pass)login.onclick = function () {if (text.value.length <= 6 || pass.value.length <= 6) {alert('请输入正确的账号和密码')text.value = ''pass.value = ''return}//存入本地localStorage.setItem('txt', text.value)localStorage.setItem('pass', pass.value)//跳转网页location.href = 'http://www.itheima.com'}window.onload = function () {//页面加载完成后,把在本地的账号和密码赋值给文本框的文本text.value = localStorage.getItem('txt')pass.value = localStorage.getItem('pass')}</script>
