一、节点层级
在HTML中,文档元素始终是<html>,XML中任何元素都能成为文档元素
DOM中共有12种节点类型,如元素节点、属性节点、文档类型节点、注释节点等,都继承于Node类型
1.Node类型
nodeType: 表示节点类型,由12个常量取值,如Node.ELEMENT_NODE
浏览器并不支持所有节点类型
nodeName与nodeValue:对元素而言,前者对应标签名,后者始终为null
节点关系:
childNodes:类数组对象,可以使用[index]访问,有length属性,实时快照
someNode.childNodes[1] === someNode.childNodes.item(1)
parentNode
previousSibling nextSibling
firstChild lastChild
hasChildNodes() :返回true or false
ownerDocument: 所有结点共享的关系,指向代表整个文档的文档节点
操纵节点:
appendChild():将新节点添加到末尾,或者将已存在节点移动到末尾
insertBefore(新节点,参照节点):参照节点为null时从末尾添加
replaceChild(新节点,要被替换的节点)
removeChild(要移除的节点)
其他方法:
cloneNode():传入true表示复制当前节点及所有子DOM树;false则复制当前节点
不会复制JavaScript属性
Normalize():处理文本节点,如果为空则删除,如果多个并列则合并
2.Document类型
表示文档节点的类型
1)文档子节点
可以是:DocumentType Element ProcessingInstruction Comment
documentElement属性始终指向HTML页面中<html>元素
body属性始终指向body元素
doctype属性(若存在)则指向文档声明、comment文档外的注释
2)文档信息
title属性
URL 当前页面完整url
domain 包含页面的域名
referrer 包含链接到当前页面的那个页面的url
3)定位元素
getElementById()
getElementsByTagName()
HTMLCollection取特定元素item(), namedItem()
getElementsByName()
4)特殊集合
document.anchors 带name属性的<a>
document.applets 所有<applet>元素
document.forms 所有<form>元素
document.images 所有<img>元素
document.links 所有带href的<a>元素
5)兼容性监测
document.implementation属性,提供hasFeature(feature, version)方法,返回true则支持 【已废弃】
6)文档写入
document.write()简单写入一个文本
document.writeln() 写入后加一个换行符
open() close()打开和关闭网页输出流
3.Element类型
表示XML或者HTML元素
在HTML中,元素标签名始终全大写;在XML中,标签名始终与源代码中一致
1)HTML元素
id
title 提示语
lang 元素内容语言
dir 语言书写方向“ltr" "rtl"
className
2)属性值操作
getAttribute()
setAttribute()
removeAttribute()
3)attributes属性
getNamedItem()
removeNamedItem()
setNamedItem()
item()
4)创建元素
document.createElement(tagName)
5)元素后代
childrenNodes属性,getElementsByTagName()
避免存在空文本子节点,建议对nodeType进行判断
4.Text类型
表示纯文本节点
操作文本的方法
appendData(text)
deleteData(offset,count)
insertData(offset,text)
replaceData(offset, count, text)
splitText(offset) 从offset将当前文本节点拆成两个文本节点
substringData(offset, count)提取子文本
length属性 nodeValue.length === data.length
1)创建文本节点
document.createTextNode(text)
2)规范化文本节点
normalize()
3)拆分文本节点
splitText()
5.Comment类型
注释节点
拥有处理splitText()之外的所有Text节点的操作方法
6.CDATSection类型
表示XML中特有的CDATA区块
和Comment操作方法相同
在XML中可以使用document.createCDataSection()
7.DocumentType类型
表示文档类型信息
name 文档类型名称
entities 文档类型描述的NamedNodeMap
notations 文档类型描述表示法的NamedNodeMap
8.DocumentFragment类型
唯一在标记中没有对应类型
document.createDocumentFragment()
9.Attr类型
name 属性名
value 属性值
specified 是否是默认值
二、DOM编程
1.动态脚本
两种方式:引入外部脚本和直接插入源代码
1)创建script标签,设置src属性,document.body.appendChild()
2)document.createElement('script'), 设置text属性或者appendChild(dcoument.createTextNode(code)),添加到body
2.动态样式
类似于动态脚本
1)动态创建link,需要设置的属性有,link.rel link.type link.href 添加到head
2)动态创建style,appendChild()或者style.styleSheet.cssText
3.操作表格
<table>元素属性和方法
caption
tBodies
tFoot
tHead
rows
createTHead()
createTFoot()
createCaption()
deleteTHead()
deleteTFoot()
deleteCaption()
deleteRow(pos)
insertRow(pos)
<tbody>属性和方法
rows
deleteRow(pos)
insertRow(pos)
<tr>属性和方法
cells
deleteCell(pos)
insertCell(pos)
4.使用NodeList
NodeList NamedNodeMap HTMLCollection都是实时的
三、MutationObserver接口
可以在DOM被修改时执行异步回调
1.基本用法
MutationObserve实例通过调用构造函数创建并传入一个回调函数来创建
let observer = new MutationObserver(() => console.log('DOM was mutated'))
1)observe()
observe(dom节点,mutationObserverInit对象) 将observer与Dom关联起来
2)回调与MutationRecord
每个回调都会收到一个MutationRecord实例的数组,MutationRecord记录变化信息
回调函数的第二个参数为observer实例
3)disconnect()
提前终止回调
使用setTimeout可以让已经入列的信息被观察后再断联
4)复用MutationObserver
可以多次调用observe(),用一个MutationObserver对象观察多个不同的目标节点
MutationRecord的target属性标记不同的目标节点
5)重用MutationObserver
disconnect()方法并没有结束实例的生命,可以继续observe()
2.MutationObserverInit对象与观察范围
粗略可分属性变化、文本变化、子节点变化
Subtree 是否观察子树,默认false,
Attributes 属性变化,默认false
attributeFilter 字符串数组,要观察那些属性
attributeOldValue 默认false
characterData 修改字符数据是否出发事件,默认false
characterDataOldValue
childList 修改目标节点的子节点是否触发变化事件
1)观察属性
观察属性节点的添加、修改、删除
2)观察字符串数据
文本节点(Text Comment ProcessingInstruction节点)的添加、修改、删除
3)观察子节点childList
子节点的添加和移除
子节点重新排序会触发两次
4)观察子树
将观察事件扩展到整个元素的子树
3.异步回调与记录队列
记录队列对于每个MutationObserver实例都是唯一的,是所有DOM变化事件的有序队列
1)记录队列
每次MutationRecord实例被添加到记录队列中,当且仅当之前没有排期的微任务时,才会将MutationObserver的回调作为微任务调度到任务队列中。保证记录队列的内容不会被回调处理两次。
2)takeRecords()
调用takeRecords()方法可以取出记录队列中所有MutationRecord实例,并清空记录队列
四、性能、内存和垃圾回收
MutationObserver对目标节点具有弱引用;
目标节点对MutationObserver具有强引用
记录队列中每个MutationRecord实 例至少包含对已有DOM节点的一个引用