DOM节点
- DOM树里的每一个内容都称为节点
节点类型
-
元素节点
- 所有标签,如body、div
- html是根节点
-
属性节点
- 所有属性,如href
-
文本节点
- 所有文本
-
其他
节点操作
查找节点
节点关系:父节点、子节点、兄弟节点
父节点查找
parentNode属性、返回最近一级的父节点,找不到返回null
语法:
子元素.parentNode
案例:关闭二维码案例
需求:多个二维码,点击谁,谁关闭
分析:
- 需要给多个按钮绑定点击事件
- 关闭的是当前的父节点
<div class="erweima">
<img src="images/code.png" alt="" />
<span> X1 </span>
</div>
<div class="erweima">
<img src="images/code.png" alt="" />
<span> X2 </span>
</div>
<div class="erweima">
<img src="images/code.png" alt="" />
<span> X3 </span>
</div>
<script>
//获取关闭按钮
let col = document.querySelectorAll('span')
//遍历给每个按钮添加事件
for (let i = 0; i < col.length; i++) {
col[i].addEventListener('click', function () {
//将父元素隐藏
this.parentNode.style.display = 'none'
})
}
</script>
子节点查找
- childNodes:获取所有子节点、包括文本节点(空格、换行)、注释节点
- children:仅获得所有子元素节点、返回的是伪数组
语法:
父元素.children
兄弟关系查找
- 下一个兄弟节点:nextElementSibling 属性
- 上一个兄弟节点:previousElementSibling 属性
增加节点
创建元素节点
方法:
document.createElement('标签')
追加节点
插入到父元素的最后一个子元素
父元素.appendChild(标签)
插入到父元素中某个子元素的前面
父元素.insertBefore(插入元素, 插在那个元素前)
\案例:学成在线案例渲染
需求:按照数据渲染页面
分析:
- 准备好空的ul 结构
- 根据数据的个数,创建一个新的空li
- li里面添加内容 img 标题等
- 追加给ul
<script>
let data = [ { src: 'images/course01.png', title: 'Think PHP 5.0 博客系统实战项目演练111', num: 1125 }, { src: 'images/course02.png', title: 'Android 网络动态图片加载实战', num: 357 }]
let myul = document.querySelector('ul')
for (let i = 0; i < data.length; i++) {
//创建li标签
let myli = document.createElement('li')
//在li标签插入内容
myli.innerHTML = `
<img src="${data[i].src}" alt="" />
<h4>
${data[i].title}
</h4>
<div class="info">
<span>高级</span> • <span>${data[i].num}</span>人在学习
</div>`
//将li标签插入空的ul
myul.appendChild(myli)
</script>
克隆节点
元素.cloneNode(布尔值) //复制一个元素
cloneNode的参数:
- 若为true,则代表克隆时会包含后代节点一起克隆
- 若为false,则代表克隆时不包含后代节点
- 默认为false
删除节点
通过父元素删除
父元素.removeChild(要删除的元素)
注意:
- 不存在父子关系则删除不成功
- 删除节点和隐藏节点(display:none)的区别: 隐藏节点还是存在的,但是删除,则从html中删除节点
时间对象
实例化
- 在代码中发现了 new 关键字时,一般将这个操作称为实例化
- 创建一个时间对象并获取时间
获得当前时间
let date = new Date()
获得指定时间
let date = new Date('2021-11-17')
时间对象中常用的方法
| 方法 | 作用 | 说明 |
|---|---|---|
| getFullYear() | 获得年份 | 获取四位年份 |
| getMonth() | 获得月份 | 取值为 0 ~ 11 |
| getDate() | 获取月份中的每一天 | 不同月份取值也不相同 |
| getDay() | 获取星期 | 取值为 0 ~ 6 |
| getHours() | 获取小时 | 取值为 0 ~ 23 |
| getMinutes() | 获取分钟 | 取值为 0 ~ 59 |
| getSeconds() | 获取秒 | 取值为 0 ~ 59 |
案例:页面显示时间
需求:将当前时间以:YYYY-MM-DD HH:mm 形式显示在页面
分析:
- 调用时间对象方法进行转换
- 字符串拼接后,通过 innerText 给 标签
<span></span>
<script>
let spa = document.querySelector('span')
let date = new Date()
//获取年份YY
let year = date.getFullYear()
// 获取月份
let month = date.getMonth()
// 日期
let day = date.getDate()
let hours = date.getHours()
let min = date.getMinutes()
spa.innerHTML = `${year}-${month}-${day} ${hours}:${min}`
</script>
时间戳
是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式
获取时间戳方式:
let date = new Date()
console.log(date.getTime())
简写+new Date()
console.log(+new Date())
使用 Date.now()
console.log( Date.new())
注:
- 无需实例化,但是只能得到当前的时间戳, 而前面两种可以返回指定时间的时间戳
+new Date() 可以返回当前时间戳或者指定的时间戳
案例:倒计时效果
分析:
- 用将来时间减去现在时间就是剩余的时间
- 核心: 使用将来的时间戳减去现在的时间戳
- 把剩余的时间转换为 天 时 分 秒
距离2021-11-20:<span></span>
<script>
setInterval(() => {
let time = (+new Date(2021, 11, 20) - new Date())
time /= 1000
let spa = document.querySelector('span')
let d = parseInt(time / 60 / 60 / 24 % 30)
let h = parseInt(time / 60 / 60 % 24)
let m = parseInt(time / 60 % 60)
let s = parseInt(time % 60)
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
spa.innerHTML = `${d}天${h}时${m}分${s}秒`
}, 1000);
</script>
重绘回流
游览器进行界面渲染的方式
- 解析(Parser)HTML,生成DOM树(DOM Tree)
- 同时解析(Parser) CSS,生成样式规则 (Style Rules)
- 根据DOM树和样式规则,生成渲染树(Render Tree)
- 进行布局 Layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置,大小)
- 进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制
- Display: 展示在页面上
重绘
由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。
回流(重排)
当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。
一般会导致回流的操作:
- 页面的首次刷新
- 浏览器的窗口大小发生改变
- 元素的大小或位置发生改变
- 改变字体的大小
- 内容的变化(如:input框的输入,图片的大小)
- 激活css伪类 (如::hover)
- 脚本操作DOM(添加或者删除可见的DOM元素)
重绘不一定引起重排(回流),但重排(回流)一定会引起重绘