js【详解】DOM ( 含 12 种节点类型,NodeList 与 HTMLCollection 的区别,DOM 的增删改查、提升 DOM 的性能等)

文档对象模型(Document Object Model,简称DOM)

DOM 是哪种数据结构 ?

DOM 的本质是浏览器通过HTML代码解析出来的一棵

在这里插入图片描述

一个 HTML 页面就是一个文档,使用 document 表示

每个文档由不同类型的节点(共12 种)构成:

1. 元素节点(Element Nodes)

HTML中的标签(如<div><p><a>等)都被视为元素节点。

  • nodeType值:1

  • nodeName属性:返回元素的标签名(大写)

  • nodeValue属性:对于元素节点,此属性通常不包含值或返回null。

2. 属性节点(Attribute Nodes)

元素节点的属性(如 <a href="https://www.example.com"> 中的href)。

  • nodeType值:2

  • nodeName属性:返回属性的名称

  • nodeValue属性:返回属性的值。

3. 文本节点(Text Nodes)

元素节点或属性节点中的文本内容。

  • nodeType值:3

  • nodeName属性:总是返回#text

  • nodeValue属性:返回文本节点的内容。

4. CDATA区段节点 (CDATA_SECTION_NODE)

  • nodeType值:4

5. 实体引用元素节点 (ENTITY_REFERENCE_NODE)

  • nodeType值:5

6. 实体节点 (ENTITY_NODE)

  • nodeType值:6

7. 处理指令节点 (PROCESSING_INSTRUCTION_NODE)

  • nodeType值:7

8. 注释节点(Comment Nodes)

HTML中的注释内容,以 <!-- 注释内容 --> 形式出现。

  • nodeType值:8

  • nodeName属性:总是返回#comment

  • nodeValue属性:返回注释的内容。

9. 文档节点(Document Nodes)

整个文档对象,通常通过 document 对象访问。

  • nodeType值:9

  • nodeName属性:返回#document

  • nodeValue属性:对于文档节点,此属性通常不包含值或返回null。

10. 文档类型节点(Document Type Nodes)

文档类型声明(如<!DOCTYPE html>)。

  • nodeType值:10

  • nodeName属性:返回文档类型的名称(如html)

  • nodeValue属性:对于文档类型节点,此属性通常不包含值或返回null。

11. 文档片段节点(Document Fragment Nodes)

轻量级的文档对象,可以包含节点和子树,但不会被认为是文档的一部分。常用于临时存储和操作节点,以提高性能。

  • nodeType值:11

12. DTD中声明的符号节点

  • nodeType值:12

NodeList 对象

由不同类型节点构成的类数组

通过 querySelectorAll 和 childNodes 可得到 NodeList 对象

document.querySelectorAll('body') instanceof NodeList // true
document.body.childNodes instanceof NodeList // true

只有 childNodes 返回的是一个动态集合( DOM 删除或新增一个相关节点,都会立刻反映在 NodeList 实例 ),其他的 NodeList 都是静态集合。

NodeList 对象的属性

  • length属性:节点的数量

NodeList 对象的方法

  • forEach 方法:遍历节点
  • item 方法: 接受一个整数值作为参数,表示成员的位置,返回该位置上的成员。
document.body.childNodes.item(0) // 返回第一个成员,等同于 document.body.childNodes[0]
  • keys 方法:返回键名的遍历器
  • values 方法:返回键值的遍历器
  • entries 方法:返回的遍历器同时包含键名和键值的信息

HTMLCollection 对象

仅由元素节点构成的类数组,不能包含其他类型的节点。

通过 getElementsByTagName、children、document.images、document.links 等可得到 HTMLCollection 对象

document.getElementsByTagName('div') instanceof HTMLCollection // true

document.getElementsByTagName('div')[0].children instanceof HTMLCollection // true

HTMLCollection 实例都是动态集合,节点的变化会实时反映在集合中。

HTMLCollection 对象的属性

  • length 属性:元素节点的数量

