目录
- MutationObserver概览
- MutationObserver构造器
- MutationObserver实战
MutationObserver概览
- MutationObserver interface可以用来监测DOM树的变化。
- MutationObserver 是旧的DOM3事件规范Mutation Events特性的一个替换。
- 在DOM事件触发的时候,会触发MutationObserver中传入的callback。
- DOM监听是不会立刻开始的,必须调用observer()方法才能监听。
MutationObserver构造器
var observer = new MutationObserver(callback);
callback接受MutationRecord和MutationObserver两个入参。MutationRecord描述的是变化;MutationObserver触发callback。
示例
- 下面的例子创建了一个MutationObserver
- 这个observer watch了一个node和它的所有children element的新增和移除,以及element上的attribute的变化。
callback function
function callback(mutationList, observer) { mutationList.forEach((mutation) => { switch (mutation.type) { case 'childList': // 关注mutation.addedNodes和mutation.removedNodes属性 break; case 'attributes': // 关注mutation.target, mutation.attributeName, mutation.oldValue break; } }) }
callback() 函数会在observer用observe()开始监视DOM时,指定的观察请求配置相匹配的更改时,将调用callback()函数。
所发生的更改(对子列表的更改或对属性的更改)通过查看mutation.type属性。
创建并且启动observer
下面的代码设置了整个观察进度。
var targetNode = document.querySelector("#someElement"); var observerOptions = { childList: true, attributes: true, subtree: true, // 忽略或设置为false,只观察父节点的更改 } var observer = new MutationObserver(callback); observer.observe(targetNode, observerOptions);
- targetNode上每次元素从DOM树上添加或者删除,callback都会调用;属性值发生变化,callback也会调用。
- 直到disconnect()方法调用,targetNode才会从DOM树上移除。
MutationObserver实战
自定义高德地图panel样式(与深度选择器效果相同的js方案)
<style lang="scss"> // 隐藏跳转高德地图的按钮 /deep/ .amap-call { display: none; } </style>
为什么要动态监听panel子节点?
- 全局css会影响污染全局环境,其他地方的高德地图panel会被影响
- scoped单文件组件中可以使用深度选择器修改样式,/deep/ .amap-all 或者 .map-container >>> .amap-all
不使用深度选择器的话,还有没有其他的方式去修改?
监听panel动态插入 .amap-all DOM或许可以试试
实现步骤
- 创建MutationObserver,监听高德地图panel DOM树变化
- 创建callback,捕捉.amap-call class元素隐藏跳转高德地图的按钮
- 组件销毁前disconnect()取消监听
代码实现
<div id="panel"></div>
// 动态检测panel的amap-call节点 observePanelAmapCallNode() { const callback = (mutationList, observer) => { mutationList.forEach((mutation) => { switch (mutation.type) { case 'childList': // 关注mutation.addedNodes和mutation.removedNodes属性 console.log(mutation, observer); if (mutation.addedNodes[0].className === 'amap-call') { mutation.addedNodes[0].style.display = 'none'; } break; default: { console.log(mutation, observer); } } }); }; const targetNode = document.querySelector('#panel'); const observerOptions = { childList: true, subtree: true, }; this.panelAmapCallNodeObserver = new MutationObserver(callback); this.panelAmapCallNodeObserver.observe(targetNode, observerOptions); }, // 取消监听observer disconnectObserver() { this.panelAmapCallNodeObserver.disconnect(); },
mounted() { this.observePanelAmapCallNode(); }
beforeDestroy() { this.disconnectObserver(); }
默认样式(修改前)
自定义样式(修改后)
MutationObserver成功!
参考资料:https://developer.mozilla.org...