Mutation事件Mutation事件定义在DOM3中,用于监控DOM树结构的变化。它的简单用法如下:document.getElementById('list').addEventListener("DOMSubtreeModified",function(){console.log('列表中的子元素被修改');},false);Mutationeventlist1.DOMAttrModified:观察目标节点的属性节点(增加或删除一个属性,一个属性的属性值发生了变化)。2.DOMAttributeNameChanged3。DOMCharacterDataModified:如果目标节点是characterData节点(抽象接口,具体可以是文本节点、注释节点、处理指令节点),还需要观察节点的文本内容是否发生变化。4.DOMElementNameChanged5。DOMNodeInserted:当目标节点作为子节点插入到另一个节点时触发。6.DOMNodeRemoved:目标节点从其父节点移除时触发。7.DOMNodeInsertedIntoDocument:节点直接插入文档或通过子树间接插入文档后触发。此事件在DOMNodeInserted之后触发。8.DOMSubtreeModified:当目标DOM结构发生任何变化时触发;MutationEvents遇到的问题浏览器兼容性问题IE9不支持MutationEventsWebkit内核不支持DOMAttrModified特性,DOMElementNameChanged和DOMAttributeNameChanged在Firefox上不受支持。性能问题1.MutationEvents是同步执行的。每次调用时,都需要将事件从事件队列中取出,执行,然后从事件队列中移除。在此期间,需要移动队列元素。如果事件触发比较频繁,则每次都需要执行上述步骤,浏览器会变慢。2.MutationEvents本身就是事件,可以冒泡,所以捕获采用的是事件冒泡的形式。如果在冒泡捕获的过程中触发了其他的MutationEvents,很可能会阻塞Javascript线程,甚至导致浏览器崩溃。MutationObserverMutationObserver定义在DOM4中,用于替换新的变异事件API。与事件不同的是,所有的监听操作和相应的处理都是在其他脚本执行完之后异步执行的,触发变化后,会记录在数组中,统一进行回调,也就是当你使用observer监听多个DOM的变化,这几个DOM发生了变化,那么observer会把变化记录在change数组中,等待它们一起结束,然后一次性从change数组中执行相应的回调函数。MutationObserver浏览器兼容的作用域构造函数,用于实例化一个MutationObserver对象,其中参数为回调函数,是指定DOM节点发送变化后执行的函数,会传入两个参数,一个是变化记录数组(MutationRecord),一个是观察者对象本身constmutationObserver=newMutationObserver(function(records,itself){});observe在观察者对象上,注册需要观察的DOM节点,以及相应的参数mutationObserver.observe(Nodetarget,optionalMutationObserverInitoptions)可选参数MutationObserverInit的属性如下:childLIst观察增删改查目标节点的子节点。attributes观察目标节点的属性节点(增加或删除一个属性,改变一个属性的属性值)。characterData如果目标节点是characterData节点(抽象接口,具体可以是文本节点、注释节点、处理指令节点),还需要观察节点的文本内容是否发生变化subtree观察目标节点的所有后代节点(观察上面三个节点在目标节点包含的整个DOM树上的变化)attributeOldValue在attributes属性已经设置为true的前提下,记录变化的属性节点之前的属性值(记录到下面MutationRecord对象的oldValue属性中)characterDataOldValue在characterData属性已经设置为true的前提下,记录发生变化的characterData节点之前的文本内容(记录在下面MutationRecord对象的oldValue属性中)attributeFilter的数组attributenames(不需要指定命名空间),只有数组ch中包含的attributename才会被观察到anges,其他名称的属性在更改后将被忽略。如果要设置那些删除参数,如果要使用哪个参数,设置它的值为truedisconnect暂时中止观察者对象上设置的节点的变化监听,直到observe方法takeRecordsMutationObserver的takeRecords()方法返回所有检测到但还未检测到的由观察者的回调函数处理(因为MutationObserver处理回调是异步的)匹配DOM变化列表,使变化队列为空。此方法最常见的使用场景是在断开观察者之前立即获取所有未完成的更改记录,以便在停止观察者时可以处理任何未完成的更改。vartargetNode=document.querySelector("#someElement");varobserverOptions={childList:true,attributes:true}varobserver=newMutationObserver(callback);observer.observe(targetNode,observerOptions);var突变=observer.takeRecords();if(mutations){callback(mutations);}observer.disconnect();MutationRecord包含以下属性:1.type如果属性发生变化,则返回属性。如果一个CharacterData节点发生变化,则返回characterData,如果目标节点的一个子节点发生变化,则返回childList.2。target返回受此更改影响的节点,返回的节点类型取决于type的值。如果类型是属性,则返回改变的属性节点所在的元素节点。如果类型值为characterData,则返回更改后的characterData节点。如果类型是childList,则返回变化后的子节点的父节点。3.addedNodes返回添加的节点4.removedNodes返回删除的节点5.previousSibling返回添加或删除节点的前一个兄弟节点6.nextSibling返回添加或删除节点的下一个兄弟节点7.attributeName返回本地名称改变的属性8.oldValue根据类型值返回不同的值。如果类型是属性,则返回属性更改前的属性值。如果type为characterData,则返回节点变化前的文本数据。如果类型是childList,则返回null用例//Firefox和带有前缀的Chrome的早期版本varMutationObserver=window.MutationObserver||无线ndow.WebKitMutationObserver||window.MozMutationObserver//选择目标节点vartarget=document.querySelector('#some-id');//创建观察者对象varobserver=newMutationObserver(function(mutations){mutations.forEach(function(mutation){console.log(mutation.type);});});//配置观察选项:varconfig={attributes:true,childList:true,characterData:true}//传入目标节点和观察选项observer.observe(target,config);//后面也可以停止观察observer.disconnect();