HTMLCollection 对象的方法

  • item 方法: 参数为一个整数值,表示成员的位置,返回该位置上的成员。
document.getElementsByTagName('div').item(0) // 返回第一个元素节点,等同于 document.getElementsByTagName('div')[0]
  • namedItem 方法: 参数是一个字符串,表示 id 属性或 name 属性的值,返回对应的元素节点。如果没有对应的节点,则返回 null。

【考题】HTMLCollection 与 NodeList 的区别

  • NodeList 内的节点可以是各种类型,HTMLCollection内的节点只能是元素节点
  • NodeList 支持 forEach,HTMLCollection 不支持 forEach
  • NodeList 通过 querySelectorAll 和 childNodes 获取,HTMLCollection 通过 getElementsByTagName 和 children 获取

操作 DOM 常用的 API 有哪些 ?

获取 DOM 节点

//方式 1:通过【id】获取,返回目标 DOM 元素
let div1 = document.getElementById("box1"); 

//方式 2:通过【标签名】获取,返回【类数组】
let arr_class_1 = document.getElementsByTagName("div"); 

//方式 3:通过【样式类名】获取,返回【类数组】
let arr_class_2 = document.getElementsByClassName("hehe"); 

//方式 4:通过【CSS选择器】获取,返回符合条件的第一个 DOM 元素
let div1 = document.querySelector("selector") 

//方式 5:通过【CSS选择器】获取,返回符合条件的所有元素构成的【类数组】
let arr_class_2=3 =document.querySelectorAll("selector") 

修改 DOM 节点

property

property 方式:按对象属性的方式操作 DOM

// 元素.style.样式名 = 新样式值
元素.style.width = "300px";
// 含 - 的样式名,需用驼峰写法
元素.style.backgroundColor = "red"; 
// 一次修改多个样式
元素.style.cssText = "width: 300px;height: 300px;background-color: green;"
// 获取样式
元素.style.样式名

attribute

attribute 方式:使用setAttribute,getAttribute 操作 DOM 的属性

// 元素节点.setAttribute("属性名", "新的属性值");
myNode.setAttribute("class","red");
myNode.getAttribute("class") // red

property 和 attribute 的区别

  • property【推荐】 修改对象属性,不会体现到 html 结构中,可能会引起 DOM 重新渲染

    更推荐使用 property 是因为浏览器的优化,某些修改不会触发 DOM 重新渲染

  • attribute 修改 html 属性,会改变 html 结构,一定会引起 DOM 重新渲染

创建 DOM 节点

// document.createElement("标签名")
const newP = document.createElement('p')
newP.innerHTML = 'this is newP'

创建文档片段

const frag = document.createDocumentFragment()

使用范例如下:

在这里插入图片描述

插入 DOM 节点

作为父元素的最后一个子元素插入

父元素.appendChild(要插入的元素)

插入到父元素中某个子元素的前面

父元素.insertBefore(要插入的元素, 在哪个元素前面)

移动 DOM 节点

  <body>
    <div id="parent">
      <p id="first">段落1</p>
      <p id="second">段落2</p>
    </div>

    <script>
      var parent = document.getElementById("parent");
      var first = document.getElementById("first");
      // 将first移动到parent的末尾
      parent.appendChild(first);
    </script>

删除 DOM 节点

父节点.removeChild(子节点)

替换 DOM 节点

parentNode.replaceChild(newNode,oldNode);

获取父节点

子节点.parentNode

获取子节点列表(类数组)

const div1 = document.getElementById('div1')
// 父节点.childNodes
let div1ChildNodes = div1.childNodes

【考点】如何提升 DOM 的性能?

DOM 渲染会阻断 js 的运行,且对计算机的资源消耗很大,所以需要尽量减少 DOM 操作,来提升其性能,具体方式如下:

  1. 对 DOM 的查询做缓存

    在这里插入图片描述

  2. 将频繁的 DOM 操作改为一次性操作

    优化前
    在这里插入图片描述

    优化后
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朝阳39

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值