前端 --- WEB APIS (Dom / Bom 操作)
0.简介
0.1 干什么的?
DOM (Document Object Model --- 文档对象模型),是浏览器提供的一套专门用来操作网页内容的功能
0.2 DOM树
将HTML文档以树状结构直观的表现出来,称之为文档树或DOM树,用以描述网页内容关系的名词,文档树直观的体现了标签与标签之间的关系

0.2 DOM对象
浏览器根据html标签生成的JS对象,所有的标签属性都可以在这个对象上面找到,修改这个对象的属性会自动映射到标签身上,即当网页内容当做对象来处理
1. 获取DOM元素
1.1 css 选择器
1. 获取一个
document.querySelector("ul li:nth-child(1)")
2. 获取所有
document.querySelectorAll("ul li")
2. 操作DOM元素
2.1 文本内容
1. innerText
innerText 不识别字符串中的标签
const li1 = document.querySelector("ul li:first-child")
i1.innerText = "<strong>hello</strong>"
2. innerHTML
innerHTML 识别字符串中的标签
const li1 = document.querySelector("ul li:first-child")
i1.innerHTML = "<strong>hello</strong>"
2.2 标签的 CSS 样式
1. 手动添加
const box = document.querySelector(".box")
box.style.height = "200px"
box.style.width = "200px"
box.style.backgroundColor = "orange"
2. 添加类名,覆盖之前
<style>
.box {
width: 200px;
height: 200px;
background-color: gray;
}
</style>
<div>1</div>
<script>
const box = document.querySelector("div")
box.className = "box" // 给div标签添加box类名,就有了这些CSS属性,注意会覆盖之前的所有类名
</script>
3. 追加类名,不覆盖
const box = document.querySelector("div")
// 追加类名
box.classList.add("box")
// 删除类名
box.classList.remove("box")
// 切换类名 -- 有box类名,则删除这个类名,没有就追加
box.classList.toggle("box")
// 是否有类名
box.classList.contains("box")
2.3 表单属性
0. 表单代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="#">
<!-- 文本输入框 -->
<label for="userName">用户名:</label>
<input id="userName" type="text">
<br>
<!-- 密码输入框 -->
<label for="pwd">密码:</label>
<input id="pwd" type="password">
<br>
<!-- 单选框 -->
<input type="radio" name="sex">男
<input type="radio" name="sex">女
<br>
<!-- 多选框 -->
<input type="checkbox" name="hobby">抽烟
<input type="checkbox" name="hobby">喝酒
<input type="checkbox" name="hobby">烫头
<br>
<!-- 单选下拉框 -->
<select name="city" id="city">
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">广州</option>
</select>
<br>
<!-- 多选下拉框 -->
<select name="tag" id="tag" multiple>
<option value="1">宅男</option>
<option value="2">二次元</option>
<option value="3">直男</option>
</select>
</form>
</body>
</html>
1. 获取输入框的值
const uName = document.querySelector("#userName")
uName.value
2. 设置输入框的值
const uName = document.querySelector("#userName")
uName.value = 123
3. 修改输入框的属性
1. 修改输入框的类型
const uName = document.querySelector("#userName")
uName.type = "password" // 将文本输入框改为密码输入框
2. 输入框 / 选择框的禁用效果
const uName = document.querySelector("#userName")
uName.disabled = true // 禁用
uName.disabled = false // 取消禁用
3. 单选框 / 多选框 的选中效果
// 单选框
const sexSelector = document.querySelectorAll("[name='sex']")
sexSelector[0].checked = true // true为选中,false为不选中
// 多选框
const hobby = document.querySelectorAll("[type='checkbox']")
hobby[0].checked = true // true为选中,false为不选中
hobby[1].checked = true // true为选中,false为不选中
4. 单选下拉框 / 多选下拉框 的选中效果
// 单选下拉框
const city = document.querySelector("#city")
city[2].selected = true // true为选中,false为不选中
// 多选下拉框
const city = document.querySelector("#tag")
city[1].selected = true
city[2].selected = true
2.4 自定义属性
设置自定义属性
<!-- 以data-属性名定义的属性,都是自定义属性 -->
<div class="demo" data-x="1" data-y="2">1</div>
获取自定义属性的值
const demo = document.querySelector(".demo")
demo.dataset.x
demo.dataset.y
3. 定时器
3.1 间歇函数
到达一定时间,执行一次,持续执行
1. 声明
1. 匿名回调函数
setInterval(function () {
console.log(1)
},1000) // 时间间隔,以毫秒为单位
2. 具名回调函数
function printer() {
console.log(1)
}
setInterval(printer,1000) // 以毫秒为单位
2. 清除
// 具名回调函数
function printer() {
console.log(1)
}
// 开启定时器
let timerID = setInterval(printer,1000) // 以毫秒为单位
// 根据开启定时器的返回值,关闭定时器
clearInterval(timerID)
3. 案例
1. 用户协议倒计时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button class="btn" disabled>我已同意用户协议(60)</button>
<script>
let count = 5
function printer() {
count--
const btn = document.querySelector(".btn")
btn.innerHTML = `我已同意用户协议(${count})`
if (count <= 0) {
btn.disabled = false
btn.innerHTML = `同意`
clearInterval(timerID)
}
}
let timerID = setInterval(printer, 1000) // 以毫秒为单位
</script>
</body>
</html>
3.2 延时函数
一定时间后执行一次,只执行一次
1. 声明
1. 匿名回调函数
setTimeout(function () {
console.log(1)
},1000) // 时间间隔,以毫秒为单位
2. 具名回调函数
function printer() {
console.log(1)
}
setTimeout(printer,1000) // 以毫秒为单位
2. 清除
// 具名回调函数
function printer() {
console.log(1)
}
// 开启定时器
let timerID = setTimeout(printer,1000) // 以毫秒为单位
// 根据开启定时器的返回值,关闭定时器
clearTimeout(timerID)
3. 案例
1. 5 秒后自动关闭的广告
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.dady{
position: relative;
width: 1000px;
height: 200px;
background-color: pink;
margin: 100px auto;
text-align: center;
font-size: 50px;
line-height: 200px;
font-weight: 700;
}
.baby{
position: absolute;
right: 20px;
top: 10px;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="dady">
我是广告1
<div class="baby">x</div>
</div>
<script>
function clearGuanggao() {
const dady = document.querySelector(".dady")
dady.style.display = "none"
}
setTimeout(clearGuanggao,5000)
</script>
</body>
</html>
3.3 对比
- 延时函数: 只执行一次
- 间歇函数: 每隔一段时间就执行一次,除非手动清除
4. 事件监听
4.1 事件绑定
1. 事件监听添加事件
const btn = document.querySelector(".btn")
btn.addEventListener("click",function (event) {
})
2. on添加事件
<button class="btn" onclick="printer()">同意</button>
<button class="btn" ononmouseenter="printer()">同意</button>
<script>
function printer() {
console.log(1)
}
</script>
3. 区别
1. 传统 on 绑定事件
- 同一个对象,后面注册的事件会覆盖前面注册的事件(同一个事件)
- 直接使用null覆盖就可以实现事件的解绑
- 都是冒泡阶段执行
2. 事件监听注册
- 后面注册的事件不会覆盖前面注册的事件(同一个事件)
- 可以通过第三个参数确定是在冒泡或者捕获阶段执行
- 必须使用removeEventListener(事件类型,事件处理函数,是否使用事件捕获)
- 匿名函数无法被解绑
4.2 鼠标事件
1. 点击事件
const btn = document.querySelector(".btn")
btn.addEventListener("click",function (event) {
})
2. 鼠标经过
const btn = document.querySelector(".btn")
// mouseover,有事件冒泡效果,不推荐
btn.addEventListener("mouseenter",function (event) {
})
3. 鼠标离开
const btn = document.querySelector(".btn")
// mouseout,有事件冒泡效果,不推荐
btn.addEventListener("mouseleave",function (event) {
})
4.3 焦点事件
1. 获得焦点
const userName = document.querySelector(".userName")
userName.addEventListener("focus",function (event) {
})
2. 失去焦点
const userName = document.querySelector(".userName")
userName.addEventListener("blur",function (event) {
})
4.4 键盘事件
1. 键盘按下
const userName = document.querySelector(".userName")
userName.addEventListener("keydown",function (event) {
})
2. 键盘抬起
const userName = document.querySelector(".userName")
userName.addEventListener("keyup",function (event) {
})
4.5 文本输入事件
const userName = document.querySelector(".userName")
userName.addEventListener("input",function (event) {
console.log(userName.value)
})
4.6 音视频事件
1. 播放位置发生改变
const video = document.querySelector("video")
video.ontimeupdate = function (e) {
console.log(e.timeStamp) // 获取当前播放的时间
}
2. 加载完毕后,未开始播放前只触发一次
音视频框加载完成后,并未开始播放时只触发一次
const video = document.querySelector("video")
video.onloadeddata = function (e) {
console.log(e.timeStamp) // 获取当前播放的时间
}
4.7 事件对象 --- event
1. 使用场景
- event中有事件触发时的相关信息
- 鼠标点击事件中,事件对象中保存了鼠标点在哪个位置等信息
- 可以使用事件对象来判断用户按下了什么按键,来执行什么操作
2.常见属性
1. type
获取当前的事件类型
2. clientX / clientY
获取光标相对于浏览器窗口左上角的位置
**3. offsetX / offsetY **
获取光标相对于当前DOM元素左上角的位置
**4. key **
获取用户按下的键盘的值
5. target
当前点击的DOM对象
target.classList // 类名列表
target.classList.contains("del") // 类名列表中是否包含del的类名
4.8 事件流
事件流指的是事件完整执行过程中的流动路径

4.9 事件捕获
简单来说,捕获是父到子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.father{
width: 400px;
height: 400px;
background-color: pink;
}
.son{
width: 200px;
height: 200px;
background-color: orange;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
document.addEventListener("click",function () {
alert("我是爷爷元素")
},true) // 第三个参数传入true,用于开启事件捕获
const father = document.querySelector(".father")
father.addEventListener("click",function () {
alert("我是父亲元素")
},true) // 第三个参数传入true,用于开启事件捕获
const son = document.querySelector(".son")
son.addEventListener("click",function () {
alert("我是儿子元素")
},true) // 第三个参数传入true,用于开启事件捕获
</script>
</body>
</html>
4.10 事件冒泡
1. 冒泡现象
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这一过程被称为事件冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.father{
width: 400px;
height: 400px;
background-color: pink;
}
.son{
width: 200px;
height: 200px;
background-color: orange;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
document.addEventListener("click",function () {
alert("我是爷爷元素")
}) // 第三个参数插入false或者不传,就是事件冒泡,默认为事件冒泡机制
const father = document.querySelector(".father")
father.addEventListener("click",function () {
alert("我是父亲元素")
}) // 第三个参数插入false或者不传,就是事件冒泡,默认为事件冒泡机制
const son = document.querySelector(".son")
son.addEventListener("click",function () {
alert("我是儿子元素")
}) // 第三个参数插入false或者不传,就是事件冒泡,默认为事件冒泡机制
</script>
</body>
</html>
2. 阻止事件流
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.father{
width: 400px;
height: 400px;
background-color: pink;
}
.son{
width: 200px;
height: 200px;
background-color: orange;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
document.addEventListener("click",function () {
alert("我是爷爷元素")
})
const father = document.querySelector(".father")
father.addEventListener("click",function () {
alert("我是父亲元素")
})
const son = document.querySelector(".son")
son.addEventListener("click",function (e) {
alert("我是儿子元素")
e.stopPropagation() // 阻止事件流动,包括捕获和流动
})
</script>
</body>
</html>
4.11 事件解绑
1. onclick 解绑
// 绑定事件
btn.onclick = function () {
alert("点击了")
}
// 解绑事件
btn.onclick = null
// 事件只触发一次
btn.onclick = function () {
alert("点击了")
btn.onclick = null
}
2. addEventListener 解绑
// 必须是具名函数
function fn() {
alert("我是儿子元素")
}
// 绑定事件
btn.addEventListener("click",fn)
// 解绑事件
btn.removeEventListener("click",fn)
4.12 事件委托
1. 原理
利用事件冒泡的特点完成事件委托, 原理就是,只给父元素注册事件,当触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件
2. 示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.changeColor {
color: red;
}
</style>
</head>
<body>
<ul>
<li>我是第一个li</li>
<li>我是第二个li</li>
<li>我是第三个li</li>
<li>我是第四个li</li>
<li>我是第五个li</li>
<li>我是第六个li</li>
<p>我是p标签</p>
</ul>
<script>
const ul = document.querySelector("ul")
ul.addEventListener("click",function (e) {
// e.target 就是当前点击的那个对象
// 只点击li标签才有变色效果
if (e.target.tagName === "LI"){
e.target.classList.add("changeColor")
}
// 查看target对象上的属性和方法
console.dir(e.target)
})
</script>
</body>
</html>
3. 优点 / 好处
- 减少注册次数,提高程序性能
4.13 阻止元素默认行为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.changeColor {
color: red;
}
</style>
</head>
<body>
<form action="#">
姓名: <input type="text" name="username">
<br>
<input type="submit"></input>
</form>
<script>
const form = document.querySelector("form")
form.addEventListener("submit",function (e) {
e.preventDefault() // 阻止form表单的默认行为
})
</script>
</body>
</html>
4.14 页面加载事件
1. 等待页面元素完全加载完毕
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.changeColor {
color: red;
}
</style>
</head>
<body>
<script>
// 等待页面所有资源完全加载完毕,立刻执行回调函数
window.addEventListener("load",function () {
const btn = document.querySelector("button")
btn,addEventListener("click",function () {
alert(1)
})
})
</script>
<button>点击</button>
</body>
</html>
2. 不等待样式表、图像等完全加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.changeColor {
color: red;
}
</style>
</head>
<body>
<script>
// 等待初始的HTML文旦完全加载和解析完成后,触发 DOMContentLoaded 事件,无需等待样式表、图像等完全加载,立刻执行回调函数
domcument.addEventListener("DOMContentLoaded",function () {
const btn = document.querySelector("button")
btn,addEventListener("click",function () {
alert(1)
})
})
</script>
<button>点击</button>
</body>
</html>
4.15 页面滚动事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.changeColor {
color: red;
}
</style>
</head>
<body>
<script>
window.addEventListener("scroll",function (e) {
document.documentElement.scrollLeft // 左侧被拉过的像素值
document.documentElement.scrollTop // 顶部被拉过的像素值
})
document.documentElement.scrollTop = 500 // 打开页面滚动条就滑动了500px的距离
window.scrollTo(0,0) // 滚动条到顶部
</script>
<button>点击</button>
</body>
</html>
4.16 页面尺寸事件
// 检测窗口尺寸
document.documentElement.clientWidth // 获取元素的宽度,不包含border,包含padding,document.documentElement为html元素
document.documentElement.clientHeight // 获取元素的高度,不包含border,包含padding,document.documentElement为html元素
document.documentElement.offsetWidth // 获取元素的宽度,包含border,padding,content,document.documentElement为html元素
document.documentElement.offsetHeight // 获取元素的高度,包含border,padding,content,document.documentElement为html元素
document.documentElement.offsetLeft // 获取元素距离自己带有定位属性的父级元素的左边距离
document.documentElement.offsetTop // 获取元素距离自己带有定位属性的父级元素的上边距离
document.documentElement.getBoundingClientRect() // 获取元素的大小及其相对于视口的位置
// 窗口尺寸改变时触发事件
window.addEventListener("resize",function () {
})
4.16 移动端事件
1. 触屏事件
1. 手指触摸到一个 DOM 元素时触发的事件
const dady = document.querySelector(".dady")
dady.addEventListener("touchstart",function () {
console.log(1)
})
2. 手指在一个 DOM 元素上滑动时触发
const dady = document.querySelector(".dady")
dady.addEventListener("touchmove",function () {
console.log(1)
})
3. 手指在一个 DOM 元素上移开时触发
const dady = document.querySelector(".dady")
dady.addEventListener("touchchend",function () {
console.log(1)
})
5. 环境对象 this
是指函数内部特殊的变量 this , 它代表着当前函数运行时所处的环境
函数的调用方式不同,this 指向的对象也不同,原则是,谁调用的这个函数,这个函数中的 this 就是谁
6. 日期对象
6.1 实例化
1. 获取当前时间
const date = new Date()
2. 获取指定时间
const date = new Date("2022-5-1 08:30:00")
6.2 常用方法
1. 获取年份
const date = new Date()
date.getFullYear()
2. 获取月份
const date = new Date()
date.getMonth() + 1 // 取到的月份是0-11,需要手动+1
3. 获取天
不同月份,取值也不相同
const date = new Date()
date.getDate()
4. 获取星期几
星期天是0,范围是 0 - 6
const date = new Date()
date.getDay()
5. 获取小时
const date = new Date()
date.getHours()
6. 获取分钟
const date = new Date()
date.getMinutes()
7. 获取秒
const date = new Date()
date.getSeconds()
8. 获取格式化后的日期
const date = new Date()
return date.toLocaleString() // 2024/5/8 16:24:56
9. 获取年月日
const date = new Date()
return date.toLocaleDateString() // 2024/5/8
10. 获取时分秒
const date = new Date()
return date.toLocaleTimeString() // 16:24:56
6.3 时间戳
从1970年01月01日00时00分00秒起至现在的毫秒数
将来的时间戳 - 当前时间戳 = 剩余的毫秒数 / 1000 = 秒数
方法一:
// 获取当前时间戳
const date = new Date()
date.getTime()
// 获取指定时间戳
const date = new Date("2024-5-8 16:24:56")
date.getTime()
方法二:
// 获取当前时间戳
const time = +new Date()
// 获取指定时间戳
const time = +new Date("2024-5-8 16:24:56")
**方法三: **
// 只能获取当前时间戳
const time = Date.now()
6.4 案例
1. 同步显示时间在页面中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="dateContent"></div>
<script>
const dateContent = document.querySelector(".dateContent")
function getDate() {
const date = new Date()
let y = date.getFullYear()
let m = date.getMonth() + 1
let d = date.getDate()
let H = date.getHours()
let M = date.getMinutes()
let S = date.getSeconds()
return `${y}-${m}-${d} ${H < 10 ? "0" + H : H}:${M < 10 ? "0" + M : M}:${S < 10 ? "0" + S : S}`
}
dateContent.innerHTML = getDate()
setInterval(function () {
dateContent.innerHTML = getDate()
},1000)
</script>
</body>
</html>
2. 显示星期几
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="dateContent"></div>
<script>
const dateContent = document.querySelector(".dateContent")
function getDate() {
const date = new Date()
const arr = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
let D = date.getDay()
return `${arr[D]}`
}
dateContent.innerHTML = getDate()
setInterval(function () {
dateContent.innerHTML = getDate()
}, 1000)
</script>
</body>
</html>
3. 倒计时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="today"></div>
<br>
<div class="leave">
<div>下班倒计时</div>
<div class="leaveTime"></div>
</div>
<br>
<div class="leaveTime"> 17:30:00 下班</div>
<script>
const today = document.querySelector(".today")
const dateContent = document.querySelector(".dateContent")
const leaveTime = document.querySelector(".leave .leaveTime")
function getDateString() {
const date = new Date()
let y = date.getFullYear()
let m = date.getMonth() + 1 // 月份记得 + 1
let d = date.getDate()
let H = date.getHours()
let M = date.getMinutes()
let S = date.getSeconds()
return `${y}-${m}-${d} ${H < 10 ? "0" + H : H}:${M < 10 ? "0" + M : M}:${S < 10 ? "0" + S : S}`
}
function leaveCountTime() {
const nowdate = +new Date() // 当前时间戳
const localDate = new Date()
const leaveDate = +new Date(localDate.toLocaleDateString() + " 17:30:00") // 将来时间戳
let allTime = (leaveDate - nowdate) / 1000 // 得到的是毫米,记得除以1000
let h = parseInt(allTime / 60 / 60 % 24) // 计算出小时
let m = parseInt(allTime / 60 % 60) // 计算出分钟
let s = parseInt(allTime % 60) // 计算出秒
return `${h < 10 ? "0" + h : h}:${m < 10 ? "0" + m : m}:${s < 10 ? "0" + s : s}` // 补零操作
}
today.innerHTML = "今天是 " + getDateString()
setInterval(function () {
today.innerHTML = "今天是 " + getDateString()
}, 1000)
leaveTime.innerHTML = leaveCountTime()
setInterval(function () {
leaveTime.innerHTML = leaveCountTime()
}, 1000)
</script>
</body>
</html>
7. 节点操作
7.1 获取父节点
获取最近一级的父节点
1. 语法
const baby = document.querySelector(".baby")
baby.parentNode
2. 示例
需求: 点击右上角的 x,隐藏整个盒子
效果图

代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.dady{
position: relative;
width: 1000px;
height: 200px;
background-color: pink;
margin: 100px auto;
text-align: center;
font-size: 50px;
line-height: 200px;
font-weight: 700;
}
.baby{
position: absolute;
right: 20px;
top: 10px;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="dady">
我是广告
<div class="baby">x</div>
</div>
<script>
// 绑定在子元素,查找自己的父节点,隐藏父元素节点
const baby = document.querySelector(".baby")
baby.addEventListener("click",function () {
this.parentNode.style.display = "none"
})
// 使用事件委托,事件绑定在父元素,当点击子元素时,事件冒泡到父元素,触发自己所绑定的点击事件
const dady = document.querySelector(".dady")
dady.addEventListener("click",function () {
this.style.display = "none"
})
</script>
</body>
</html>
需求: 多个盒子,点击右上角的 x,隐藏整个盒子
效果图

代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.dady{
position: relative;
width: 1000px;
height: 200px;
background-color: pink;
margin: 100px auto;
text-align: center;
font-size: 50px;
line-height: 200px;
font-weight: 700;
}
.baby{
position: absolute;
right: 20px;
top: 10px;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="dady">
我是广告1
<div class="baby">x</div>
</div>
<div class="dady">
我是广告2
<div class="baby">x</div>
</div>
<script>
// 找到多个元素,循环为每个元素为其绑定点击事件,关闭其父元素节点
const baby = document.querySelectorAll(".baby")
for (let i = 0;i<baby.length;i++){
baby[i].addEventListener("click",function () {
this.parentNode.style.display = "none"
})
}
</script>
</body>
</html>
7.2 获取子节点
1. 获取所有子节点
包括元素节点、文本节点(空格、换行)、注释节点等
1. 语法
const dady = document.querySelector(".dady")
dady.childNodes
2. 获取所有元素子节点
仅获取所有元素节点,返回的是一个伪数组
1. 语法
const ul = document.querySelector("ul")
ul.children
7.3 获取兄弟节点
1. 下一个兄弟
const baby1 = document.querySelector(".baby1")
baby1.nextElementSibling
2. 上一个兄弟
const baby1 = document.querySelector(".baby1")
baby1.previousElementSibling
7.4 创建节点
document.createElement("li")
7.5 新增节点
1. 插入节点
const ul = document.querySelector("ul")
const li = document.createElement("li")
ul.insertBefore(li,ul.children[0]) // 参数1为需要插入节点对象,参数2为插入到哪个元素对象前面
2. 追加节点
const ul = document.querySelector("ul")
const li = document.createElement("li")
ul.appendChild(li)
7.6 克隆节点
const li1 = document.querySelector("ul li:first-child")
li1.cloneNode(true) // 参数为true,则代表克隆时会包含后代节点一起克隆,参数为false,则代表克隆时不包含后代节点,默认为false
7.7 删除节点
const ul = document.querySelector("ul")
ul.removeChild(ul.children[0])
8. BOM对象
8.1 概述
1. 介绍
- window对象是一个全局对象,也可以说是JavaScript中的顶级对象
- 像 document、alert()、console.log()这些都是window对象的属性和方法,基本BOM的属性和方法都是window的
- 所有通过 var 定义在全局作用域中的变量、函数都会变成window对象的属性和方法
- window对象下的属性和方法调用的时候可以省略window
2. 组成部分

8.2 JS 执行机制(事件循环机制)
1. 面试题
下面代码的执行顺序是什么
// 面试题一
console.log(1)
setTimeout(function () {
console.log(2)
},1000)
console.log(3)
// 面试题二
console.log(1)
setTimeout(function () {
console.log(2)
},0)
console.log(3)
2. 执行机制
JavaScript语言的一大特点就是单线程,也就是说: 同一时间只能做一件事
这是因为 JavaScript 这门脚本语言诞生的使命所致 --- 为了处理页面中用户的交互以及操作 DOM 而诞生的.比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行.应该先进行添加,之后再删除
单线程就意味着,所有任务都需要排队,前一个任务结束,才会执行后一个任务. 这样所导致的问题是: 如果JS执行时间过长,就会造成页面的渲染不连贯,导致页面渲染加载阻塞的视觉感受
为了解决这个问题,利用多核CPU 的计算能力,H5提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程,于是,JS中出现了同步和异步
**同步: **
前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列书序是一致、同步的
**异步: **
在执行一个任务时,由于该任务比较耗时,可以在做这个任务的同时,处理其他任务,等这个任务可以继续做了再继续做这个任务,JS的异步是通过回调函数实现的,异步任务相关添加到任务队列(消息队列)中
JS执行机制
- 先将所有的任务加载到内存中,将所有的同步任务放入执行栈中
- js借助浏览器的多线程,执行网络请求、DOM事件、定时器等异步任务,当异步任务执行结束后,将异步任务推入任务队列中
- 先依次执行执行栈中的同步任务
- 一旦执行栈中所有的同步任务执行完毕,系统会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈开始执行,执行完毕后,再次读取任务队列中的异步任务,此过程称为事件循环
8.3 location对象
拆分并保存了URL地址的各个组成部分
1. 常用属性和方法
1. href
location.href // 获取当前的访问地址
location.href = "http://www.baidu.com" // 跳转到指定地址
2. search
location.search // 获取地址中携带的请求参数,?号及后面的所有字符串
3. hash
location.hash // 获取地址中的哈希值, #号及后面的所有字符串
4. reload()
location.reload(true) // 刷新当前页面,参数为true表示强制刷新,不从本地后去数据,强制发送网络请求获取数据
2. 使用场景
用户点击可以跳转,如果不点击,则5秒后自动跳转,要求有秒数倒计时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
span{
color: red;
}
</style>
</head>
<body>
<a href="http://www.baidu.com">支付成功! <span>5</span> 秒后跳转到首页</a>
<script>
const a = document.querySelector("a")
let num = 5
let timerID = setInterval(function () {
num--
a.innerHTML = `支付成功! <span>${num}</span> 秒后跳转到首页`
if (num <= 0){
clearInterval(timerID)
location.href = "http://www.baidu.com"
}
},1000)
</script>
</body>
</html>
8.4 navigator对象
获取浏览器自身的相关信息
1. 常用属性和方法
1. userAgent
获取浏览器的版本及平台
navigator.userAgent
2. 使用场景
根据浏览器的版本及平台跳转不同的页面
// 检测userAgent的版本,不同的设备跳转不同的页面
!(function () {
const userAgent = navigator.userAgent
const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
if (android || iphone){
location.href = "http://www.baidu.com"
}
})()
8.5 history对象
主要用于管理历史记录,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等
1. 常用属性和方法
1. back()
history.back() // 回退到上个页面
2. forward()
history.forward() // 前进到下个页面
3. go()
history.go() // 前进或后退,参数如果是正数,就是前进,是负数就是后退
8.6 本地存储
1. 概述
用于存储数据
- 数据存储在浏览器中
- 设置、读取方便,页面刷新不丢失数据
- 容量较大,sessionStorage和localStorage约
5M左右
2. localStorage
可以将数据永久存储在本地(用户的电脑),除非手动删除,否则关闭页面也会存在
特性
- 可以多窗口(页面)共享(同一浏览器可以共享)
- 以键值对的形式存储使用
1. 存储
localStorage.setItem("userName","小明")
2. 读取
localStorage.getItem("userName")
3. 删除
localStorage.removeItem("userName") // 删除指定的键值对
localStorage.clear() // 删除所有
4. 修改
localStorage.setItem("userName","小明2") // 如果没有 userName 就是新增,如果有就是覆盖修改
3. sessionStorage
可以用来存储数据,但是当关闭浏览器窗口的时候,sessionStroage就会被清除
1. 存储
sessionStorage.setItem("userName","小明")
2. 读取
sessionStorage.getItem("userName")
3. 删除
sessionStorage.removeItem("userName") // 删除指定的键值对
sessionStorage.clear() // 删除所有
4. 修改
sessionStorage.setItem("userName","小明2") // 如果没有 userName 就是新增,如果有就是覆盖修改
4. 存储复杂数据
1. 存储
先转成 JSON 串后,再存储
const userInfo = {
name:"小明",
age:18,
gender:"男"
}
localStorage.setItem("userInfo",JSON.stringify(userInfo))
2. 读取
先将读取的 JSON 串转成 Object 对象,再读取其中的内容
JSON.parse(localStorage.getItem("userInfo"))

浙公网安备 33010602011771号