第十四章:DOM
14.1 节点层级
- 文档元素:html
14.1.1 Node 类型
nodeType
Node.ELEMENT_NODE
:1Node.ATTRIBUTE_NODE
:2Node.TEXT_NODE
:3Node.CDATE_SECTION_NODE
:4Node.ENTITY_REFERENCE_NODE
:5Node.ENTITY_NODE
:6Node.PROCESSING_INSTRUCTION_NODE
:7Node.COMMENT_NODE
:8Node.DOCUMENT_NODE
:9Node.DOCUMENT_TYPE_NODE
:10Node.DOCUMENT_FRAGMENT_NODE
:11Node.NOTATION_NODE
:12
1. nodeName
与 nodeValue
- 值取决于节点类型
2. 节点关系
childNodes
hasChildNodes()
parentNode
previousSibling
和nextSibling
:前后的兄弟节点firstChild
和lastChild
ownerDocument
:指向代表整个文档的文档节点
3. 操纵节点
appendChild()
:传入已存在的节点时,会将它移动到新位置insertBefore()
replaceChild()
:返回被替换的节点removeChild()
4. 其他方法
cloneNode()
:传入布尔值,决定是否深复制- 只会复制 html 属性
normalize()
:删除空文本节点,合并相邻的文本节点
14.1.2 Document 类型
nodeType: Node.DOCUMENT_NODE
nodeName: "#document"
nodeValue: null
parentNode: null
ownerDocument: null
- 子节点可以是
DocumentType
(最多一个)、Element
(最多一个)、ProcessingInstruction
或Comment
1. 文档子节点
documentElement
:指向<html>
baody
:指向<body>
doctype
:指向<!doctype>
2. 文档信息
title
:修改此属性不会改变<title>
URL
:包含当前页面的完整 URL,不可设置domain
:包含页面的域名,不能设置为 URL 中不包含的值- 放松后不能再收紧
referrer
:包含链接到当前页面的那个页面的 URL,不可设置
3. 定位元素
getElementById()
getElementByTagName()
namedItem()
<img src="" name="myImage"></img>
const imgs = document.getElementsByTagName("img");
let myImg1 = imgs.namedItem("myImage");
let myImg2 = imgs['myImage'];
getElementsByName()
4. 特殊集合
document.anchors
:所有带 name 属性的<a>
元素document.forms
:所有<form>
元素document.images
document.links
:所有带 href 属性的<a>
元素
5. DOM 兼容性检测
6. 文档写入
write() / writeln()
open() / close()
14.1.3 ELement 类型
nodeType: Node.ELEMENT_NODE
nodeName: 元素标签名
- 通过
nodeName / tagName
获取(建议转换为小写)
- 通过
nodeValue: null
parentNode: Document / Element 对象
- 子节点:p414(第四版)
1. HTML 元素
id
title
lang
dir
:语言书写方向- ltr:从左向右
- rtl:从右向左
className
2. 取得属性
getAttribute()
3. 设置属性
setAttribute()
removeAttribute()
4. attribute 属性
- p418(第四版)
5. 创建元素
document.createElement()
6. 元素后代
14.1.4 Text 类型
nodeName: '#text'
nodeValue: 节点包含的文本
- 不支持子节点
- 方法:
appendData()
deleteData(offset, count)
insertData(offset, text)
replaceData(offset, count, text)
splitText(offset)
:在指定位置将当前文本节点拆分为两个substringData(offset, count)
1. 创建文本节点
document.createTextNode()
2. 规范化文本节点
normalize()
3. 拆分文本节点
14.1.5 Comment 类型
nodeName: '#comment'
nodeValue: 注释的内容
- 不支持子节点
14.1.6 CDATASection 类型
- 表示 XML 中特有的 CDATA 区块
- p423(第四版)
14.1.7 DocumentType 类型
nodeValue: null
14.1.8 DocumentFragment 类型
- 不能添加到文档,作用是充当其他要被添加的节点的仓库
nodeName: '#document-fragment'
nodeValue: null
document.createDocumentFragment()
<ul id='list'></ul>
let fragment = document.createDocumentFragment();
let ul = document.getElementsById("list");
for (let i = 0; i < 3; i++) {
let li = document.createElement("li");
li.appendChild(document.createTextNode(`item - ${i}`));
// 直接插入 ul 会导致浏览器多次重新渲染页面
fragment.appendChild(li);
}
ul.appendChild(fragment); // fragment 中的节点被添加到 ul 中,而其本身不会被添加进去
14.1.9 Attr 类型
nodeName: 属性名
nodeValue: 属性值
- HTML 中不支持子节点
- 属性:
- name
- value
- specified:布尔值,表示属性是否使用默认值
document.createAttribute()
setAttributeNode()
14.2 DOM 编程
14.2.1 动态脚本
- 通过 innerHTML 属性创建的脚本元素永远不会执行
14.2.2 动态样式
<link rel="stylesheet" type="text/css" href="styles.css">
14.2.3 操作表格
- p429(第四版)
14.2.4 使用 NodeList
14.3 MutationObserver 接口
- 可以在 DOM 被修改时异步执行回调
14.3.1 基本用法
let observer = new MutationObserver(() => console.log("DOM changed"));
1. observe()
方法
- 新创建的 MutationObserver 实例不会关联 DOM 的任何部分,需要调用该方法
let observer = new MutationObserver(() => console.log("body attributes changed"));
observer.observe(document.body, { attributes: true });
2. 回调与 MutationRecord
- 每个回调都会收到一个 MutationRecord 实例的数组,实例包含的信息包括发生了什么变化、DOM 的那一部分受到了影响
3. disconnect()
方法
4. 复用 MutationObserver
- 多次调用
observe()
可以复用一个 MutationObserver 对象观察多个不同的目标节点 disconnect()
会停止观察所有目标
5. 重用 MutationObserver
14.3.2 MutationObserverInit 与观察范围
-
observe()
接收的第二个参数 -
MutationObserverInit 对象用于控制对目标节点的观察范围
-
p438(第四版)
14.3.3 异步回调与记录队列
1. 记录队列
2. takeRecords()
方法
- 清空记录队列,取出并返回其中的 MutationRecord 实例