WebAPI DOM节点操作 时间对象 重绘回流

148 阅读3分钟

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>

重绘回流

游览器进行界面渲染的方式

图片1.png

  • 解析(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元素)

重绘不一定引起重排(回流),但重排(回流)一定会引起重绘