下面是一次涉及命名空间的类似变化:
let observer = new MutationObserver(
(mutationRecords) => console.log(mutationRecords));
observer.observe(document.body, { attributes: true });
document.body.setAttributeNS('baz', 'foo', 'bar');
// [ // {
// addedNodes: NodeList [],
// attributeName: "foo",
// attributeNamespace: "baz",
// nextSibling: null,
// oldValue: null,
// previousSibling: null
// removedNodes: NodeList [],
// target: body
// type: "attributes"
// }
// ]
连续修改会生成多个 MutationRecord 实例,下次回调执行时就会收到包含所有这些实例的数组, 顺序为变化事件发生的顺序:
let observer = new MutationObserver(
(mutationRecords) => console.log(mutationRecords));
observer.observe(document.body, { attributes: true });
document.body.className = 'foo';
document.body.className = 'bar';
document.body.className = 'baz';
// [MutationRecord, MutationRecord, MutationRecord]
下表列出了 MutationRecord 实例的属性。
属性 说明
target type oldValue
被修改影响的目标节点 字符串,表示变化的类型:“attributes”、“characterData"或"childList”
如果在 MutationObserverInit 对象中启用(attributeOldValue 或 characterData OldValue 为 true),"attributes"或"characterData"的变化事件会设置这个属性为被替代的值
"childList"类型的变化始终将这个属性设置为 null
let observer = new MutationObserver(() => console.log('<body> attributes changed')); observer.observe(document.body, { attributes: true });
document.body.className = 'foo'; 11 observer.disconnect();
attributeName
attributeNamespace
addedNodes
removedNodes
previousSibling
nextSibling
对于"attributes"类型的变化,这里保存被修改属性的名字 其他变化事件会将这个属性设置为 null 对于使用了命名空间的"attributes"类型的变化,这里保存被修改属性的名字 其他变化事件会将这个属性设置为 null 对于"childList"类型的变化,返回包含变化中添加节点的 NodeList 默认为空 NodeList 对于"childList"类型的变化,返回包含变化中删除节点的 NodeList 默认为空 NodeList 对于"childList"类型的变化,返回变化节点的前一个同胞 Node
默认为 null 对于"childList"类型的变化,返回变化节点的后一个同胞 Node 默认为 null
传给回调函数的第二个参数是观察变化的 MutationObserver 的实例,演示如下:
let observer = new MutationObserver(
(mutationRecords, mutationObserver) => console.log(mutationRecords,
mutationObserver));
observer.observe(document.body, { attributes: true }); document.body.className = 'foo';
// [MutationRecord], MutationObserver
3. disconnect()方法
默认情况下,只要被观察的元素不被垃圾回收,MutationObserver 的回调就会响应 DOM 变化事 件,从而被执行。要提前终止执行回调,可以调用 disconnect()方法。下面的例子演示了同步调用 disconnect()之后,不仅会停止此后变化事件的回调,也会抛弃已经加入任务队列要异步执行的回调: 10
let observer = new MutationObserver(() => console.log('<body> attributes changed')); observer.observe(document.body, { attributes: true });
document.body.className = 'bar';
//(没有日志输出)
要想让已经加入任务队列的回调执行,可以使用 setTimeout()让已经入列的回调执行完毕再调用 disconnect():
document.body.className = 'foo';
setTimeout(() => {
observer.disconnect();
document.body.className = 'bar';
}, 0);
// <body> attributes changed