一. 首先要了解什么是 DOM?
DOM: 全称 Document Object Mode 文档对象模型,表示由多层节点构成的文档。
document: 表示每个文档的根节点,它的唯一子结点是 html,也就是文档元素 (documentElement),文档元素是文档最外层的元素,所有子元素都存在于这个元素之内。每个文档只有一个文档元素。
Node: 表示 dom 中的节点,DOM 中一共有12中节点类型,而这12个节点都继承至 Node类型。
二. DOM 中的节点类型
1. Node类型
所有dom中的节点都来至于该类型,共享该类型上的方法和属性。
属性:
- nodeType: 表示节点的类型
- nodeName: 表示元素标签名(前提是该node类型为元素)
- nodeValue:元素的该值始终未 null
- childNodes: 表示该节点下的所有子结点,它是继承至
NodeList类型,是一个类数组类型。 - parentNode: 当前节点的父节点
- previousSibling: 表示当前节点的上一个同胞节点
- nextSibling: 表示当前节点的下一个同胞节点
- firstChild: 表示第一个子结点
- lastChild: 表示最后一个子结点
- normalize:用来合并该节点 childNodes 中的文本节点,正常来说每个元素下只有一个文本节点
方法:
- hasChildNodes: 返回一个布尔值,判断是否有子结点。
- appendChild:将一个节点插入该节点的最后一个子结点中,如果插入的节点已存在,则会改变其位置。
- insertBefore: 接收两个参数,一个要插入的节点,一个参照节点,将插入节点变为参照节点的前一个同胞节点。
- replaceChild: 接收两个参数,要插入的节点和要替换的节点
- removeChild: 接收一个参数,要移除的节点
- cloneNode: 参数为一个布尔值,true 表示克隆该节点的整个节点树,false表示只隆该节点,包含子结点
2. Document 类型
该节点是HTMLDocument的实例,是一个操作dom的全局对象
属性:
- title: 表示 title 标签中的文本
- URL:当前页面的完整路径
- domain:当前页面的域名
- referrer:表示跳转到当前页面的页面路径
方法:
- getElementById: 参数为一个节点id属性值,获取该节点
- getElementsByTagName: 参数为一个标签名,返回包含零个或多个元素的NodeList,是一个
HTMLCollection类数组类型,可通过[0]或者['name'属性值]的方式查找节点。
注意:HTMLCollection 是实时变化的,而NodeList是固定不变的。 - getElementsByName: 参数为一个 name 属性值,其他用法同 getElementsByTagName 一样。
- createElement: 参数为标签名,创建一个元素节点
- createTextNode: 创建一个文本节点
特殊集合:
- anchors: 包含文档中所有带 name 的 a 标签元素
- forms:返回文档中所有 form 标签元素
- images: 返回所有 img 标签元素
- links: 返回文档中所有带有href属性的 a 标签元素
注意: 返回的集合都是HTMLCollection 的实例
HTMLCollection 和 NodeList 区别:
HTMLCollection 集合中的节点会实时更新,而NodeList中的不会
let navsHTML = document.getElementsByTagName('nav')
let navsNode = document.querySelectorAll('nav')
console.log(navsHTML,navsNode)
document.body.removeChild(document.getElementById('nav'));
console.log(navsHTML,navsNode)
打印结果:
HTMLCollection(3) [nav#nav.nav, nav#nav.nav, nav#nav.nav, nav: nav#nav.nav]
NodeList(3) [nav#nav.nav, nav#nav.nav, nav#nav.nav]
HTMLCollection(2) [nav#nav.nav, nav#nav.nav, nav: nav#nav.nav]
NodeList(3) [nav#nav.nav, nav#nav.nav, nav#nav.nav]
3. Element 类型
Element表示HTML元素
属性:
- tagName: 返回一个大写的标签名
- nodeName: 同tagName 一样
- className: 返回 class 的属性值
- style: 用于更改 CSS 样式
- attributes: 返回当前元素上的所有属性名,以类数组的形式
方法
- getAttribute: 返回标签上的属性值
- setAttribute: 两个参数,一个是属性名,一个是要设置的属性值,会覆盖原来的属性值
- removeAttribute: 参数为要删除的属性名
4. Text类型
创建:document.createTextNode()
该类型为文本节点,每个元素下只能添加一个文本节点
方法:
- appendData(text): 向节点末尾添加文本
- deleteData(offset, count): 从offset 处开始删除 count个字符
- insertData(offset, text): 在 offset 处插入 文本
- replaceData(offset, count, text): 替换从 offset 开始的count 个文本
- splitText(offset): 在 offset 处将文本拆分为两个节点
- substringData(offset, count): 提取从offset 开始的 count个文本
5. Comment 类型
创建`:document.createComment()
注释节点,该节点同文本节点一样,拥有相同的方法
6. DocumentFragment 类型
创建:document.createFragment()
该类型是唯一一个在标记中没有对应表示的类型,它是一个轻量级的文档,它来操作节点没有在完整文档中那样的消耗。
使用方法:
let fragment = document.createDocumentFragment();
for(let i = 0; i< 5; i++){
let div = document.createElement('div')
div.innerText = `我是第${i}个`
fragment.appendChild(div);
}
document.body.appendChild(fragment)
三. MutationObserver 接口
可以在DOM被修改时执行异步执行回调,此时的异步是微任务,使用该接口可以观察整个文档,DOM树的一部分,或某个元素。此外还可以观察元素属性,字节点,文本。
1. observer 用法
observer 具体的可观察属性配置
配置其观察 body 标签上的属性变化,而其后代属性修改不会触发
let observer = new MutationObserver(()=>{
console.log('body 被修改了')
})
observer.observe(document.body, {attributes: true});
document.body.className = 'body'; // 执行回调
2. 回调参数 MutationRecord
每一个回调都会接收一个MutationRecord 实例的数组,用来记录发生了什么变化,以及dom那一部分受到影响
3. disconnect 方法
该方法是MutationObserver 实例的方法,用来终止回调的执行,极时已经将回调添加到任务队列,也不会执行。
let observer = new MutationObserver((Record, Observer)=>{
console.log('body 被修改了')
})
observer.observe(document.body, {attributes: true});
document.body.className = 'body'; // 回调不会被执行
observer.disconnect();
4. takeRecords 方法
用于清空记录队列,并且返回其中的所有MutationRecord实例
5. 性能与垃圾回收
性能: 回调事件是委托给微任务来执行的。
垃圾回收:
- MutationObserver 拥有对目标节点的弱引用,由于是弱引用不会妨碍垃圾回收程序回收目标节点。
- 目标节点拥有对 MutationObserver 的强引用。如果目标节点从dom中删除,则关联的MutationObserver 也会被回收。
四. DOM 扩展
1. Selectors API
- document.querySelector: 参数为一个css选择符,返回匹配的第一个元素
- document.querySelectorAll: 参数同上一样,但是会返回所有匹配的节点,返回的是一个 NodeList 静态实例,不会实时更新。
2. matches()
用来检测某个元素会不会被Selectors API 返回
console.log(document.body.matches('body')) // true
3. classList 属性
该属性返回的是一个类数组的class属性值,可以方便的实现对class值的增删
<nav id="nav" class="nav hah">我是导航</nav>
console.log(document.getElementById('nav').classList)// DOMTokenList(2) ['nav', 'hah', value: 'nav hah']
- add(value): 向类名列表中添加指定的字符串值value
- contains(value): 返回布尔值,表示给定的value是否存在
- remove(value):从类名列表中删除指定的字符串值
- toggle(value):如果类名列表中已经存在指定value 则删除,如果不存在,则添加
4. readyState 属性
- loading: 表示文档正在加载
- complete: 表示文档加载成功, 同 onload 事件用法相同
5. 自定义数据属性
方便的获取节点上的自定义属性值
<nav id="nav" class="nav" data-src="优快云.com" data-infoId="石头山">我是导航</nav>
console.log(document.getElementById('nav').dataset)
// DOMStringMap {src: '优快云.com', infoid: '石头山'}
6. children 属性
该节点返回的是只包含Element类型的子结点
7. contains 方法
用于判断目标节点是不是搜素节点的后代,返回一个布尔值
console.log(document.body.contains(document.getElementById('nav')))// true
五. DOM2 和 DOM3
1. Document 的变化
- createElementsNS(namespaceURI, tagName): 以给定的标签名 tagName 创建指定的命名空间的一个新元素
- getElementsByTagNameNS(namespaceURI, tagName): 返回 指定命名空间namespaceURI 中所有的 tagName 标签
2. 样式
为每一个元素添加了一个style 属性,用于使用JS更改元素样式。
- cssText: 包含style 属性中的CSS代码
- parentRule: 表示CSS信息的CSSRule 对象
六. 遍历
1. NodeIterator
创建: document.createNodeIterator(),该方法接收四个参数
- root: 作为遍历的根节点
- whatToShow: 表示应该访问哪些节点
- filter: 表示是否接收或跳过指定节点
- entityReferenceExpansion: 布尔值,表示是否扩展实体

1227

被折叠的 条评论
为什么被折叠?



