MutationObserver 通过构造函数创建并调用 observe() 监听 DOM 变化,支持 childList、attributes、characterData 等配置,需精准选择目标节点、合理编写回调、及时调用 disconnect() 防内存泄漏。直接用 `MutationObserver` 构造函数创建观察器,传入回调函数,再调用 `observe()` 指定目标节点和监听类型,就能高效捕获 DOM 变化。它不是事件,不实时触发,而是批量、异步处理,性能好且兼容主流浏览器(Chrome 26+、Firefox 14+、Safari 10+、Edge 11+)。
监听哪些变化?关键配置项要设对
只开启需要的类型,避免无效开销:
-
childList: true —— 监听子节点增删(比如
appendChild、removeChild) - subtree: true —— 必须加!否则只监听目标元素自身,深层动态插入的内容会漏掉
-
attributes: true —— 监听属性变化(如
class、data-id),配合attributeFilter可聚焦特定属性 -
characterData: true —— 监听文本内容变更(如
textContent = 'new'),注意目标需是文本节点或启用了subtree - attributeOldValue / characterDataOldValue: true —— 需要对比新旧值时才启用
监听谁?目标节点选得准才不干扰
别盲目监听 document 或 document.body:
- 监听
document可能捕获到中脚本/样式注入,引发误报 - 监听
document.body会混入页面 UI 元素(工具栏、弹窗等),日志杂乱 - 推荐监听具体容器,比如
document.getElementById('preview')或document.querySelector('#app') - 确保目标节点已挂载,可放在
DOMContentLoaded里初始化,或加空值判断
怎么写回调?批量处理 + 类型判断是重点
回调接收的是 MutationRecord 数组,每条记录含类型、节点、新增/删除内容等信息:
- 用
mutation.type区分变更类型:'childList'、'attributes'、'characterData' - 处理
childList时,用Array.from(mutation.addedNodes)转数组,并过滤出元素节点(nodeType === 1) - 避免在回调里直接修改被监听的 DOM,否则可能触发死循环;建议用
DocumentFragment组装后一次性替换 - 高频更新场景(如聊天消息流)可加节流,或只记录变更摘要而非整页 HTML
用完记得断开,防止内存泄漏
观察器持续持有对 DOM 节点的引用,不清理会影响性能:
- 组件卸载、弹窗关闭、预览模式切换时,必须调用
observer.disconnect() - React 中可在
useEffect清理函数里调用;Vue 中可在beforeUnmount钩子中执行 - 临时暂停可用
observer.takeRecords()清空前序未处理记录,再恢复监听
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











