推荐答案
// www.javascriptcn.com code example
// 选择需要观察的元素
const targetNode = document.getElementById('targetElement');
// 配置观察选项 (哪些变化需要观察)
const config = {
attributes: true, // 监听属性变化
childList: true, // 监听子节点变化
subtree: true, // 监听后代节点变化
characterData: true, // 监听文本节点变化
};
// 创建一个观察器实例
const observer = new MutationObserver(function(mutationsList, observer) {
for(let mutation of mutationsList) {
if(mutation.type === 'childList') {
console.log('A child node has been added or removed.');
} else if (mutation.type === 'attributes') {
console.log(`The ${mutation.attributeName} attribute was modified.`);
} else if (mutation.type === 'characterData') {
console.log('A text content has changed.')
}
}
});
// 开始观察目标节点
observer.observe(targetNode, config);
// 如果不再需要观察,可以调用 disconnect() 方法停止观察
// observer.disconnect();本题详细解读
MutationObserver API 允许我们监听 DOM 树的更改。 它是一个异步 API,因此变化不会立即触发回调函数,而是批量处理,性能更高。
核心概念:
MutationObserver类: 创建一个观察器实例,接收一个回调函数作为参数。 这个回调函数会在监听的 DOM 发生变化时被调用。observe()方法: 启动观察,接收两个参数:targetNode: 需要观察的 DOM 元素。config: 一个对象,用于配置观察哪些类型的变化,比如:childList: 监听目标元素的直接子节点的变化(添加或删除)。attributes: 监听目标元素属性的变化。subtree: 监听目标元素及其后代节点的变化。characterData: 监听文本节点内容的变化。attributeOldValue: 记录属性变化前的旧值。characterDataOldValue: 记录文本节点变化前的旧值。
- 回调函数: 当被观察的 DOM 发生配置的变化时被调用,接收两个参数:
mutationsList: 一个包含MutationRecord对象的数组,每个对象描述了一个变化。observer: 指向MutationObserver实例本身。
MutationRecord对象: 描述 DOM 变化的对象,包括以下属性:type: 变化的类型 (childList,attributes, orcharacterData).target: 发生变化的节点。addedNodes:childList类型变化时添加的节点集合。removedNodes:childList类型变化时删除的节点集合。attributeName:attributes类型变化时变化的属性名。attributeNamespace:attributes类型变化时变化的属性的命名空间(如果没有则为null)。oldValue:attributes和characterData类型变化时,变化前的旧值 (需在config配置中开启attributeOldValue或characterDataOldValue)。previousSibling:childList类型变化时,添加/删除节点之前的同级节点。nextSibling:childList类型变化时,添加/删除节点之后的同级节点。
disconnect()方法: 停止观察。
示例详解:
- 我们首先使用
document.getElementById()选取一个 DOM 元素作为targetNode。 - 然后,创建一个
config对象来指定我们想要观察的变化类型。 - 接着,创建一个
MutationObserver实例,并在回调函数中处理各种类型的变化,打印日志。 - 使用
observer.observe(targetNode, config)开始观察。 - 最后,示例代码也注释了
observer.disconnect()方法,说明何时停止观察。
使用场景:
- 监听动态插入的元素,实现懒加载或无限滚动。
- 观察属性变化,比如监听图片加载完成。
- 响应用户交互导致的 DOM 更改。
- 创建自定义组件,响应内部 DOM 变化。
- 实现框架的响应式系统。