DOM01
DOM:
Document Object Model
Document: 文档, 就是HTML代码
Object: 浏览器实际运行的不是HTML
HTML是文本 会被隐式转化成 JS的 对象类型, 然后运行到浏览器上
DOM: 才是浏览器中显示的内容的本体, 学习DOM之后可以灵活操作所有浏览器的技能
HTML本质: 是一套语法糖
写法
可以让程序员方便快捷的创建 DOM元素, 易读
不过: HTML 能够提供的操作特别有限
, 无法适应实际开发的需求场景
HTML只能在页面上显示静态
的内容, 例如 图片/文字
DOM树
HTML 在转换成 DOM 对象的过程中, 称为 DOM 树结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM</title>
</head>
<body>
<div id="box">
<button>家乐</button>
<button>凯凯</button>
<button>铭铭</button>
</div>
<script>
// HTML代码本质是一套语法糖: 用于快速创建DOM元素
// 实际运行后, 浏览器的底层会把HTML转换成 JS的元素, 存储在 window.document
console.log(window)
// log: 打印出来的是美化后的样子
console.log(document)
// dir: 直接输出对象本身
console.dir(document);
</script>
</body>
</html>
初体验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM操作初体验</title>
<style>
/* DOM阶段 CSS 很重要: 到 xin88.top 有css参考, 周末去看 */
#box {
background-color: #1373c5;
padding: 30px;
border-radius: 10px;
font-size: 30px;
/* 粗体 */
font-weight: bold;
/* 行内块 */
display: inline-block;
color: white;
}
</style>
</head>
<body>
<!-- DOM能做什么? -->
<!--
HTML的本质是 DOM的语法糖写法, 提供了一些简单的功能 -- 静态
学习DOM, 才能灵活的发挥浏览器的所有功能
HTML属于 阉割版的 DOM, 仅具备少量功能
-->
<div id="box"></div>
<script>
// 获取当前的时间, 现在 div#box 里
// Date
const now = new Date().toLocaleTimeString()
console.log('now:', now);
// 目标: 找到 div#box 元素, 然后把 now 放到其内部
// HTML真正运行时, 会转变成 document 对象
//
// get获取 Element元素 By通过 Id
var box = document.getElementById('box')
console.log('box:', box);
console.dir(box); //dir 查看本质
// innerHTML属性: 代表标签的内容
box.innerHTML = now
// 定时器: 每秒刷新一次
setInterval(() => {
box.innerHTML = new Date().toLocaleString()
}, 1000);
</script>
</body>
</html>
固定元素读取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>固有元素的读取</title>
</head>
<body>
<script>
// 作为一个网页, 哪些元素是一定会有的?
// head body html
console.log(document.head);
console.log(document.body);
console.log(document.documentElement); //html
</script>
</body>
</html>
按照关系读取元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>按照关系读取元素</title>
</head>
<body>
<button>菜肴</button>
<button>蔡瑶</button>
<button>浩南</button>
<button>浩北</button>
<script>
// 读取 body中的第一个元素
// firstChild: 第一个子元素. 子分两类- 文本 和 节点
console.log(document.body.firstChild); // 回车+空格
// 指定类型: 第一个 元素类型的 孩子
console.log(document.body.firstElementChild);
// 第二个: 第一个后面的
console.log(document.body.firstElementChild.nextElementSibling);
// 第一个子元素 . 下一个元素
// 获取所有孩子 children
console.log(document.body.children);
// 第二个孩子. 下标1的
console.log(document.body.children[1]);
</script>
</body>
</html>
小练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小练习</title>
</head>
<body>
<button>家乐入赘</button>
<div style="display: none;">恭喜恭喜, 早生贵子!</div>
<!-- 点击后, 让 上方div隐藏, 即 display 改为 none -->
<button>被赶出家门</button>
<!-- 点击按钮后, 让 div 显示出来 -->
<script>
// 找到 body的孩子中,序号2的元素
const btn2 = document.body.children[2]
btn2.onclick = function () {
// previous: 上一个,前一个
const d = btn2.previousElementSibling
d.style.display = 'none' //隐藏
}
// 找到按钮元素: body中的第一个
const btn = document.body.firstElementChild
btn.onclick = function () {
console.log('家乐入赘了!');
const msg = document.body.children[1]
console.log(msg);
console.dir(msg); //展开 找到 style 中的display
// 把display 从 none -> ''
msg.style.display = ''
}
</script>
</body>
</html>
通过id查找元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>通过id查找元素</title>
</head>
<body>
<ul>
<li id="hao1">浩洋</li>
<li id="hao2">浩冬</li>
<li id="hao3">浩南</li>
<li id="hao4">浩西</li>
</ul>
<script>
// 需求: li#hao1 变绿
const hao1 = document.getElementById('hao1')
console.dir(hao1) // 展开查看 style 的 color 属性
hao1.style.color = 'green'
// 练习: 找到 li#hao2的元素, 变为红色 red
const hao2 = document.getElementById('hao2')
hao2.style.color = 'red'
// id的特殊性: 浏览器默认会把具有id属性的元素自动保存起来
console.log(hao3);
hao3.style.color = 'orange'
// 不推荐直接用 id的值, 原因有3
// 1. 兼容性问题: 并非所有浏览器所有版本都有自动找id的功能
// 2. 没有代码提示
// 3. 团队合作时: 照顾有些人不知道能直接用
hao4.style.color = 'brown'
</script>
</body>
</html>
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#box {
width: 200px;
height: 200px;
border: 2px solid gray;
margin-top: 10px;
/* 过度时间 */
transition: 0.5s;
}
</style>
</head>
<body>
<button>变红</button>
<button>变绿</button>
<button>变蓝</button>
<button>变圆</button>
<div id="box"></div>
<script>
// 利用解构语法, 读取子元素: 很常见
const [btn1, btn2, btn3, btn4] = document.body.children
const box = document.getElementById('box')
console.dir(box); // 展开到 style 中找到背景色属性
btn1.onclick = function () {
box.style.backgroundColor = 'red'
}
// btn2: 变绿 green
// 不推荐用箭头: 以后会有this关键词的问题, 当前场景无所谓
btn2.onclick = () => box.style.backgroundColor = 'green'
// btn3: 变蓝 blue
btn3.onclick = function () {
box.style.backgroundColor = 'blue'
}
// btn4: 圆角??
btn4.onclick = function () {
box.style.borderRadius = box.style.borderRadius == '50%' ? '' : '50%'
// style的元素默认值都是 空字符串
}
</script>
</body>
</html>
总结
DOM:
-
HTML: 就是DOM的一个语法糖写法, 仅提供了小部分功能 --
静态展示
-
DOM: 才是浏览器中显示的内容的本体. 利用DOM才能制作出
动态变化
的页面, 更加完善
DOM的精髓:找到要操作的元素, 然后修改他的属性
作业
-
点击
家乐
按钮, 利用 style 属性, 让div#box
背景色变绿, 利用 innerHTML 属性, 让其中的文字变为:欢迎家乐
-
点击
波波
按钮, 利用 style 属性, 让div#box
背景色变蓝, 字体变大到30px, 利用 innerHTML 属性, 让其中的文字变为:欢迎波波
, -
点击
浪浪
按钮, 利用 style 属性, 让div#box
背景色变紫色, 文字变白色, 粗体, 利用 innerHTML 属性, 让其中的文字变为:欢迎浪浪
DOM02
DOM:
D
ocumentO
bjectM
odel
Document: 文档 -- 就是HTML代码
Object: 对象 -- HTML代码转换而来的对象
Model: 模型 -- HTML 转换成 Object 这种方式
HTML
: 就是一种 语法糖
写法, 可以快速的创建出DOM元素
-
浏览器在阅读HTML后, 会转换成
document
对象, 最后显示到页面上 -
浏览器真正展示到页面上的, 是
document
对象 -
学习DOM的目的: 直接操作
document
对象, 不再使用普通的HTML -
HTML只能提供简单的操作操作
-
可以粗暴理解:
DOM
犹如玩游戏开挂
, 操作底层代码, 突破限制
查找元素
DOM的重要核心操作: 先查找到元素
-> 然后修改元素的属性
-
固定元素的查找:
-
document.head
-
document.body
-
document.documentElement
: 整个html
-
-
按照关系查找
-
第一个子元素:
firstElementChild
-
所有子元素:
children
-
数组类型, 利用 下标取值来读取某个元素
-
常见
利用数组解构
语法, 快速获取多个元素
-
-
下一个兄弟元素:
nextElementSibling
-
上一个兄弟元素:
previousElementSibling
-
-
按照id查找:
-
document.getElementById()
-
特殊: 浏览器会自动把 id 的元素找到并保存在同名变量中, 可以直接用
-
不推荐
-
-
作业
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>作业</title>
<style>
#box {
width: 200px;
height: 200px;
margin-top: 10px;
border: 2px solid brown;
transition: 0.5s;
}
</style>
</head>
<body>
<button>家乐</button>
<button>波波</button>
<button>浪浪</button>
<div id="box"></div>
<script>
// 任务: 为每个按钮添加点击事件, 点击后让 div#box 发生变化
// DOM操作的核心1: 先找到你要操作的元素
// 所有元素都存储在 document 这个对象里
const [btn1, btn2, btn3] = document.body.children
const box = document.getElementById('box')
console.dir(box) // dir: 用来输出真正的 dom 元素对象
// 核心理念2: 操作元素的属性
// style的属性, 默认值是 "" 空字符串
// 每个元素,都具备很多事件, 都是以 on 开头的属性
// on: 当...时
// onclick: 当点击时
btn1.onclick = function () {
box.style.backgroundColor = 'green'
// innerHTML: 代表标签中的文本
box.innerHTML = '欢迎家乐'
}
btn2.onclick = function () {
box.style.backgroundColor = 'blue'
box.style.fontSize = '30px'
box.innerHTML = '欢迎波波'
}
btn3.onclick = function () {
box.style.backgroundColor = 'purple'
box.style.color = 'white'
box.style.fontWeight = 'bold'
box.innerHTML = '欢迎浪浪'
}
</script>
</body>
</html>
通过 标签 和 class 查找
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>更多查找元素的方式</title>
</head>
<body>
<div id="box">
<div>
<p>Hello</p>
<p>World</p>
<div>
<!-- 通过 name 或 class 来添加特征用于区分 -->
<!-- name: 为表单元素而生 -- form 提交 -->
<p class="p-1">欢迎</p>
<p class="p-1">浪浪</p>
</div>
</div>
<div></div>
</div>
<script>
// 按照标签名查找元素: Tag标签
const ps = document.getElementsByTagName('p')
// 查询结果是 类(似)数组: 原型不是数组, 无法使用数组的方法
// 例如 无法使用 forEach 来遍历
console.log(ps);
// for..of : 专业遍历, 适用于 类数组
// 声明的变量名, 随便起 -- 最好见名知意
for (const p of ps) {
p.style.color = 'red'
}
// 通过 class 名来查找
const pc = document.getElementsByClassName('p-1')
console.log(pc);
// 把 pc 中的元素, 背景色变绿
for (const p of pc) {
p.style.backgroundColor = 'green'
}
</script>
</body>
</html>
通过name查找
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>通过name查找</title>
</head>
<body>
<div id="box">
<!-- 表单元素: 具有 name 属性 -->
<input type="radio" name="sex" id="">
<input type="radio" name="sex" id="">
<hr>
<input type="radio" name="xx" id="">
<input type="radio" name="xx" id="">
</div>
<script>
// 通过 name 来查找元素
const sexs = document.getElementsByName('sex')
console.log(sexs);
// 原型是 NodeList, 非数组 -- 类数组
// 但是: 原型中有 forEach 方法可以用
// 除了 for..of, 也能用 forEach 遍历
sexs.forEach(sex => {
// accentColor: 选中时的高亮色
sex.style.accentColor = 'red'
})
</script>
</body>
</html>
通过css选择器查找
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>通过css选择器查找</title>
</head>
<body>
<!--
css选择器:
id: #
class: .
属性: [type='password'] 选择 type='password' 的元素
伪类: li:first-child
标签: tag
伪元素: div:after
相邻兄弟: h1+p <h1><h1><p></p>
子代: >
后代: 空格
-->
<div id="box">
<p>波波</p>
<p>浪浪</p>
<p>家乐</p>
<p>浩然</p>
</div>
<script>
// 把家乐 变为 粉色
// css选择器: id=box 的`子`元素中 第三个孩子
// #box > p:nth-child(3)
// query:查询 selector:选择器
const p3 = document.querySelector('#box>p:nth-child(3)')
console.log(p3);
console.dir(p3);
p3.style.color = 'pink'
// 把所有 p 标签都添加一个边框
// all: 代表所有, 查询到满足条件的所有元素
const ps = document.querySelectorAll('#box > p')
console.log(ps);
// 原型 NodeList -- 类数组
// 但是 有 forEach 方法可以用来遍历
ps.forEach(p => p.style.border = '1px solid blue')
ps.forEach(p => {
p.style.border = '1px solid blue'
})
// forEach 不懂, 看 JS高级第五天
</script>
</body>
</html>
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
</head>
<body>
<div id="box">
<p>蔡瑶</p>
<p>李浩洋</p>
<p>雷家乐</p>
<p>亮亮</p>
<p>思琪</p>
</div>
<!-- 把所有名字是三个字的元素 高亮显示: 文字颜色变红 -->
<script>
// 提前思考: 查询出来的东西是 1个 还是 多个(All)
const ps = document.querySelectorAll('#box > p')
ps.forEach(p => {
if (p.innerHTML.length == 3) {
p.style.color = 'red'
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
table {
border-collapse: collapse;
width: 200px;
}
td,
th {
border: 1px solid gray;
text-align: center;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>亮亮</td>
<td>37</td>
</tr>
<tr>
<td>2</td>
<td>铭铭</td>
<td>32</td>
</tr>
<tr>
<td>3</td>
<td>楠楠</td>
<td>18</td>
</tr>
<tr>
<td>4</td>
<td>家乐</td>
<td>24</td>
</tr>
</tbody>
</table>
<!-- 需求: 把 年龄 大于 30岁的, 整行添加 红色背景色 -->
<!-- 提示: 利用 parentElement 可以找到元素的父元素 -->
<script>
// 年龄: tr 中的最后一个td
const ages = document.querySelectorAll('tbody td:last-child')
console.log(ages)
// age: 箭头函数的形参, 代表 ages 类数组中的具体元素
// 形参名 是随便起, 但是: 见名知意 是起名原则
ages.forEach(age => {
// innerHTML: 用于读取标签中的文本
// 隐式类型转换: 变量会根据所在的 表达式, 自行转换成合理的类型
if (age.innerHTML > 30) {
// 获取某个元素的父元素: parentElement
const tr = age.parentElement
console.log(tr);
tr.style.backgroundColor = 'red'
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
table {
border-collapse: collapse;
}
th,
td {
border: 1px solid gray;
padding: 5px 20px;
}
</style>
</head>
<body>
<!-- 光标放最后面, 用 ctrl+i 可以弹出生成提示 -->
<!-- table>(thead>tr>th*4)+(tbody>(tr>td*4)*4) -->
<table>
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>亮亮</td>
<td>男</td>
<td><button>删除</button></td>
</tr>
<tr>
<td>2</td>
<td>楠楠</td>
<td>女</td>
<td><button>删除</button></td>
</tr>
<tr>
<td>3</td>
<td>梦瑶</td>
<td>女</td>
<td><button>删除</button></td>
</tr>
<tr>
<td>4</td>
<td>家乐</td>
<td>男</td>
<td><button>删除</button></td>
</tr>
</tbody>
</table>
<!-- 要求: 男所在行-blue 女所在行-red -->
</body>
</html>
this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>this</title>
</head>
<body>
<!--
this关键词:
-- 涛哥买了个锤子, 楠姐拿锤子打亮亮
- function: 锤子的this? -- 楠姐 this代表使用者
- 箭头函数: 锤子的this? -- 涛哥 this代表声明时所在作用域中的this
切记:DOM的事件 要绑定 function, 因为其中this必须指向事件触发时所在的对象
-->
<button>11</button>
<button>22</button>
<button>33</button>
<script>
const [btn1, btn2, btn3] = document.body.children
// onclick 在btn1 对象里, 触发时所在对象 btn1
btn1.onclick = function () {
// this: function触发时所在对象
console.log(this)
}
// 箭头this: 在哪声明的, 算哪里的this, 后期不变
// 全局生成: window
var a = () => { console.log(this) }
btn2.onclick = a
// 同上: 格式变为合写
btn3.onclick = () => { console.log(this) }
</script>
</body>
</html>
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
</head>
<body>
<h2>家乐的相亲会</h2>
<p>亮灯女嘉宾: 是否要持续关注?</p>
<button>大乔</button>
<button>小乔</button>
<button>蔡文姬</button>
<button>貂蝉</button>
<button>西施</button>
<script>
// DOM核心1: 先找到你要操作的元素
const btns = document.querySelectorAll('button')
btns.forEach(btn => btn.onclick = function () {
// this: 代表触发时所在对象
this.remove()
})
</script>
</body>
</html>
class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>class操作</title>
<style>
#box {
width: 200px;
height: 200px;
border: 2px solid gray;
transition: 0.5s;
margin-top: 10px;
}
/* class选择器 . */
.suc {
background-color: green;
}
.fail {
background-color: red;
}
</style>
</head>
<body>
<!-- css样式有两种做法: style 和 class -->
<!-- style: 内联样式, 适合非常少量的css修改 -- 实际开发很少用 -->
<!-- class: 内部样式, 适合实际开发 -->
<button>成功</button>
<button>失败</button>
<div id="box"></div>
<script>
const [btn1, btn2, box] = document.body.children
console.dir(box) //到后台找到 class 相关的属性
btn1.onclick = function () {
// className: 因为JS中 class是关键词, 代表 JAVA的 类
// 所以 JS 中, 改名为 className
box.className = 'suc'
}
// 练习: 完成失败的操作
btn2.onclick = function () {
box.className = 'fail'
}
</script>
</body>
</html>
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#box {
/* 用户-可选中文本: 不能 */
user-select: none;
}
#box>span {
display: inline-block;
padding: 5px 15px;
background-color: #bbb;
border-radius: 5px;
}
/* span:标签 .cur: class='cur' */
/* span.cur : <span class='cur' 代表 span带有 cur */
#box>span.cur {
background-color: orange;
color: white;
}
</style>
</head>
<body>
<div id="box">
<span class="cur">黄焖鸡</span>
<span>KFC</span>
<span>麦当劳</span>
<span>水煮鱼</span>
<span>炒饭</span>
</div>
<script>
// 牢记: DOM操作的核心 -- 先找到你要操作的元素
const spans = document.querySelectorAll('#box span')
spans.forEach(span => span.onclick = function () {
// this.className = 'cur'
// if (this.className == '') {
// this.className = 'cur'
// } else {
// this.className = ''
// }
this.classList.toggle('cur')
console.log(this.classList);
// classList: 一个工具箱, 存储了一些快捷的操作class的方法
// 常用方法:
// - add: 添加样式
// - remove: 删除
// - replace: 替换
// - toggle: 切换 -- 有就删, 没有就加
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#box {
user-select: none;
}
#box>span {
display: inline-block;
background-color: #bbb;
line-height: 80px;
width: 80px;
text-align: center;
transition: 0.3s;
}
/* cur: 自定义的, 最优单词 active(激活) */
#box>span.cur {
border-radius: 50%;
background-color: orange;
color: white;
}
</style>
</head>
<body>
<h3>请选择英雄:</h3>
<div id="box">
<span>德莱文</span>
<span>万豪</span>
<span>提莫</span>
<span>纳尔</span>
<span>猫咪</span>
</div>
<script>
const spans = document.querySelectorAll('#box span')
spans.forEach(span => span.onclick = function () {
// 唯一性的选择: 先找到之前的带有 cur 样式的元素, 删掉样式
const cur = document.querySelector('.cur')
// 如果 cur 为真, 说明存在, 再执行
// if (cur) cur.classList.remove('cur')
// 实际工作: 更喜欢用逻辑短路写法
cur && cur.classList.remove('cur')
// 逻辑与: 全真则为真 -- 前方表达式是真, 后方才能继续执行
// cur: 如果是假 false && xxx : xxx 就不会执行
// 家乐要嫁人- 要求: 有房 && 有车 && 有钱
// 必须前方条件满足, 才会验证后续的条件
// 搜狗输入法: shift 按键 切换中英文
this.classList.add('cur')
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#pages {
user-select: none;
background-color: #f5f5f6;
padding: 20px;
}
#pages>span {
background-color: white;
color: #4e6ef2;
display: inline-block;
border-radius: 4px;
line-height: 40px;
width: 40px;
text-align: center;
}
#pages>span.cur {
background-color: #4e6ef2;
color: white;
}
</style>
</head>
<body>
<div id="pages">
<span class="cur">1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>
<script>
const spans = document.querySelectorAll('#pages span')
spans.forEach(span => span.onclick = function () {
// 保障唯一性: 新的添加前, 要移除旧的
// 参数是 css选择器 .cur 代表 class=cur
const cur = document.querySelector('.cur')
// 参数是 class名
cur.classList.remove('cur')
// 区别: 当前练习 默认第一项就是 class='cur', 不存在搜索不到的情况, 所以不需要判断 cur 是否存在
this.classList.add('cur')
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#dian {
user-select: none;
background-color: #888;
padding: 10px;
}
#dian>span {
display: inline-block;
width: 20px;
height: 20px;
border-radius: 10px;
background-color: white;
transition: width 0.7s;
}
#dian>span.cur {
background-color: #206cfe;
width: 50px;
}
</style>
</head>
<body>
<div id="dian">
<span class="cur"></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<script>
// DOM核心宗旨:找到你要操作的元素
const spans = document.querySelectorAll('#dian span')
// 所有事件
// https://www.w3school.com.cn/jsref/dom_obj_event.asp
spans.forEach(span => span.onmouseenter = function () {
document.querySelector('.cur').classList.remove('cur')
this.classList.add('cur')
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#box {
width: 200px;
}
#box>div {
border: 2px solid gray;
background-color: green;
height: 100px;
}
#box>div:last-child {
display: none;
}
#box>div:last-child.open {
display: block;
}
</style>
</head>
<body>
<div id="box">
<button>展开</button>
<div></div>
<div></div>
</div>
<script>
// DOM操作的核心: 先找到你要操作的元素
// 做什么: 点击按钮 -> 切换 最后一个div的显示 open
// 预判: 要查找的元素有几个 1个 ?? 多个??
const btn = document.querySelector('button')
btn.onclick = function () {
const d = document.querySelector('#box>div:last-child')
// 切换样式 open: 工具箱 classLis中, toggle
d.classList.toggle('open')
// 通过判断是否含有 open 样式, 来决定按钮的文字
// contains: 包含, 用于判断是否包含某个样式
this.innerHTML = (d.classList.contains('open') ? '收起' : '展开')
}
</script>
</body>
</html>
今日内容回顾
DOM的用途主要在于实战
-
DOM核心点1: 学会如何找到你要操作的元素
-
固定的:
head
body
documentElement
-
按照关系:
-
children
-
firstElementChild
-
parentElement
-
nextElementSibling
:隔壁的兄弟
-
-
按照特征查找(
除了id 其他很少用
)-
id
-
class
-
标签名
-
name
-
-
利用
css选择器
查找-
querySelector
: 查单个
元素, 返回值是 元素本身 -
querySelectorAll
: 查多个
元素, 返回值是 类数组, 有forEach可以用
-
-
-
class
-
className: 就是 class 属性本身
-
classList
: 一个工具箱
, 存放了很多操作class的方法, 更加易用!-
add: 添加样式
-
remove: 移除样式
-
toggle: 切换样式
-
contains: 是否有某个样式
-
-
作业
点击之后变色高亮手游休闲
, 悬浮时是 娱乐天地
的样子
同时只能一个高亮
鼠标进入时: mouseenter
会展开当前项. 本质是切换 open
样式
提示: 刚开始每一条
<div id='box'>
<div>
<div>标题</div>
<div>说明 -- 初始隐藏</div>
</div>
<div>
<div>标题</div>
<div>说明 -- 初始隐藏</div>
</div>
<div>
<div>标题</div>
<div>说明 -- 初始隐藏</div>
</div>
</div>
DOM03
复习
DOM的核心操作2件事:
-
查找到你要操作的元素
-
固定元素的查找:
head
body
documentElement
-
按照关系
-
chilren: 子元素们
-
parentElement: 父元素
-
firstElementChild: 第一个子元素
-
nextElementSibling: 下一个兄弟元素
-
previousElementSibling: 上一个兄弟元素
-
-
按照特征
-
id : 唯一性, 结果只有一个
-
class: 多个
-
标签 tag: 多个
-
name: 多个
-
-
通过 css选择器
最常用
-
querySelector: 单个元素
-
querySelectorAll: 多个元素
-
-
-
操作元素的属性
-
style: 内联样式
-
class:
-
className: 就是class属性本身
-
classList:
工具箱
-- 存放了很多操作class的方法-
add: 添加
-
remove: 移除
-
toggle: 切换
-
contains: 判断是否存在
-
-
-
事件: 都是 on 开头
-
onclick: 点击
-
onmouseenter: 鼠标进入
-
-
作业
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>作业</title>
<style>
#box {
user-select: none;
background-color: #f2f5f6;
padding: 10px;
}
#box>span {
display: inline-block;
line-height: 40px;
width: 100px;
border-radius: 20px;
background-color: white;
text-align: center;
color: #666;
margin: 0 5px;
border: 1px solid #eee;
}
#box>span:hover {
border-color: #ff5d23;
color: #ff5d23;
}
#box>span.active {
color: white;
background-color: #ff5d23;
border-color: #ff5d23;
}
</style>
</head>
<body>
<div id="box">
<span class="active">网游竞技</span>
<span>单机热游</span>
<span>手游休闲</span>
<span>娱乐天地</span>
<span>颜值</span>
<span>科技文化</span>
</div>
<script>
// 分辨 要查找的元素是 1个 还是 多个??
const spans = document.querySelectorAll('#box span')
spans.forEach(span => span.onclick = function () {
// 删除之前的高亮项
document.querySelector('.active').classList.remove('active')
// 当前点击项高亮
this.classList.add('active')
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>作业</title>
<style>
#box {
background-color: #888;
color: white;
width: 300px;
}
#box>div {
padding: 10px;
}
#box>div>div:last-child {
display: none;
}
/* 带有 open 样式, 应该显示: 优先级权重 open会优先 */
#box>div.open>div:last-child {
display: block;
}
#box>div.open>div:first-child {
color: orange;
font-size: 1.2em;
}
#box>div.open {
background-color: #666;
}
</style>
</head>
<body>
<div id="box">
<div class="open">
<div>英雄联盟钻粉福利周11</div>
<div>开通钻粉领取福利周边~!</div>
</div>
<div>
<div>英雄联盟钻粉福利周22</div>
<div>开通钻粉领取福利周边~!</div>
</div>
<div>
<div>英雄联盟钻粉福利周33</div>
<div>开通钻粉领取福利周边~!</div>
</div>
</div>
<script>
const items = document.querySelectorAll('#box>div')
items.forEach(item => item.onmouseenter = function () {
document.querySelector('.open').classList.remove('open')
this.classList.add('open')
})
</script>
</body>
</html>
大小图切换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片相关</title>
<style>
#box {
background-color: lightblue;
width: 400px;
user-select: none;
}
#box>img {
width: 100%;
}
body {
background-color: #eee;
}
#box>div>img {
width: 23%;
/* transparent: 透明 */
border: 2px solid transparent;
}
#box>div>img.active {
border-color: red;
}
</style>
</head>
<body>
<div id="box">
<img src="./imgs/1_lg.jpg" alt="">
<div>
<!-- 自定义属性: 存储小图对应的大图名 -->
<img data-big="1_lg.jpg" class="active" src="./imgs/1.sm.jpg" alt="">
<img data-big="2.lg.jpg" src="./imgs/2.sm.jpg" alt="">
<img data-big="3.lg.jpg" src="./imgs/3.sm.jpg" alt="">
<img data-big="4.lg.jpg" src="./imgs/4.sm.jpg" alt="">
</div>
</div>
<script>
const imgs = document.querySelectorAll('#box>div>img')
const big_img = document.querySelector('#box>img')
console.dir(big_img) // 查看其 src 属性
imgs.forEach(img => img.onmouseenter = function () {
const active = document.querySelector('#box .active')
active.classList.remove('active')
// 当前项.工具箱.添加工具()
this.classList.add('active')
// 读取当前项中, 存储的自定义属性 big, 即大图的名字
// 图片使用时, 需要有路径, 不能光有名字, 所以要拼接
big_img.src = './imgs/' + this.dataset.big
})
</script>
</body>
<!--
大图1张 1000KB
小图1张 100KB
5张图
-- 假设: 全用大图, 消耗 5000KB
-- 假设: 5个小图 + 1个大图 消耗 1500KB
-- --- 用户滑动时: 临时请求大图
------ 优点: 首次加载速度快; 如果用户没看别的, 省3500kb流量
-->
</html>
自定义属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自定义属性</title>
</head>
<body>
<!-- 每个DOM元素, 系统都提供了很多固有属性 -- 系统属性 -->
<!-- 可以添加 自定义属性: 以 data- 开头 -->
<a href="http://www.baidu.com" id="a1" class="danger" title="百度一下, 精彩即来" target="_blank" data-xx="11" data-yy="22"
data-zz="33">百度一下</a>
<script>
const a1 = document.getElementById('a1')
console.dir(a1); // 试一试, 能否在后台找到自定义属性在哪里?
// dataset: 专门存储利用 data- 声明的自定义属性
// 读取自定义属性
console.log(a1.dataset.xx);
console.log(a1.dataset.yy);
console.log(a1.dataset.zz);
</script>
</body>
</html>
标签栏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>标签栏</title>
<style>
#tabs>div:first-child {
border-bottom: 1px solid red;
background-color: #f7f7f7;
color: #666;
padding: 0 1px 1px 1px;
user-select: none;
}
#tabs>div:first-child>span {
padding: 10px 20px;
display: inline-block;
}
#tabs>div:first-child>span.active {
background-color: red;
color: white;
}
#tabs>div:last-child>div {
border: 1px solid gray;
height: 300px;
padding: 10px;
background-color: #eee;
}
/* :not(): 不是, 不是 .active 的, 都隐藏 */
#tabs>div:last-child>div:not(.active) {
display: none;
}
</style>
</head>
<body>
<div id="tabs">
<div>
<!-- 利用自定义属性, 存储 标题对应的内容id -->
<span data-id="tab1" class="active">商品介绍</span>
<span data-id="tab2">规格与包装</span>
<span data-id="tab3">售后保障</span>
</div>
<div>
<div id="tab1" class="active">商品介绍...</div>
<div id="tab2">规格与包装...</div>
<div id="tab3">售后保障...</div>
</div>
</div>
<script>
const tabs = document.querySelectorAll('#tabs>div:first-child>span')
tabs.forEach(tab => tab.onclick = function () {
const s = '#tabs>div:first-child>span.active'
document.querySelector(s).classList.remove('active')
this.classList.add('active')
// 把之前带有 .active 的详情, 移除激活态
document.querySelector('#tabs div.active').classList.remove('active')
// 读取当前点击项中存储的 自定义属性 id
const id = this.dataset.id
// 通过id 找到对应的详情元素
// id是变量, 需要用模板字符串拼接
const detail = document.querySelector(`#tabs #${id}`)
detail.classList.add('active')
})
</script>
<!--
总结: 可以利用自定义属性, 让不同元素之前产生联系
实现: 操作A元素, 让B元素产生变化
-->
</body>
</html>
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#box {
user-select: none;
}
#box>div>span {
display: inline-block;
width: 180px;
line-height: 50px;
text-align: center;
border-radius: 4px;
border: 1px solid gray;
color: gray;
margin: 0 10px 10px 0;
}
#box>div>span.active {
border-color: red;
color: red;
}
#box>h1 {
color: red;
}
</style>
</head>
<body>
<div id="box">
<h1>4899</h1>
<div>
<span data-price="4899" class="active">12GB+512GB</span>
<span data-price="3999">8GB+256GB</span>
<span data-price="3699">8GB+128GB</span>
<span data-price="4399">12GB+256GB</span>
</div>
</div>
<script>
const items = document.querySelectorAll('#box>div>span')
const h1 = document.querySelector('#box>h1')
items.forEach(item => item.onclick = function () {
document.querySelector('#box .active').classList.remove('active')
this.classList.add('active')
//读取当前项的 自定义属性 price
const price = this.dataset.price
h1.innerHTML = price //设置到 h1 的文本
})
</script>
</body>
</html>
输入框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>输入框</title>
</head>
<body>
<input type="text" id="">
<script>
// 输入框的相关事件:
const inp = document.querySelector('input')
// 1. 获得焦点 focus
inp.onfocus = function () {
console.log('focus: 光标闪烁, 获得焦点');
}
// 2. 失去焦点 blur
inp.onblur = function () {
console.log('blur: 失去焦点');
}
// 3. 内容变化 change
// 前提: 输入框内容变化 然后 回车或失去焦点后触发
inp.onchange = function () {
// value: 此属性中存储的是 输入框的值
console.log('内容变化:', this.value);
}
// 4. 内容实时变更 input
inp.oninput = function () {
console.log('实时:', this.value);
}
// 5. 键盘事件 keyup
// 事件参数: 当事件触发时,会自动携带事件相关的所有信息
inp.onkeyup = function (e) {
// 事件参数一直都有, 之前没用上. 显示要用, 所以声明参数接收
// 形参名随便, 但是最好有含义 event:事件 简称e
console.log(e);
// keyCode: 按键的编号
// 利用 keyCode 来判断用户按下了什么按键
// keyCode == 13 代表回车
if (e.keyCode == 13) {
console.log('回车被点...');
// 场景: 在输入框中 按回车, 自动发送搜索请求之类的...
}
}
</script>
</body>
</html>
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#box {
user-select: none;
}
#box>div {
display: inline-block;
}
#box>div>span {
font-size: 0.7em;
color: white;
display: inline-block;
border-radius: 3px;
padding: 3px 5px;
transform: scale(0.8);
}
/* 只有激活的才显示: 不带有 active 样式的,都隐藏 */
#box>div>span:not(.active) {
display: none;
}
#box>div>span.ok {
background-color: green;
}
#box>div>span.err {
background-color: red;
}
#box>div>span.info {
background-color: gray;
}
</style>
</head>
<body>
<div id="box">
<span>手机号:</span>
<input type="text" placeholder="请输入您的手机号">
<div>
<span class="err">手机号格式不正确</span>
<span class="err">手机号不能为空</span>
<span class="ok">该手机号可以使用</span>
<span class="info">请输入合法的手机号</span>
</div>
</div>
<script>
const inp = document.querySelector('#box input')
// 获得焦点: 让 .info 显示
inp.onfocus = function () {
// bug修复: 如果手机号已经对了, 则不做处理
if (/^1[3-9]\d{9}$/.test(this.value)) return
const active = document.querySelector('#box .active')
// active:不一定存在, 使用前先判断为真
active && active.classList.remove('active')
const info = document.querySelector('#box .info')
info.classList.add('active')
}
// 失去焦点
inp.onblur = function () {
// 删除之前激活的
document.querySelector('#box .active').classList.remove('active')
// 判断:如果输入框是空的
if (this.value == '') {
const empty = document.querySelector('#box .err:nth-child(2)')
empty.classList.add('active')
return //停止函数的执行, 后续代码不生效
}
// 正则验证手机号格式 /^1[3-9]\d{9}$/
if (/^1[3-9]\d{9}$/.test(this.value)) {
const ok = document.querySelector('#box .ok')
ok.classList.add('active')
} else {
const err = document.querySelector('#box .err:first-child')
err.classList.add('active')
}
}
</script>
<!--
书写代码完成一个功能时:
- 思路: 先把要展示的内容都写出来, 然后根据条件判断 哪些显示 哪些不显示
---- 获取焦点: 清空之前的激活, 显示提示info
---- 失去焦点:
------- 为空: 显示 为空的报错
------- 手机号格式错误: 显示 格式错误的报错
------- 手机号格式正确: 显示 格式正确的提示
- 代码: 需要熟练度 -- 只能多练
-->
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
#box {
user-select: none;
}
#box>div {
display: inline-block;
}
#box>div>span {
display: inline-block;
padding: 5px 10px;
color: white;
border-radius: 3px;
}
#box>div>span.info {
background-color: gray;
}
#box>div>span.ok {
background-color: green;
}
#box>div>span.err {
background-color: red;
}
#box>div>span:not(.active) {
display: none;
}
</style>
</head>
<body>
<div id="box">
<span>用户名:</span>
<input type="text" placeholder="请输入用户名">
<div>
<span class="info">用户名长度在6到9位之间</span>
<span class="ok">用户名可以使用</span>
<span class="err">用户名不能为空</span>
<span class="err">用户名位数错误!</span>
</div>
</div>
<script>
const inp = document.querySelector('#box input')
inp.onfocus = function () {
// 获得焦点时, 也要清除之前的高亮项目
// ES6提供的语法: 变量?. 如果变量是真的, 才会继续执行
// 中文的ES6教程: https://es6.ruanyifeng.com/
document.querySelector('#box .active')?.classList.remove('active')
const info = document.querySelector('#box .info')
info.classList.add('active')
}
inp.onblur = function () {
document.querySelector('#box .active').classList.remove('active')
if (this.value == '') {
const err = document.querySelector('#box .err:nth-child(3)')
err.classList.add('active')
return // 防止为空, 导致后续的 位数错误也显示
}
if (this.value.length >= 3 && this.value.length <= 9) {
const ok = document.querySelector('#box .ok')
ok.classList.add('active')
} else {
const err = document.querySelector('#box .err:last-child')
err.classList.add('active')
}
}
</script>
</body>
</html>
change事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>change事件</title>
<style>
.btn {
display: inline-block;
width: 300px;
text-align: center;
background-color: #72b134;
border-radius: 3px;
line-height: 30px;
color: white;
user-select: none;
}
.btn:active {
opacity: 0.7;
}
/* 联合在一起写: 代表同时具备 */
.btn.disabled {
background-color: #aaa;
/* 指针-事件们: 一个都不留; 去掉所有鼠标响应 */
pointer-events: none;
}
</style>
</head>
<body>
<div id="box">
<!-- label被点击时, 会触发其子元素的点击事件 -->
<label>
<input type="checkbox">
<span>我已阅读并同意用户注册协议</span>
</label>
<br>
<div class="btn disabled">提交注册</div>
</div>
<script>
// 检测: 勾选按钮的 状态变化
const btn = document.querySelector('.btn')
const chb = document.querySelector('#box input')
// change: 值发生变化
chb.onchange = function () {
console.dir(this); // 检查 : checked 属性的值
console.log('checked:', this.checked);
// if (this.checked) { //勾选状态, 删除disabled
// btn.classList.remove('disabled')
// } else {
// btn.classList.add('disabled')
// }
this.checked ? btn.classList.remove('disabled') : btn.classList.add('disabled')
// []: 其中书写JS代码
// btn.classList[this.checked ? 'remove' : 'add']('disabled')
// 下方3行代码同含义
// btn.classList.add('xxx')
// btn.classList['add']('xxx')
// var x = 'add'
// btn.classList[x]('xxx')
}
</script>
</body>
</html>
今日知识点
-
图片的 src 属性
-
自定义属性:
data-
开头, 存储在dataset
属性里 -
输入框的事件
-
focus
-
blur
-
change
-
input
-
keyup
-
作业
作业1: 轮播图的参考: 首页
图片从今日提供的压缩包中获取
-
先把 小圆点的效果完成
-
关于图片: css必须用 绝对定位来书写
position:absolute
-
4张图片需要
层叠在一起
, 其中只有 带有 active 样式的图片才显示-
为图片添加过度
transition:0.5s
-
图片把
opacity
透明度改为0, 只有 active的透明度才是 1 即显示
-
-
每个小圆点有个自定义属性,
data-index
, 值是对应的图片的 序号, 即nth-child(??)
<div id='banner'> <div> <img class='active' src='.....'> <img src='.....'> <img src='.....'> <img src='.....'> </div> <div> <span data-index='1' class='active'></span> <span data-index='2'></span> <span data-index='3'></span> <span data-index='4'></span> </div> </div>
DOM04
复习
-
输入框的相关事件
-
focus: 获得焦点
-
blur: 失去焦点
-
change: 内容变化时 -- 回车/失去焦点
-
input: 实时变化监听
-
keyup: 键盘的按键抬起
-
通过事件参数
e
来读取当前是哪个按键触发的, 回车keyCode = 13
-
-
-
自定义属性
-
data-
: 存储在dataset
中 -
用途
-
存储一些相关的属性 或者 关键其他的元素们
-
-
作业
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>作业</title>
<style>
/* 绝对定位: 父相子绝 */
#banner {
border: 2px solid red;
user-select: none;
width: 600px;
height: 300px;
position: relative;
}
#banner>div:last-child {
position: absolute;
bottom: 5px;
width: 100%;
text-align: center;
}
#banner>div:first-child {
position: relative;
height: 100%;
}
#banner>div>img {
position: absolute;
width: 100%;
height: 100%;
transition: 0.5s;
}
/* 除了 .active 之外, 都要透明 */
#banner img:not(.active) {
opacity: 0;
}
#banner span {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #cccccc;
margin: 0 4px;
}
#banner span.active {
background-color: orange;
}
</style>
</head>
<body>
<div id="banner">
<div>
<img class="active" src="./imgs/banner1.png" alt="">
<img src="./imgs/banner2.png" alt="">
<img src="./imgs/banner3.png" alt="">
<img src="./imgs/banner4.png" alt="">
</div>
<div>
<!-- 利用自定义属性, 记录小圆点对应的图是第几个 -->
<span data-index="1" class="active"></span>
<span data-index="2"></span>
<span data-index="3"></span>
<span data-index="4"></span>
</div>
</div>
<script>
// DOM核心: 先查出你要操作的元素
// 我要 操作小圆点 -> 就要把小圆点查出来 -> 数 4 个 -> all
const dians = document.querySelectorAll('#banner span')
dians.forEach(dian => dian.onmouseenter = function () {
document.querySelector('#banner span.active').classList.remove('active')
this.classList.add('active')
const index = this.dataset.index
// index存储的是第几个, 例如 1 2 3 4
const img = document.querySelector(`#banner img:nth-child(${index})`)
// 去掉之前 激活的图片, 为当前图片添加激活
document.querySelector('#banner img.active').classList.remove('active')
img.classList.add('active')
})
</script>
</body>
</html>
轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>轮播图</title>
<style>
#banner {
user-select: none;
border: 2px solid red;
width: 400px;
overflow: hidden;
position: relative;
}
#banner>div:last-child {
position: absolute;
width: 100%;
text-align: center;
bottom: 5px;
}
#banner>div:first-child {
display: flex;
}
#banner img {
width: 100%;
height: 160px;
transition: 0.5s;
}
/* 移动第一个图片的 左侧外边距, 让图片一起动 */
#banner img:first-child {
/* margin-left: -400px; */
}
#banner span {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #cccccc;
margin: 0 4px;
}
#banner span.active {
background-color: orange;
}
</style>
</head>
<body>
<div id="banner">
<div>
<img class="active" src="./imgs/banner1.png" alt="">
<img src="./imgs/banner2.png" alt="">
<img src="./imgs/banner3.png" alt="">
<img src="./imgs/banner4.png" alt="">
</div>
<div>
<span data-index="0" class="active"></span>
<span data-index="1"></span>
<span data-index="2"></span>
<span data-index="3"></span>
</div>
</div>
<script>
const dians = document.querySelectorAll('#banner span')
dians.forEach(dian => dian.onmouseenter = function () {
document.querySelector('#banner span.active').classList.remove('active')
this.classList.add('active')
const index = this.dataset.index
const img = document.querySelector('#banner img:first-child')
img.style.marginLeft = -400 * index + 'px'
})
// 定时器实现自动滚动
setInterval(() => {
// 获取当前的项目, 然后触发其下一项
const active = document.querySelector('#banner span.active')
// 下一个小圆点
let next_dian = active.nextElementSibling
console.log(next_dian);
// 如果 next_dian 是null, 说明已经是最后一个, 则回到第一个
// if (next_dian == null) {
// 激活的元素.父元素.第一个子元素
// next_dian = active.parentElement.firstElementChild
// }
// 进阶语法: 逻辑短路, 在逻辑或中, 前面是假的, 则会执行后续代码;
next_dian || (next_dian = active.parentElement.firstElementChild)
// 直接触发小圆点的 mouseenter
next_dian.onmouseenter()
}, 2000);
// 下一个 和 上一个 按钮的逻辑, 与自动滚动几乎一样, 仅是利用点击触发
// 更加细节的轮播图: 后续采用 第三方 swiper 实现
</script>
</body>
</html>
标签内容操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>标签内容操作</title>
</head>
<body>
<div id="box">
<a href="">百度一下</a>
</div>
<div id="app">Welcome</div>
<script>
const box = document.getElementById('box')
console.log(box.innerHTML) // HTML标签 + 文本
console.log(box.innerText) // 文本
// 是否相同?
// 如果标签的内容是`纯文本`: HTML和 Text 读取结果相同
console.log(app.innerHTML == app.innerText);
console.log(app.innerHTML) // 其中没有HTML标签, 只有文本
console.log(app.innerText) // 只读文本
// 设置内容:
box.innerHTML = '<h1>Hello</h1>' // 值作为HTML代码解析
app.innerText = '<h1>Hello</h1>' // 值作为普通文本显示
</script>
</body>
</html>
数组转HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数组转html</title>
</head>
<body>
<div id="box"></div>
<script>
const data = ['vue', 'react', 'angular', 'uniapp']
// 要求: 把数据放到按钮里, 显示在 div#box 中
// 高阶函数: map 映射. 把数组中的元素 映射成 HTML代码
const els = data.map(v => `<button>${v}</button>`)
console.log(els);
// 如何把数组的元素, 拼接成字符串: join
console.log(els.join('')) //默认是逗号间隔, 主动传递 ''
box.innerHTML = els.join('') // 参数代表用什么间隔
// 套路: 先用 map 把数组中的元素转换成 HTML 代码
// 然后利用 join 拼接到一起, 设置给 innerHTML
</script>
</body>
</html>
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
.tag {
display: inline-block;
width: 70px;
line-height: 30px;
text-align: center;
background-color: #f6f7f8;
border: 1px solid #ddd;
margin: 0 10px 10px 0;
border-radius: 4px;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
const data = ['番剧', '国创', '综艺', '动画', '鬼畜', '电影', '电视剧', '纪录片', '游戏', '音乐']
// 要求拼接成: <span class='tag'>xxx</span>
// 然后自己书写一个 .tag 的class来设置样式
const a = data.map(y => `<span class='tag'>${y}</span>`)
box.innerHTML = a.join('')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
<style>
a {
text-decoration: none;
padding: 4px;
display: inline-block;
color: gray;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
const data = [
{ title: '新闻', href: 'http://news.baidu.com/' },
{ title: 'hao123', href: 'https://www.hao123.com/' },
{ title: '地图', href: 'https://map.baidu.com/' },
{ title: '贴吧', href: 'https://tieba.baidu.com/' },
{ title: '视频', href: 'https://haokan.baidu.com/' },
]
// 示例: <a href="http://news.baidu.com/">新闻</a>
// 参数解构: ES6 -- JS高级的第五天
const a = data.map(({ title, href }) => `<a href="${href}">${title}</a>`)
box.innerHTML = a.join('')
const b = data.map(v => {
return `<a href='${v.href}'>${v.title}</a>`
})
box.innerHTML = b.join('')
</script>
</body>
</html>
冒泡机制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>冒泡机制</title>
<style>
.red {
height: 600px;
background-color: red;
width: 600px;
}
.blue {
height: 400px;
width: 400px;
background-color: blue;
}
.green {
height: 200px;
width: 200px;
background-color: green;
}
</style>
</head>
<body>
<!--
冒泡机制:
- 当子元素上触发事件, 会自动通知父元素, 触发其相同的事件
- 事件参数e: 其中的target属性存储了 事件触发的当事人
- 利用 stopPropagation() 可以停止冒泡
-->
<div class="red">
<div class="blue">
<div class="green"></div>
</div>
</div>
<script>
// 事件冒泡机制: 当子元素上发生某个事件, 会传递给父元素
// 通俗: 找家长 找老师... -- 家乐被人打了, 家乐找爸爸告状
const red = document.querySelector('.red')
// 凡是事件触发时,都会自动带有事件参数: 包含了事件触发时的各种信息
red.onclick = function (e) {
// 红色触发的点击事件, 不一定是自己触发的, 有可能是子元素传递
console.log(e) // 找到target属性
// e.target: 代表触发事件的 当事人
console.log('red被点击');
}
const blue = document.querySelector('.blue')
blue.onclick = function () {
console.log('blue被点击');
}
const green = document.querySelector('.green')
green.onclick = function (e) {
// stop:停止 propagation: 传播
e.stopPropagation()
// 事件的冒泡机制被终止, 不会通知父元素
console.log('green被点击');
}
</script>
</body>
</html>
事件委托
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件委托</title>
<style>
#box {
padding: 10px;
background-color: #ddd;
}
#box>span {
display: inline-block;
border-radius: 3px;
padding: 5px 10px;
background-color: #aaa;
margin: 0 10px 10px 0;
}
</style>
</head>
<body>
<!-- 事件委托: 元素的事件 交由 父元素来管理, 委托给父元素 -->
<!-- 适用场景: 动态新增的子元素 -->
<input type="text" name="" id="">
<div id="box">
<span>百度</span>
<span>京东</span>
<span>淘宝</span>
<span>阿里</span>
</div>
<script>
const items = document.querySelectorAll('#box span')
items.forEach(item => item.onclick = function () {
this.remove()
})
const inp = document.querySelector('input')
inp.onkeyup = function (e) {
// 键盘事件的 keyCode 属性, 13代表回车
if (e.keyCode == 13) {
// 累加
box.innerHTML += `<span>${this.value}</span>`
this.value = ''
}
}
// 问题: 新增每个元素 都需要重新为其添加 点击事件, 过于繁琐
// 做法: 给父元素添加
box.onclick = function (e) {
// target: 事件触发的当事人
console.log('box被点击:', e.target);
// 查看其属性, 哪个能分辨出span还是div
console.dir(e.target)
if (e.target.tagName == 'SPAN') {
e.target.remove()
}
}
</script>
</body>
</html>
手动创建DOM元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手动创建DOM元素</title>
<style>
#box {
padding: 10px;
background-color: limegreen;
}
</style>
</head>
<body>
<!--
常规的网页制作:
先书写HTML -> 浏览器转换成 DOM元素 -> 显示在浏览器上
-- 合理: HTML相当于语法糖, 容易写容易读
但是: 大神们认为让浏览器 解析HTML代码转换成DOM元素 -- 浪费系统资源; 不如放弃HTML, 直接用JS来创建DOM元素 -- 追求极致的性能
目前 WEB的第二大框架: React 就是采用此方式
-->
<div id="box"></div>
<script>
// 新建一个button
// create创建 Element元素
const btn = document.createElement('button')
btn.innerHTML = '点我'
btn.id = 'b1'
btn.className = 'danger'
console.log(btn);
const box = document.getElementById('box')
// 添加到 box 的子元素
// append:新增/添加 child:子元素
box.appendChild(btn) // 向box元素中,添加子元素
// 字符串 -> 被浏览器解析成DOM元素 -> 再展示到页面上
// box.innerHTML = '<button>啦啦啦</button>'
// a = 6;
// a = 10;
</script>
</body>
</html>
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习</title>
</head>
<body>
<div id="box"></div>
<script>
const data = ['铭铭', '亮亮', '楠楠', '小新', '涛涛']
// 用 forEach 遍历 data, 制作成 DOM元素 (button) 类型
// 添加到 box 的子元素里
data.forEach(v => {
// 常规: 字符串书写HTML代码, 需要浏览器解析成DOM元素
// box.innerHTML += `<button>${v}</button>`
// 高端: 抛弃HTML语法糖, 采用纯DOM
const btn = document.createElement('button')
btn.innerHTML = v
// 添加到 box的子元素
box.appendChild(btn)
})
// 问题: 目前的添加方式, 1个1个挨个往里加
// 类似于: 家乐买了10个雪糕, 要放冰箱里, 问分几步?
// 正常: 3步 开门 -> 一起放进去 -> 关门
// 现在: 开门->放1个->关门 : 一次循环, 我们做了5次
</script>
</body>
</html>
文档片段
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文档片段</title>
</head>
<body>
<div id="box"></div>
<script>
const data = ['铭铭', '亮亮', '楠楠', '小新', '涛涛']
// 之前: 制作一个放一次, 制作一个放一次...
// 现在: 把制作好的DOM元素, 先放在一个虚拟容器里, 一起放到页面
// create创建 Document文档 Fragment片段
// 一个虚拟的容器, 用来放多个DOM元素
const frag = document.createDocumentFragment()
data.forEach(v => {
const btn = document.createElement('button')
btn.innerHTML = v
// 把生成的DOM 先放在 虚拟的 文档片段里
frag.appendChild(btn) // 类似 雪糕放到塑料袋里
})
// box: 相当于冰箱, 把所有东西 一起放进去
box.appendChild(frag)
// box:冰箱
// frag: 塑料袋
// 按钮: 雪糕
// 以前: 雪糕 1个放冰箱 关门; 再开再放1个关门....
// 现在: 先把雪糕放塑料袋, 然后 打开冰箱放进去: 省电
</script>
<!--
此部分: 属于 造火箭的技术 -> 给开发框架 年薪40W .. 用的
但是: 面试可能会问到
面试官的考察点: 上进心 -- 程序员的发展潜力
-->
</body>
</html>
阻止默认事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>阻止默认事件</title>
</head>
<body>
<a href="http://www.tmooc.cn">Go Tmooc</a>
<a href="">xxx</a>
<script>
// 用途: 主要是团队合作
// 例如 家乐(JS) 和 马(HTML) 组队
// 家乐开发JS, 需要给 a 标签添加个性化的 onclick 事件
// 佩奇-不知道不应该写 href: <a href="">xxx</a>
// 防御: 在JS中阻止默认事件, 放置 href 产生的刷新效果
const a = document.querySelector('a')
a.onclick = function (e) {
// prevent阻止 Default默认
e.preventDefault()
// 超链接 带有 href: 点击后默认会进行跳转操作
alert('a被点击了')
}
</script>
</body>
</html>
事件监听器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件监听器</title>
</head>
<body>
<!-- 事件监听器: 团队合作, 多个人向同一个按钮添加多个事件 -->
<button>我是按钮</button>
<script>
const btn = document.querySelector('button')
// 问题: onclick 是个属性, 同时只能赋1个值
btn.onclick = function () {
alert("家乐是最棒的!")
}
btn.onclick = function () {
alert("佩奇才是最棒的!")
}
// 事件监听器: 可以为1个事件 添加多个方法
// add添加 Event事件 Listener监听器
// 参数1: 事件名 -- 系统规定, 注意没有 on 开头
btn.addEventListener('click', function () {
alert('111111')
})
btn.addEventListener('click', function () {
alert(22222)
})
</script>
</body>
</html>
鼠标事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>鼠标事件</title>
<style>
#box {
width: 500px;
height: 500px;
background-color: #999;
user-select: none;
position: relative;
}
#box>span {
position: absolute;
display: inline-block;
width: 26px;
text-align: center;
line-height: 26px;
border-radius: 50%;
border: 3px solid white;
color: white;
background-color: blue;
}
</style>
</head>
<body>
<!--
思路:
1. 点击时, 创建一个元素 添加到页面上
2. 通过事件参数, 获取 点击的坐标
3. 设置给创建的元素, 显示在对应位置
-->
<div id="box"></div>
<script>
let num = 1
box.onclick = function (e) {
// 仅限 事件触发的当事人 target, 是box 的场景 才添加
if (e.target !== this) return
console.log(e) //展开查看, 猜一猜哪个是坐标
// x,y: 点击位置距离 浏览器内容的左上角
// offsetX, offsetY: 点击位置距离当前元素的左上角
// screenX, screenY: 距离屏幕的左上角
const span = document.createElement('span')
span.innerHTML = num++ // 先赋值, 再+1
const { offsetX, offsetY } = e
// 默认是左上角, 需要移动到中间, 所以-13 1半的宽
span.style.top = offsetY - 13 + 'px'
span.style.left = offsetX - 13 + 'px'
this.appendChild(span)
}
</script>
</body>
</html>
滚动监听
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>滚动监听</title>
<style>
#box>div {
padding: 10px;
border-radius: 10px;
background-color: gray;
margin-bottom: 10px;
width: 300px;
}
#xx {
right: 0;
position: fixed;
top: 0;
width: 100%;
height: 100px;
background-color: purple;
}
/* .hide {
display: none;
} */
</style>
</head>
<body>
<!-- 监听页面的滚动距离, 切换内容的显示与否 -->
<div id="box"></div>
<!-- diplay:'' -->
<div id="xx" style="display: none"></div>
<script>
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div')
div.innerHTML = i
box.appendChild(div)
}
// window提供的, 监听窗口的滚动
window.onscroll = function () {
// console.log('onscroll');
// 获取滚动的距离: 由于兼容性问题, 提供两种读取方式, 在不同浏览器上不一定哪个好用. y的值就是其中 正常读取的值
// document.documentElement.scrollTop: 获取滚动的距离
// document.body.scrollTop: 获取滚动的距离
const y = document.documentElement.scrollTop || document.body.scrollTop
// 设定: 至少有一个人会答应, 不一定是谁
// 例如: 家乐的媳妇 = 迪丽热巴答应不 || 马尔扎哈答应不
// 所以: 家乐的媳妇是 后方表达式中 首个 为真的
console.log('y:', y);
// 如果 y > 4000 像素 就显示 div#xx; 否则就隐藏
// display="none" 代表隐藏
// display="" 代表不隐藏
xx.style.display = y > 4000 ? '' : 'none'
// if (y > 4000) {
// xx.classList.remove('hide')
// } else {
// xx.classList.add('hide')
// }
}
// 逻辑或 表达式的值: 是从左到右 第一个真值, 如果没有则是最后一个
var a = null || 0 || '' || 11
console.log(a);
var b = null || 0 || '' || false || undefined
console.log(b)
</script>
</body>
</html>
回顾
-
标签内容
-
innerHTML: 读取内容中的
html + 文本
-
innerText: 读取内容中的
文本
-
注意
: 如果标签内容只有文本
, 则两种方式读取结果一样
-
-
数组转HTML显示到页面的方式
-
利用 map 方法映射数组为 HTML代码
-
利用数组的 join 方法拼接成字符串
-
利用 innerHTML 设置给元素
-
-
冒泡机制
-
当事件触发时, 会传递给父元素, 触发其相同的事件
-
阻止冒泡:
e.stopPropagation()
-
事件委托: 通过父元素来帮子元素实现事件, 适合
动态新增
的子元素
-
-
手动创建DOM元素 -- 获得极致的性能
重要的理念
-
不写HTML代码, 而是直接用JS代码来创建DOM元素
-
-
阻止默认事件:
e.preventDefault()
-
事件监听器:
addEventListener
-
可以为一个事件 重复绑定多个方法
-
-
鼠标事件: 主要是 几个
坐标值
-
滚动监听:
onscroll
监听滚动的距离, 然后做事-
总体思路:
监听滚动距离
当达到一个临界值, 把元素显示/隐藏
-
扩展视频
www.xin88.top 提供的网盘里, 有进阶视频, 查看 防抖和节流
DOM05
复习
DOM的核心操作: 找到元素
-> 操作其属性
-
找到元素的方式
-
固定:
head
,body
,documentElement
-
关系: 儿子们, 第一个孩子, 下一个兄弟, 父...
-
特征: id, 标签名, class, name
-
css选择器:
querySelector
和querySelectorAll
-
-
属性的操作
-
标签的内容
-
innerHTML: 获取
HTML+文本
-
innerText: 获取
文本
-
注意: 如果标签中
只有
文本内容, 则两种读法结果相同
-
-
数组转HTML:
-
数组中存储的是数据, 使用map映射成HTML
-
利用 join() 拼接成字符串
-
利用 innerHTML 添加到元素中
-
-
冒泡: 事件在元素上触发时, 会传递给其父元素, 触发相同的事件
-
利用事件参数 :
stopPropagation
来阻止冒泡 -
使用场景: 动态添加的子元素 的事件监听, 适合给父元素添加
-
事件委托
: 子元素的事件 委托给父元素处理
-
-
-
追求极致的性能: 通过JS创建DOM元素
-
普通: 先书写HTML -> 浏览器帮助转换成DOM -> 显示到页面
-
现在: JS创建DOM的代码 -> 显示到页面
-
-
阻止默认:
preventDefault
-
事件监听器: 在团队合作项目中非常好用
-
addEventListener
: 可以为一个事件 添加多个方法
-
-
鼠标事件: 记住几组坐标值的用法, 坐标系是什么
-
滚动监听:
-
onScroll
事件: 来自window. 用来监听整个页面的滚动 -
通常搭配滚动偏移量, 来决定一些元素的显示与否
-
因为兼容性的问题, 不同浏览器, 读取滚动偏移量
scrollTop
方式不同 有的是从body
读取, 有的是从documentElement
读取 -
const y = document.body.scrollTop || document.documentElement.scrollTop
-
逻辑或表达式的值: 从左到右第一个真值, 如果没有真值,则使用最后一个
const a = null || false || 0 || 11 || true //a = 11
-
-
-
有时间多回顾 CSS: class 和 style 是两个体系
class: 优先级比style低, 具体看 选择器的权重
style: 最高的优先级
如果style的属性 和 class 的属性重复, 则style生效
style="display: none"
: 隐藏
元素.style.display=''
: 空字符串代表这个style没有设置, 则class生效
属性读取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>属性读取</title>
</head>
<body>
<a href="http://www.tmooc.cn" id="a1" class="danger" data-xx="11" data-yy="22">Go Tmooc</a>
<script>
// DOM元素的属性分: 系统 和 自定义 data-
const a1 = document.getElementById('a1')
console.dir(a1)
// 读取属性的 旧写法
// get获取 Attribute属性
console.log(a1.getAttribute('id'))
console.log(a1.getAttribute('href'))
// 修改: set设置
a1.setAttribute('href', 'http://www.baidu.com')
// 判断元素是否设置了 某个属性
// has: 有
console.log(a1.hasAttribute('id')) //true
console.log(a1.hasAttribute('target')) //false
// 自定义属性
console.log(a1.getAttribute('data-xx'))
//读取系统属性
console.log(a1.id)
console.log(a1.className)
// 自定义属性 dataset
console.log(a1.dataset.xx)
console.log(a1.dataset.yy)
</script>
</body>
</html>
BOM
Browser Object Model
: 浏览器对象模型一些用于操作浏览器的API
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>地址栏</title>
</head>
<body>
<!-- replace: 替换 -->
<button onclick="location.replace(`http://www.baidu.com`)">切换到百度</button>
<button id="b3">3秒后跳转</button>
<script>
// 手动为当前路径结尾添加 ?name=家乐&age=19
// URLSearchParams: 专门转化 URL的传参
const params = new URLSearchParams(location.search)
console.log(params.get('name')) // 读取 name 属性的值
b3.onclick = function () {
setTimeout(() => {
location.replace('http://www.tmooc.cn')
}, 3000);
}
console.log(location);
// 需求1: 每隔2s 刷新一次页面
setInterval(() => {
// location.reload()
}, 2000);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>open</title>
</head>
<body>
<!-- 编程方式开启新的网页:open -->
<a href="http://www.baidu.com" target="_blank">百度一下</a>
<!-- 常见于 广告 -->
<button id="b1">3秒后开启新页面</button>
<script>
b1.onclick = function () {
setTimeout(() => {
open('http://www.tmooc.cn')
// JS高级第一天: 在全局中直接用的属性, 存储在 window 里
}, 3000);
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浏览器信息</title>
</head>
<body>
<a href="./05.历史信息.html">历史</a>
<script>
console.log(navigator);
// 读取到 浏览器所在的系统信息, 浏览器的插件信息等...
// 然后可以判断 进而提供个性化的一些操作
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>历史信息</title>
</head>
<body>
<!-- 利用 history 的 go 方法 -->
<!-- go(n): n<0代表后退 n>0代表前进 n=0 代表刷新 -->
<!-- 如下: n是几,就是几页-->
<button onclick="history.go(-1)">上一页</button>
<button onclick="history.go(1)">下一页</button>
<button onclick="history.go(0)">刷新</button>
<hr>
<a href="./04.浏览器信息.html">浏览器信息</a>
<script>
console.log(history);
</script>
</body>
</html>