MutationObserver
MutationObserver 观察器可以观察目标节点的子节点、属性和文本内容等变化。具体来说,它能够观察以下三种类型的变化:
childList:指目标节点的子节点发生变化,例如新增或删除一个子元素。attributes:指目标节点的属性发生变化,例如修改一个属性的值。characterData:指目标节点或其子节点的文本内容发生变化,例如修改了一个文本节点的内容。
除了上述三种基本类型之外,MutationObserver 还提供了一些其他的配置选项,以便更精细地控制观察器的行为。这些选项包括:
subtree:表示是否观察目标节点的后代节点中任意一个节点的变化(默认为 false)。attributeOldValue:如果设置为 true,则在属性变化时记录之前的属性值(默认为 false)。characterDataOldValue:如果设置为 true,则在字符数据变化时记录之前的值(默认为 false)。attributeFilter:一个数组,其中每个元素都是要观察的属性名。为空数组则表示观察所有属性的变化。
我们可以根据具体需求选择相应的配置选项,并在回调函数中处理相应的业务逻辑。需要注意的是,不同类型的变化会触发不同类型的 MutationRecord 对象,而在回调函数中我们可以获取到这些对象,并通过它们的属性来判断变化的具体类型和内容。
示例代码
例1:监听元素属性变化
// 需要被监听的元素
const targetNode = document.getElementById('target');
// 创建一个 MutationObserver 对象
const observer = new MutationObserver(function(mutationsList, observer) {
// 迭代所有的变更记录
for (let mutation of mutationsList) {
if (mutation.type === 'attributes') {
console.log(`属性 ${mutation.attributeName} 的值发生了变化`);
}
}
});
// 开始观察目标节点
observer.observe(targetNode, { attributes: true });
例2:监听元素子节点的变化
// 需要被监听的元素
const targetNode = document.getElementById('target');
// 创建一个 MutationObserver 对象
const observer = new MutationObserver(function(mutationsList, observer) {
// 迭代所有的变更记录
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
console.log(`元素的子节点发生了变化`);
}
}
});
// 开始观察目标节点
observer.observe(targetNode, { childList: true });
例3:监听元素子节点及属性的变化
// 需要被监听的元素
const targetNode = document.getElementById('target');
// 创建一个 MutationObserver 对象
const observer = new MutationObserver(function(mutationsList, observer) {
// 迭代所有的变更记录
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
console.log(`元素的子节点发生了变化`);
} else if (mutation.type === 'attributes') {
console.log(`属性 ${mutation.attributeName} 的值发生了变化`);
}
}
});
// 开始观察目标节点
observer.observe(targetNode, { childList: true, attributes: true });
例4:监听指定属性的变化
// 需要被监听的元素
const targetNode = document.getElementById('target');
// 创建一个 MutationObserver 对象
const observer = new MutationObserver(function(mutationsList, observer) {
// 迭代所有的变更记录
for (let mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-name') {
console.log(`属性 data-name 的值发生了变化,新值为 ${mutation.target.getAttribute('data-name')}`);
}
}
});
// 开始观察目标节点
observer.observe(targetNode, { attributes: true, attributeFilter: ['data-name'] });
例5:监听所有 DOM 变化
// 需要被监听的元素
const targetNode = document.documentElement;
// 创建一个 MutationObserver 对象
const observer = new MutationObserver(function(mutationsList, observer) {
// 迭代所有的变更记录
for (let mutation of mutationsList) {
console.log(`发生了 ${mutation.type} 类型的变化`);
}
});
// 开始观察目标节点
observer.observe(targetNode, { childList: true, attributes: true, subtree: true });