# MutationObserver
# 1、基础
MutationObserver赋予我们观察一个DOM变化的能力。观察者会观察 DOM 树中的单个Node节点,也可能会观察被指定节点的部分或者所有的子孙节点。
先看一个简单的伪代码,了解一下API。主要就是可以观察一个DOM元素, 然后可以通过options传入一些配置项。构造函数的回调会在DOM变化时被触发。
const observer = new MutationObserver(mutationList => {});
observer.observe(target, options);
// 停止监听
observer.disconnect();
target:DOM 树中的一个要观察变化的 DOM Node (可能是一个 Element),或者是被观察的子节点树的根节点。
options可以有如下属性
- subtree
当为
true
时,将会监听以target
为根节点的整个子树。包括子树中所有节点的属性,而不仅仅是针对target
。默认值为false
。 - childList
当为
true
时,监听target
节点中发生的节点的新增与删除(同时,如果subtree
为true
,会针对整个子树生效)。默认值为false
。 - attributes
当为
true
时观察所有监听的节点属性值的变化。默认值为true
,当声明了attributeFilter
或attributeOldValue
,默认值则为false
。 - attributeFilter 一个用于声明哪些属性名会被监听的数组。如果不声明该属性,所有属性的变化都将触发通知。
- attributeOldValue
当为
true
时,记录上一次被监听的节点的属性变化 - characterData
当为
true
时,监听声明的target
节点上所有字符的变化。默认值为true
,如果声明了characterDataOldValue
,默认值则为false
- characterDataOldValue
当为
true
时,记录前一个被监听的节点中发生的文本变化。默认值为false
# 2、使用
下面是一个简单的demo。下图是MutationRecord的一些属性,个人理解可以根据MutationRecord的type属性判断是什么被更改, 通过addedNodes或者removedNodes判断是新增还是删除操作。 比如下面的childList
就是新增删除元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MutationObserver Demo</title>
</head>
<body>
<div id="container">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<p>sss</p>
</div>
<button onclick="addEl2()">add</button>
<button onclick="deleteEl()">delete</button>
<button onclick="changeAttr()">change attr</button>
<button onclick="changeCharacterData()">Change Character Data</button>
<script>
const container = document.querySelector('#container');
const ul = container.querySelector('ul');
const observer = new MutationObserver(MutationRecordList => {
console.log(MutationRecordList);
});
observer.observe(container, {
subtree: true,
childList: true,
attributes: true
});
// 停止监听
// observer.disconnect();
function addEl2() {
addEl('111');
addEl('222');
}
function addEl(text) {
const el = document.createElement('div');
el.textContent = text;
el.style.color = 'red';
container.appendChild(el);
}
function deleteEl() {
container.removeChild(container.lastChild);
}
function changeAttr() {
ul.setAttribute('id', 'ul-id');
}
function changeCharacterData() {
container.classList.add('container');
}
</script>
</body>
</html>