MutationObserverInit对象
MutationObserverInit对象用于控制对目标节点的观察范围。粗略的讲观察者可以观察的事件包括属性变化、文本变化和子节点变化。
MutationObserverInit对象属性:
| subtree |
布尔值,表示除了目标节点,是否观察目标节点的子树(后代) 如果是false,则只观察目标节点的变化;如果是true,则观察目标节点及其整个子树 默认为false |
| attributes | 布尔值,表示是否观察目标节点的属性变化 |
| attributeFilter | 字符串数组,表示要观察哪些属性的变化 |
| attributeOldValue |
布尔值,表示 MutationRecord是否记录变化之前的属性值 把这个值设置为true也会将attributes的值转换为true 默认为false |
| characterData |
布尔值,表示修改字符数据是否触发变化事件 默认为false |
| characterDataOldvalue |
布尔值,表示 MutationRecord是否记录变化之前的字符数据 把这个值设置为true也会将 characterData的值转换为true 默认为false |
| childList |
布尔值,表示修改目标节点的子节点是否触发变化事件 默认为false |
注:在调用observer()时,MutationObserverInit对象中的attributes、characterData和childList属性必须至少有一项为true(无论是直接<br>设置这几个属性,还是通过设置attributeOldValue等属性间接导致它们的值转换为true)。否则会抛出错误,因为没有任何变化事件可能触发回调
1、观察属性
MutationObserver可以观察节点属性的添加、移除和修改。要为属性变化注册回调,需要在 MutationObserverInit对象中将attributes属性设置为true
例:
let mutationAttr1 = new MutationObserver((MutationRecords)=>console.log(MutationRecords));
mutationAttr1.observe(document.body,{attributes:true});
// 添加属性
document.body.setAttribute('foo','bar');
// 修改属性
document.body.setAttribute('foo','baz');
// 删除属性
document.body.removeAttribute('foo');
以上的变化都被记录下来了
// [MutationRecord, MutationRecord, MutationRecord]
把attributes设置为true的默认行为是观察所有属性,但不会在MutationRecord对象中记录原来的值。如果想观察某个或某几个属性,可以使用attributeFilter
属性来设置白名单,即一个属性明字符串数组
let mutationAttr2 = new MutationObserver((MutationRecords)=>console.log(MutationRecords));
mutationAttr2.observe(document.body,{attributeFilter:['foo']});
//添加白名单
document.body.setAttribute('foo','bar');
//添加被排除的属性
document.body.setAttribute('baz','qux');
//只有foo属性的变化被记录了
// [
// {
// addedNodes:NodeList[],
// attributeName:"foo",
// attributeNamespace:null,
// nextSibling:null
// oldValue:null
// previousSibling:null
// removedNodes:NodeList[]
// target:body
// type:"attributes"
// }
// ]
如果想在变化记录中保存属性原来的值可以将attributeOldValue属性设置为true
let mutationAttr3 = new MutationObserver((MutationRecords)=>console.log(MutationRecords.map((x)=>x.oldValue)) );
mutationAttr3.observe(document.body,{attributeOldValue:true});
document.body.setAttribute('foo','bar');
document.body.setAttribute('foo','baz');
document.body.setAttribute('foo','qux');
//[null, 'bar', 'baz']
2、观察字符数据
let mutationCharacterData1 = new MutationObserver((MutationRecords)=>console.log(MutationRecords));
//创建观察的文本节点
document.body.firstChild.textContent='foo';
mutationCharacterData1.observe(document.body.firstChild,{characterData:true});
//赋值为相同的字符串
document.body.firstChild.textContent='foo';
//赋值为新字符串
document.body.firstChild.textContent='bar';
//通过节点设置函数赋值
document.body.firstChild.textContent='baz';
//以上变化都被记录下来了
//[MutationRecord,MutationRecord,MutationRecord]
将characterData属性设置为true的默认行为不会在MutationRecord对象中记录原来的字符数据。如果想在变化记录中保存原来的字符数据可以将characterDataOldValue属性设置为true
let mutationCharacterData2 = new MutationObserver((MutationRecords)=>console.log(MutationRecords.map((x)=>x.oldValue)) );
//创建观察的文本节点
document.body.firstChild.textContent='foo';
mutationCharacterData2.observe(document.body.firstChild,{characterDataOldValue:true});
//赋值为相同的字符串
document.body.firstChild.textContent='foo';
//赋值为新字符串
document.body.firstChild.textContent='bar';
//通过节点设置函数赋值
document.body.firstChild.textContent='baz';
//每次变化都保留了上一次的值
//['foo', 'foo', 'bar']
3、观察子节点
MutationObserver可以观察目标节点子节点的添加和移除。要观査子节点,需要在MutationObserverInit对象中将childList属性设置为true
例:添加子节点
let mutationChildList1 = new MutationObserver((MutationRecords)=>console.log(MutationRecords));
mutationChildList1.observe(document.body,{childList:true});
let div = document.createElement('div');
document.body.appendChild(div);
// [
// {
// addedNodes:NodeList[div],
// attributeName:null,
// attributeNamespace:null,
// nextSibling:null
// oldValue:null
// previousSibling:null
// removedNodes:NodeList[]
// target:body
// type:"childList"
// }
// ]
例:移除子节点
在以上例子的基础上移除div
document.body.removeChild(div)
// [
// {
// addedNodes:NodeList[],
// attributeName:null,
// attributeNamespace:null,
// nextSibling:null
// oldValue:null
// previousSibling:null
// removedNodes:NodeList[div]
// target:body
// type:"childList"
// }
// ]
对子节点重新排序(尽管调用一个方法即可实现)会报告两次变化事件,因为从技术上会执行先移除再增加
let mutationChildList2 = new MutationObserver((MutationRecords)=>console.log(MutationRecords));
//创建两个初始子节点
document.body.appendChild(document.createElement('div'));
document.body.appendChild(document.createElement('span'));
mutationChildList2.observe(document.body,{childList:true});
//交换子节点顺序
document.body.insertBefore(document.body.lastChild,document.body.firstChild)
//第一次是节点被删除,第二次是节点被添加
// [
// {
// addedNodes:NodeList[],
// attributeName:null,
// attributeNamespace:null,
// nextSibling:null
// oldValue:null
// previousSibling:div
// removedNodes:NodeList[span]
// target:body
// type:"childList"
// }
// ]
// [
// {
// addedNodes:NodeList[span],
// attributeName:null,
// attributeNamespace:null,
// nextSibling:div
// oldValue:null
// previousSibling:null
// removedNodes:NodeList[]
// target:body
// type:"childList"
// }
// ]
4、观察子树
默认情况下,MutationObserver将观察的范围限定为一个元素及其子节点的变化。可以把观察的范围扩展到这个元素的子树(所有后代的节点),这需要在MutationObserverInit对象中subtree属性设置为true
例:观察元素及其后代节点属性的变化
let mutationObserver = new MutationObserver((MutationRecords)=>console.log(MutationRecords));
//创建一个后代
document.body.appendChild(document.createElement('div'));
//观察body元素及其子树
mutationObserver.observe(document.body,{attributes:true,subtree:true});
//修改body元素的子树
document.body.firstChild.setAttribute('foo','bar')
//[
// {
// addedNodes:NodeList[],
// attributeName:'foo',
// attributeNamespace:null,
// nextSibling:null
// oldValue:null
// previousSibling:null
// removedNodes:NodeList[]
// target:div
// type:"childList"
// }
// ]
takeRecords()方法
takeRecord()方法可以清空记录队列,取出并返回其中所有的MutationRecord实例
例:
let observer = new MutationObser=((mutationRecords)=>console.log(mutationRecords));
observer.observe(document.body, { attributes: true });
document.body.className='foo';
document.body.className='bar';
document.body.className='baz';
console.log(observer.takeRecord());
console.log(observer.takeRecord());
//[MutationRecord, MutationRecord, MutationRecord]
//[]
此方法在希望断开与观察目标的联系,但又希望处理由于调用disconnect()而抛弃的记录队列中的MutationRecord实例时比较实用
本文详细介绍了MutationObserver对象及其初始化参数MutationObserverInit,展示了如何利用这些参数观察DOM节点的属性、字符数据及子节点的变化,并提供了丰富的示例代码。
&spm=1001.2101.3001.5002&articleId=128188749&d=1&t=3&u=7ab419588b3f4cdea26b2715a1344f55)
2929

被折叠的 条评论
为什么被折叠?



