乐趣区

关于javascript:Mutation-events和MutationObserver-监听DOM变化

Mutation events

Mutation events 是在 DOM3 中定义,用于监听 DOM 树结构变动的事件
它简略的用法如下:

document.getElementById('list').addEventListener("DOMSubtreeModified", function(){console.log('列表中子元素被批改');
}, false);

Mutation 事件列表

1. DOMAttrModified: 察看指标节点的属性节点(新增或删除了某个属性, 以及某个属性的属性值产生了变动)。2. DOMAttributeNameChanged
3. DOMCharacterDataModified: 如果指标节点为 characterData 节点 (一种形象接口, 具体能够为文本节点, 正文节点, 以及解决指令节点) 时, 也要察看该节点的文本内容是否发生变化
4. DOMElementNameChanged
5. DOMNodeInserted: 在指标节点作为子节点被插入到另一个节点中时触发。6. DOMNodeRemoved:在指标节点从其父节点中被移除时触发。7. DOMNodeInsertedIntoDocument: 在一个节点被直接插入文档或通过子树间接插入到文档之后触发。这个事件在 DOMNodeInserted 之后触发。8. DOMSubtreeModified: 在指标 DOM 构造中产生任何变动时触发;

Mutation Events 遇到的问题
浏览器兼容性问题
IE9 不反对 Mutation Events
Webkit 内核不反对 DOMAttrModified 个性,
DOMElementNameChanged 和 DOMAttributeNameChanged 在 Firefox 上不被反对。
性能问题
1.Mutation Events 是 同步执行 的,它的每次调用,都须要从事件队列中取出事件,执行,而后事件队列中移除,期间须要挪动队列元素。如果事件触发的较为频繁的话,每一次都须要执行下面的这些步骤,那么浏览器会被拖慢。
2.Mutation Events 自身是事件且能够冒泡,所以捕捉是采纳的是事件冒泡的模式,如果冒泡捕捉期间又触发了其余的 MutationEvents 的话,很有可能就会导致阻塞 Javascript 线程,甚至导致浏览器解体。

MutationObserver

Mutation Observer 是在 DOM4 中定义的,用于代替 mutation events 的新 API,它的不同于 events 的是,所有监听操作以及相应解决都是在其余脚本执行实现之后异步执行的,并且是所以变动触发之后,将变得记录在数组中,对立进行回调的,也就是说,当你应用 observer 监听多个 DOM 变动时,并且这若干个 DOM 产生了变动,那么 observer 会将变动记录到变动数组中,期待一起都完结了,而后一次性的从变动数组中执行其对应的回调函数。

Mutation Observer 的浏览器兼容范畴

构造函数

用来实例化一个 Mutation 观察者对象,其中的参数是一个回调函数,它是会在指定的 DOM 节点发送变动后,执行的函数,并且会被传入两个参数,一个是变动记录数组(MutationRecord),另一个是观察者对象自身

const mutationObserver = new MutationObserver(function(records, itself){});

observe

在观察者对象上,注册须要察看的 DOM 节点,以及相应的参数

mutationObserver.observe(Node target, optional MutationObserverInit options)

其中的可选参数 MutationObserverInit 的属性如下:

childLIst 察看指标节点的子节点的新增和删除。attributes 察看指标节点的属性节点(新增或删除了某个属性, 以及某个属性的属性值产生了变动)。characterData 如果指标节点为 characterData 节点 (一种形象接口, 具体能够为文本节点, 正文节点, 以及解决指令节点) 时, 也要察看该节点的文本内容是否发生变化
subtree 察看指标节点的所有后辈节点(察看指标节点所蕴含的整棵 DOM 树上的上述三种节点变动)
attributeOldValue 在 attributes 属性曾经设为 true 的前提下, 将发生变化的属性节点之前的属性值记录下来(记录到上面 MutationRecord 对象的 oldValue 属性中)
characterDataOldValue 在 characterData 属性曾经设为 true 的前提下, 将发生变化 characterData 节点之前的文本内容记录下来(记录到上面 MutationRecord 对象的 oldValue 属性中)
attributeFilter 一个属性名数组(不须要指定命名空间), 只有该数组中蕴含的属性名发生变化时才会被察看到, 其余名称的属性发生变化后会被疏忽想要设置那些删选参数的话,如果想要应用哪个参数的话,就将其值设定为 true

disconnect

暂定在观察者对象上设置的节点的变动监听,直到从新调用 observe 办法

takeRecords

MutationObserver 的 takeRecords() 办法返回已检测到但尚未由观察者的回调函数解决 (因为 MutationObserver 解决回调是异步的) 的所有匹配 DOM 更改的列表,使变更队列放弃为空。此办法最常见的应用场景是在断开观察者之前立刻获取所有未解决的更改记录,以便在进行观察者时能够解决任何未解决的更改。

var targetNode = document.querySelector("#someElement");
var observerOptions = {
  childList: true,
  attributes: true
}

var observer = new MutationObserver(callback);
observer.observe(targetNode, observerOptions);


var mutations = observer.takeRecords();

if (mutations) {callback(mutations);
}

observer.disconnect();

MutationRecord

其蕴含的属性如下

1. type 如果是属性发生变化, 则返回 attributes. 如果是一个 CharacterData 节点发生变化, 则返回 characterData, 如果是指标节点的某个子节点产生了变动, 则返回 childList.
2. target 返回此次变动影响到的节点, 具体返回那种节点类型是依据 type 值的不同而不同的, 如果 type 为 attributes, 则返回发生变化的属性节点所在的元素节点, 如果 type 值为 characterData, 则返回发生变化的这个 characterData 节点. 如果 type 为 childList, 则返回发生变化的子节点的父节点.
3. addedNodes 返回被增加的节点
4. removedNodes 返回被删除的节点
5. previousSibling 返回被增加或被删除的节点的前一个兄弟节点
6. nextSibling 返回被增加或被删除的节点的后一个兄弟节点
7. attributeName 返回变更属性的本地名称
8. oldValue 依据 type 值的不同, 返回的值也会不同. 如果 type 为 attributes, 则返回该属性变动之前的属性值. 如果 type 为 characterData, 则返回该节点变动之前的文本数据. 如果 type 为 childList, 则返回 null

应用实例

// Firefox 和 Chrome 晚期版本中带有前缀
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
// 抉择指标节点
var target = document.querySelector('#some-id'); 
// 创立观察者对象
var observer = new MutationObserver(function(mutations) {mutations.forEach(function(mutation) {console.log(mutation.type); 
  }); 
}); 
// 配置察看选项:
var config = {attributes: true, childList: true, characterData: true} 
// 传入指标节点和察看选项
observer.observe(target, config); 
// 随后, 你还能够进行察看
observer.disconnect();
退出移动版