一、mutationobserver基础及用途
1、mutationobserver是什么?
var observer = new MutationObserver(callback);
mutationobserver指的是监测DOM变化的接口。可以用来监测DOM的子节点、属性和文本变化等等。下面是一个基本的示例:
var target = document.querySelector('#some-id');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
observer.observe(target, { attributes: true, childList: true, characterData: true });
2、mutationobserver的callback
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
使用mutationobserver需要传入一个callback函数,当观察到指定节点的变化时就会回调该函数。该函数的参数是一个MutationRecord对象的数组,MutationRecord对象包含了一些信息,比如打变化的类型、目标节点以及节点的旧值和新值等等,开发者可以根据自己的需求对这些信息做出相应的处理。
3、mutationobserver的用途
mutationobserver在实际开发中有很多用途,比如实时更新某个组件的状态、监测某个元素的变化、自动设置某个元素的高度等等,可以大大提高开发效率。下面是一些应用实例:
(1)监测某个元素的变化
var targetNode = document.getElementById('target');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
(2)实时更新某个组件的状态
var targetNode = document.getElementById('target');
var observer = new MutationObserver(function(mutations) {
var statusNode = document.getElementById('status');
statusNode.innerHTML = '状态已更新';
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
(3)自动设置某个元素的高度
var targetNode = document.getElementById('target');
var observer = new MutationObserver(function(mutations) {
var heightNode = document.getElementById('height');
heightNode.innerHTML = targetNode.offsetHeight;
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
二、mutationobserver常见问题
1、mutationobserver与setTimeout的区别
mutationobserver和setTimeout都可以用来实现实时监测DOM的变化,区别是setTimeout是不停地轮询DOM结构,而mutationobserver则只会在DOM结构发生变化后才会被触发。setTimeout的缺点是会占用一定的CPU资源,同时也可能会导致页面性能下降。因此,在实现类似功能时更推荐使用mutationobserver。
2、mutationobserver的兼容性
mutationobserver是HTML5的新特性,目前主流浏览器均支持,IE11及以上版本也已经支持,但是低于IE11的版本不支持。因此,在兼容性上需要做出一些特别的处理。
3、mutationobserver的性能优化
在使用mutationobserver时一定要注意性能问题,因为如果DOM结构发生变化比较频繁的话,mutationobserver就会在较短的时间内被频繁触发,导致性能下降。因此,开发者需要注意以下几点:
(1)监测尽可能少的节点,因为监测节点越多,触发mutationobserver的频率就越高。
(2)在设置observer.observe()时,尽量避免使用默认的配置,因为默认配置下会监测DOM变化的所有属性。所以只需要监测需要的节点即可。
(3)合理选择callback函数中的处理方式,避免无效操作,提高代码效率。
三、mutationobserver实际应用
1、监测某个元素的变化并更新另一个元素
<div id="target">I love javascript</div>
<div id="result"></div>
<script>
var targetNode = document.getElementById('target');
var resultNode = document.getElementById('result');
var observer = new MutationObserver(function(mutations) {
resultNode.innerHTML = targetNode.innerHTML;
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
</script>
2、自动设置某个元素的高度
<div id="target">I love javascript</div>
<div id="height"></div>
<script>
var targetNode = document.getElementById('target');
var heightNode = document.getElementById('height');
var observer = new MutationObserver(function(mutations) {
heightNode.innerHTML = targetNode.offsetHeight;
});
var config = { attributes: false, childList: true, characterData: false };
observer.observe(targetNode, config);
</script>
3、实时更新某个组件的状态
<div id="target">I love javascript</div>
<div id="status"></div>
<script>
var targetNode = document.getElementById('target');
var statusNode = document.getElementById('status');
var observer = new MutationObserver(function(mutations) {
statusNode.innerHTML = '状态已更新';
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
</script>
四、如何使用mutationobserver实现数据双向绑定
1、数据双向绑定是什么?
数据双向绑定是指当一个模型(Model)的数据发生变化时,视图(View)会做出相应的改变;反之,当用户在视图上进行操作时,模型中的数据也会跟着改变。
2、如何使用mutationobserver实现数据双向绑定?
在实现数据双向绑定时,可以使用mutationobserver来监测数据变化,实现视图的自动更新。具体实现方法如下:
<input type="text" id="input">
<p id="result"></p>
<script>
// 监测input的变化
var input = document.getElementById('input');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes') {
document.getElementById('result').innerHTML = input.value;
}
});
});
observer.observe(input, { attributes: true });
// 监测result的变化
var result = document.getElementById('result');
result.addEventListener('input', function() {
input.value = result.innerHTML;
observer.disconnect();
// 触发一次变化事件,通知数据更新
var e = document.createEvent('HTMLEvents');
e.initEvent('change', true, true);
input.dispatchEvent(e);
observer.observe(input, { attributes: true });
});
</script>
实现数据双向绑定需要注意以下几点:
(1)需要在监测变化时进行判断,避免死循环。
(2)需要在DOM节点发生变化时通过触发一次change事件通知数据进行更新。
(3)在input与result的相互监测时,需要先取消mutatiionobserver的监测,然后再重新开始新的监测。
五、mutationobserver的局限性
mutationobserver虽然强大,但是也有一些局限性,需要注意。
1、mutationobserver的无法监听CSS的变化。比如改变元素的宽度、高度、位置等属性,都无法被mutationobserver检测到。但是可以通过监听resize或scroll事件的方式来实现。
2、无法检测到通过cloneNode()操作插入的节点,节点需要完全重新渲染才能被mutationobserver检测到。
3、无法检测到对Text节点的修改,因为Text节点的nodeValue属性是一个字符串,而不是一个DOM元素。
4、无法检测到通过innerHTML进行赋值的变化,因为这种方式是直接对DOM节点进行赋值,而不是通过DOM操作进行的。
六、总结
mutationobserver作为一种强大的DOM变化监测方式,在实际开发中有着广泛的应用。通过对它的基础、常见问题、实际应用以及局限性等方面进行探究,我们可以更好地了解它的使用方法和注意事项,从而更好地应用它,提高开发效率。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/185811.html