MutationObserver 监听DOM树变化

1 概述

Mutation observer 是用于代替 Mutation events 做为观察DOM树结构发生变化时,作出相应处理的API。为何要使用mutation observer 去代替 mutation events 呢,咱们先了解一下mutation eventsjavascript

Mutation Events

Mutation events 是在 DOM3中定义,用于监听DOM树结构变化的事件java

它简单的用法以下:数组

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

Mutation 事件列表浏览器

  • DOMAttrModified
  • DOMAttributeNameChanged
  • DOMCharacterDataModified
  • DOMElementNameChanged
  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMNodeInsertedIntoDocument
  • DOMSubtreeModified

其中DOMNodeRemoved,DOMNodeInserted 和 DOMSubtreeModified 分别用于 监听元素子项的删除,新增,修改(包括删除和新增),
DOMAttrModified 是监听元素属性的修改,而且可以提供具体的修改动做。异步

Mutation Events遇到的问题
  • 浏览器兼容性问题
    IE9不支持Mutation Events
    Webkit内核不支持DOMAttrModified特性,
    DOMElementNameChanged和DOMAttributeNameChanged 在Firefox上不被支持。
  • 性能问题
    1.Mutation Events是同步执行的,它的每次调用,都须要从事件队列中取出事件,执行,而后事件队列中移除,期间须要移动队列元素。若是事件触发的较为频繁的话,每一次都须要执行上面的这些步骤,那么浏览器会被拖慢。
    2.Mutation Events自己是事件,因此捕获是采用的是事件冒泡的形式,若是冒泡捕获期间又触发了其余的MutationEvents的话,颇有可能就会致使阻塞Javascript线程,甚至致使浏览器崩溃。

Mutation Observer

Mutation Observer 是在DOM4中定义的,用于替代 mutation events 的新API,它的不一样于events的是,全部监听操做以及相应处理都是在其余脚本执行完成以后异步执行的,而且是因此变更触发以后,将变得记录在数组中,统一进行回调的,也就是说,当你使用observer监听多个DOM变化时,而且这若干个DOM发生了变化,那么observer会将变化记录到变化数组中,等待一块儿都结束了,而后一次性的从变化数组中执行其对应的回调函数。函数

Mutation Observer 的浏览器兼容范围性能


兼容性

2 方法

构造函数

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

new MutationObserver(function(records, itself){});
observe

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

void 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

在观察者对象上调用takeRecords 会返回 其观察节点上的变化记录(MutationRecord)数组
其中MutationRecord数组也会做为,观察者初始化时的回调函数的第一个参数
其包含的属性以下:

type 若是是属性发生变化,则返回attributes.若是是一个CharacterData节点发生变化,则返回characterData,若是是目标节点的某个子节点发生了变化,则返回childList.
target 返回这次变化影响到的节点,具体返回那种节点类型是根据type值的不一样而不一样的,若是type为attributes,则返回发生变化的属性节点所在的元素节点,若是type值为characterData,则返回发生变化的这个characterData节点.若是type为childList,则返回发生变化的子节点的父节点.
addedNodes 返回被添加的节点
removedNodes 返回被删除的节点
previousSibling 返回被添加或被删除的节点的前一个兄弟节点
nextSibling 返回被添加或被删除的节点的后一个兄弟节点
attributeName 返回变动属性的本地名称
oldValue 根据type值的不一样,返回的值也会不一样.若是type为attributes,则返回该属性变化以前的属性值.若是type为characterData,则返回该节点变化以前的文本数据.若是type为childList,则返回null

3 使用实例

// 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();

4 参考连接

[1].MDN Mutation Observer
[2].将突变事件和属性更改事件迁移到突变观察者



文/falm(简书做者) 原文连接:http://www.jianshu.com/p/b5c9e4c7b1e1 著做权归做者全部,转载请联系做者得到受权,并标注“简书做者”。
相关文章
相关标签/搜索