js 原生dom 操作

一. 首先要了解什么是 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. 性能与垃圾回收

性能: 回调事件是委托给微任务来执行的。
垃圾回收:

  1. MutationObserver 拥有对目标节点的弱引用,由于是弱引用不会妨碍垃圾回收程序回收目标节点。
  2. 目标节点拥有对 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: 布尔值,表示是否扩展实体
2. TreeWalker
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员-石头山

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

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

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

打赏作者

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

抵扣说明:

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

余额充值