前言:紧接上文前端性能监控一文中在FMP,FCP算法设计中需要使用到MutationObserver对象进行一些DOM监控的操作,本文详细介绍一下MutationObserver Api
简介 MutationObserver用于监控DOM树变化,提供了异步方法来监听DOM元素的增加、删除、属性变化操作。开发者可以借助此方法对DOM树变化做出相应的响应。
构造函数MutationObserver() DOM 规范中的 MutationObserver() 构造函数—是 MutationObserver 接口内容的一部分—创建并返回一个新的观察器,它会在触发指定 DOM 事件时,调用指定的回调函数。MutationObserver 对 DOM 的观察不会立即启动;而必须先调用 observe() 方法来确定,要监听哪一部分的 DOM 以及要响应哪些更改。
observe参数:
target: 需要观测的目标节点
options:
attributes:是否监测元素的属性变化。
attributeOldValue:是否在属性变化时记录旧值。
attributeFilter:指定要监测的属性列表。
childList:是否监测子元素的添加或移除。
subtree:是否监测后代元素的变化。
characterData:是否监测文本节点的内容变化。
characterDataOldValue:是否在文本节点内容变化时记录旧值。
1 2 3 4 5 6 7 8 9 10 var targetNode = document .querySelector ("#someElement" );var observerOptions = { childList : true , attributes : true , subtree : true , }; var observer = new MutationObserver (callback);observer.observe (targetNode, observerOptions);
常见的使用场景
动态内容加载 当页面内容是异步加载或者说是动态生成时,可以使用MutationObserver来监控内容变化,并在变化后进行相应的处理,如页面更新,监听事件的绑定。例如:无限滚动场景下可以监听新内容加载到页面,在DOM变化后添加相应的元素或事件。
表单输入动态验证 当需要实时校验用户输入内容时,使用MutationObserver来监控表单内容,值的变化以及禁用状态等,即可实现表单的动态校验。
响应式布局 当页面布局需要根据DOM变化自适应调整时,使用MutationObserver来监测相关元素的变化,并根据变化动态地调整页面布局。例如,在响应式网页设计中,当窗口大小发生变化或元素被添加或移除时,可以使用MutationObserver来监听相关元素的变化,并根据变化重新计算和调整页面布局,以适应不同的设备和屏幕尺寸。
组件内部监听 在自定义组件的开发中,MutationObserver可以用于监听组件内部的DOM变化,以及对应的属性变化。这样可以在组件内部做出相应的处理,如更新组件的状态、重新渲染组件等。例如,当一个自定义组件中的某个子元素被添加或移除时,可以使用MutationObserver来监听这些变化,并在变化发生后更新组件的状态或重新渲染组件。
场景实例
动态校验表单元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 const form = document .querySelector ('#myForm' );const observer = new MutationObserver ((mutationsList ) => { for (let mutation of mutationsList) { if (mutation.type === 'childList' && mutation.target .nodeName === 'INPUT' ) { validateForm (); } if (mutation.type === 'attributes' && mutation.attributeName === 'disabled' ) { validateForm (); } } }); const config = { childList : true , attributes : true , subtree : true };observer.observe (form, config); function validateForm ( ) { const input1 = document .querySelector ('#input1' ); const input2 = document .querySelector ('#input2' ); const value1 = input1.value ; const value2 = input2.value ; const disabled1 = input1.disabled ; const disabled2 = input2.disabled ; }
响应式布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 const observer = new MutationObserver (function (mutationsList ) { for (let mutation of mutationsList) { if (mutation.type === 'childList' ) { adjustLayout (); } } }); const config = { childList : true , subtree : true };window .addEventListener ('resize' , adjustLayout);observer.observe (document .body , config); adjustLayout ();function adjustLayout ( ) { const windowWidth = window .innerWidth ; if (windowWidth > 1024 ) { } else if (windowWidth > 768 ) { } else { } }
参考内容 MDN Web Docs - MutationObserver
注:实例代码均由ChatGpt生成