Skip to content

👓 MutationObserver

📗 概述

MutationObserverDOM3 Events规范中的一部分,它提供了监视DOM树变化并及时作出响应的能力。通过使用MutationObserver,开发人员可以监听DOM节点的变化,并执行自定义的回调函数

🔬 工作模型

​ 每个MutationObserver实例都有一个与之对应的通知队列,当实例观察的目标DOM节点发生变化时,回调函数并不会同步执行,而是会将目标节点的变化包装成一个对象放入通知队列。

​ 需注意的是,一个MutationObserver实例也对应一个回调函数(开发者自定义),且其是一个微任务,它会在本轮次事件循环中目标节点第一次变化时被放入微队列,并在下轮事件循环中被执行。

工作模型1

​ 回调函数执行时,MutationObserver实例对应的队列会作为该回调函数的实参传入,且队列会转化成JS中的数组类型。

工作模型2

tip: MutationObserver实例观察的是DOM树,是语言层面上的变化,可以理解为JS中DOM对象的变化,而不是浏览器渲染图形层面上的变化。

🏃‍♂️ 创建实例

​ 一个MutationObserver实例负责监听一个DOM节点的变化,实例化时需要传入一个类型为MutationCallback的参数,这个参数便是实例监听执行的回调函数。有关MutationCallBack回调函数的具体内容,以下会单独讲述。

MutationObserver

🧭 实例API

observe

​ observe方法需传入一个目标节点和一个观察配置。在调用该方法后,实例将会开始观察目标节点。这意味着,实例开始接收节点变化通知。若节点发生变化,则回调函数便会被执行,这个过程会受到类型为MutationObserverInit的观察配置的影响。有关观察配置的具体内容,以下也会单独讲述。

observe()

disconnect

​ 调用实例的disconnect方法后,其会停止接收更改通知。这意味着,它将停止观察目标节点的任何更改,即使目标节点发生了任何变化,回调也不会被执行,直到再次调用其observer方法。

disconnect()

takeRecords

​ 调用实例的takeRecords方法后,其对应的通知队列中的所有待处理通知都会被删除,并将它们返回至一个新的数组对象中。

takeRecords()

⏰ 回调函数

​ 目标节点发生变化,则在下一轮事件循环中,回调函数便会被执行。回调执行时,会传入两个参数。第一个参数是DOM变化对象数组,有关DOM变化对象的具体内容会在下面进行讲述。第二个参数是当前MutationObserver实例

MutationCallback

tip: mutations数组中只存储了上一轮事件循环中目标节点发生的变化。

🌱 变化对象

​ 每个 MutationRecord 变化对象都代表一个独立的 DOM 变化,其有以下常用属性。

属性名类型描述
typestring若为属性节点变化,则值为attributes
若为文本节点和注释节点字符变化,则值为characterData
若为添加或删除子节点,则值为childList
targetNode发生变化的节点
addedNodesNodeList返回被添加的节点,若没有节点被添加,则值为空的NodeList
removedNodesNodeList返回被删除的节点,若没有节点被删除,则值为空的NodeList
attributeNamestring返回被修改的属性的属性名,或者为 null
attributeNamespacestring返回被修改的属性的命名空间,或者为 null
oldValuestring若为属性attributes变化,则返回变化之前的属性;
若为characterData变化,则返回变化之前的数据;
若为子节点树childList变化,则返回null

MutationRecord

📢 监听配置

MutationObserverInit实例用于配置MutationObserver实例监听的初始化对象,它定义了要观察的 DOM 变化类型和其他选项。MutationObserverInit有以下可配置的属性。

属性名默认值描述
attributesfalse当为true时,将会监听目标节点属性值的变化
characterData false当为true时,将会监听文本节点或注释节点上的字符变化
childListfalse当为true时,将会监听目标节点的子节点添加和删除
attributeFilter/用于声明哪些属性名会被监听的数组。若不声明,则全部监听
attributeOldValuefalse当为true时,记录目标节点属性变化前的旧值
characterDataOldValuefalse当为true时,记录目标节点文本变化前的旧值
subtreefalse当为true时,目标节点范围扩大至以参数target节点为根节点的子树中的所有节点

MutationObserverInit

tip:

  1. 调用MutationObserver实例的observe()方法时,需配置MutationObserverInit实例的attributeOldValue属性或characterDataOldValue属性为true,后续MutationRecord实例的oldValue属性才会有值。
  2. ⭐️⭐️⭐️characterData true时,使用targetElement.innerText='FatGod'这种方式修改文本值并不能被成功监听,因为这种方式的本质是将元素的原文本节点删除,插入新的文本节点,所以该过程能够监听到目标节点的childList类型变化。characterData类型的变化监听只适用于节点类型为文本或者注释的节点。若需更改文本节点或注释节点的字符可以使用characterDataNode.nodeValue = 'FatGod'该种方式,nodeValueNode接口中的属性。

上次更新于: