在MVVM
框架中,一是监听数据的变化,数据驱动视图
Object.defineProperties()
来监听数据的变化,或使用proxy
来代理和反射API
来监听DOM
的变化(利用MutationObserver
)来监听DOM
的变化注意
当通过JS
操作了DOM
之后,我们需要通知到DOM
来更新视图,在vue2.0
中是用的Object.defineProperies()
来劫持对象,而vue3.0
中是使用proxy
,维持了一个异步的队列,并不是修改了DOM
就会立即更新到视图上面
Mutaion Observer API
是用来监视DOM
变动,DOM
的任何变动,比如节点的增减,属性的变动,文本内容的变动
这个API
都可以得到通知,Mutation Observer
则是异步触发,DOM
的变动并不会马上触发,而是要等到当前所有DOM
操作都结束才触发,这样是为了应付DOM
变动频繁的特点
提示
假设文档中连续插入 1000 个li
元素,就会连续触发 1000 个插入事件,执行每个事件的回调函数,这很可能会造成浏览器的卡顿,而mutation Observer
则完全不同,只在 1000 个段落都插入结束后才会触发,而且只会触发一次
Mutation Observer
有以下特点
DOM
变动记录封装成一个数组进行处理,而不是单独处理个别的DOM
变动DOM
节点的所有变动,可以观察某一类变动使用实例
// 选择需要观察变动的节点
var targetNode = document.getElementById('app');
// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };
/ 创建一个观察器实例并监听`targetNode`元素的变动
const observer = new MutationObserver(targetNode,config);
实例:
MutationObserver
的callback
的回调函数是异步的,只有在全部DOM
操作完成之后才会调用callback
<div id="target" class="block" name="target">
target的第一个子节点
<p>
<span>target的后代</span>
</p>
</div>
以下是js
代码
var targetNode = document.getElementById('target');
var i = 0;
var observe = new MutationObserver(function (mutations, observe) {
i++;
});
observe.observe(targetNode, { childList: true });
targetNode.appendChild(docuemnt.createTextNode('1'));
targetNode.appendChild(docuemnt.createTextNode('2'));
targetNode.appendChild(docuemnt.createTextNode('3'));
console.log(i); //1 callback的回调次数
应用
有时候,MutationObserver API
都可以派上用场
web
应用程序访问者,监测当前所在页面发生了一些更改,变化javaScript
框架,需要根据DOM
的变化动态加载javaScript
模块结论
MutationObserver
提供了监视DOM
树所做更改的能力,它被设计为旧的Mutation Events
功能的替代品,该功能是DOM3 events
规范的一部分(来自 MDN)MutationObserver
在不影响浏览器性能的情况下响应DOM
更改MutationObserver
会等待所有脚本任务完成后,才会运行,采用异步方式