在这之前 DOM3 提供了 Mutation events 事件
- DOMAttrModified
- DOMAttributeNameChanged
- DOMCharacterDataModified
- DOMElementNameChanged
- DOMNodeInserted
- DOMNodeInsertedIntoDocument
- DOMNodeRemoved
- DOMNodeRemovedFromDocument
- DOMSubtreeModified
可以监听到属性、文本内容、节点插入删除、子节点变化等事件。可是该事件 W3C 已废弃,虽然一些浏览器仍然支持,但不建议使用。
MutationObserver目前IE11+及其它浏览器最新版本都已支持。可以通过以下代码判断是否支持
var MutationObserver = window.MutationObserver ||window.WebKitMutationObserver ||window.MozMutationObserver;var supportMutationObserver = !!MutationObserver;
使用如下
var mo = new MutationObserver(callback); var div = document.querySelector('div');var options = {'childList': true,'arrtibutes': true };mo.observer(div, options);
options 是配置参数,这里的配置可以观察到 div 元素的子元素和属于变动。
options 有如下选项
- childList: 子元素的变动
- attributes: 属性的变动
- characterData: 节点内容或节点文本的变动
- subtree: 所有下属节点(包括子节点和子节点的子节点)的变动
- attributeOldValueL: 值为true或者为false。如果为true,则表示需要记录变动前的属性值
- characterDataOldValue: 值为true或者为false。如果为true,则表示需要记录变动前的数据值
- attributesFilter: 值为一个数组,表示需要观察的特定属性(比如['class', 'str'])
当变动发生时回调函数会将变动记录 MutationRecord 对象传入,MutationRecord 包含了 DOM 的相关信息,有如下属性
- type: 观察的变动类型(attribute、characterData或者childList)
- target: 发生变动的DOM对象
- addedNodes: 新增的DOM对象
- removeNodes: 删除的DOM对象
- previousSibling: 前一个同级的DOM对象,如果没有则返回null
- nextSibling: 下一个同级的DOM对象,如果没有就返回null
- attributeName: 发生变动的属性。如果设置了attributeFilter,则只返回预先指定的属性
- oldValue: 变动前的值。这个属性只对attribute和characterData变动有效,如果发生childList变动,则返回null
示例1:观察子元素的变动
function callback(records) {records.forEach(function(record) {console.log(record)}) } var ob = new MutationObserver(callback) ob.observe(app1, {childList: true,subtree: true })
p1
app1
配置项 childList 表示观察子元素,subtree 表示观察子元素的下级元素。在本页面的浏览器控制台输入以下代码分别测试
app1.removeChild(p1)
app1.appendChild(document.createTextNode('TEST'))
示例2:观察属性的变化
function callback2(records) {records.forEach(function(record) {console.log(record)}) } var ob2 = new MutationObserver(callback2) ob2.observe(app2, {attribute: true,attributeOldValue: true })
app2
配置参数跟踪属性变动('attributes': true),然后设定记录变动前的值。实际发生变动时,会将变动前的值显示在控制台。打开本页面的浏览器控制台,输入以下代码测试
app2.id = 'apptest'
http://www.developcls.com/qa/9c4fa5aaa81b4b288fbfe9142a52f0b1.html
示例3:观察文本元素的变化
function callback3(records) {records.forEach(function(record) {console.log(record)}) } var ob3 = new MutationObserver(callback3) ob3.observe(app3, {characterData: true })
示例3:观察元素内容的变动
function callback3(records) {records.forEach(function(record) {console.log(record)}) } var ob3 = new MutationObserver(callback3) ob3.observe(app3, {childList: true,characterData: true,characterDataOldValue: true })
old value
配置项会观察元素文本的变化,当变动时会记录老的文本元素。打开本页面的浏览器控制台,输入以下代码测试
app3.appendChild(document.createTextNode(' hello'))
相关:
MutationObserver - Web API 接口参考 | MDN
Dev.Opera — Getting to Know Mutation Observers
http://michalbe.blogspot.com/2013/04/javascript-less-known-parts-dom.html