JavaScript MutationObserver 函数
通过 MutationObserver 接口可以跟踪DOM树的修改。它旨在取代以前在 DOM3 事件定义中包含的 Mutation Events 功能。
在复杂的Web项目中,DOM通常会发生变化。因此,有时您的应用程序可能需要对DOM的特定修改作出相应的反应。通过 MutationObserver 接口可以监听DOM的变化。
JavaScript MutationObserver 语法
- MutationObserver 的使用非常简单。应该使用回调函数创建观察者作为初始阶段,例如:
let obs_var = new MutationObserver(callback);
- 将其添加到DOM节点中是下一步,具体步骤如下:
obs_var.observe(node, config);
Config是一个包含参数的对象,用于定义响应的变化,并通过函数返回。
- childList:节点的直接子节点的变化。
- subtree:节点的所有后代。
- attributes:节点的特性。
- attributeFilter:允许您查看的属性名称列表。
- characterData:节点观察。
回调函数会跟随任何修改。观察器成为第二个参数对象,并将修改作为MutationRecord对象列表传递给第一个参数。
如何操作JavaScript MutationObserver
要使用MutationObserver API,首先必须:
- 首先定义在DOM更改时将调用的回调方法:
function callback(mutations) {
// JavaScript program
}
- 首先,创建一个MutationObserver对象,并使用MutationObserver()方法将回调函数发送给该对象的函数:
let observer = new MutationObserver(callback);
- 第三步,通过调用observe()方法来开始跟踪DOM的变化。
observer.observe(targetNode, observerOptions);
observe()函数中有两个参数。目标是需要监视变化的节点子树的根节点。在observerOptions参数中指定了应该向观察者的回调函数通知哪些DOM变化。
- 调用disconnect()方法来停止监视DOM的更新。
observer.disconnect();
示例
以下示例展示了使用不同类型数据的javascript mutationobserver api。
示例1
以下示例展示了基本的javascript mutationobserver api,包含简单的信息。
<!DOCTYPE html>
<html>
<body>
<h2> JavaScript MutationObserver Function</h2>
<div contentEditable id="elemobsId"> Click here and <b> ADD </b>...</div>
<script>
let observer_var = new MutationObserver(mutationdata => {
alert("changes happen");
});
// observe each data of the changes except attributes
observer_var.observe(elemobsId, {
childList: true, // observe direct children list
subtree: true, // observe direct lower descendants
characterDataOldValue: true, // pass old data to callback
});
</script>
</body>
</html>
输出
以下图片展示了基本的Javascript MutationObserver输出。
输出 1
插入字符到输入框中。
输出 2
插入字符后
示例2
下面的示例展示了带有false选项的基本javascript MutationObserver API。
<!DOCTYPE html>
<html>
<body>
<h2> JavaScript MutationObserver Function</h2>
<div contentEditable id="elemobsId"> Click here and <b> ADD </b>...</div>
<script>
let optiondata = {
childList: false, // observe direct children list
subtree: false, // observe direct lower descendants
characterDataOldValue: false, // pass old data to callback
}
let observer_var = new MutationObserver(mutationdata => {
alert("changes happen");
});
// observe each data of the changes except attributes
observer_var.observe(elemobsId, optiondata);
</script>
</body>
</html>
输出
以下图片显示了基本的JavaScript MutationObserver输出。
JavaScript MutationObserver选项
您可以定义选项来描述MutationObserver,将它们作为observe()方法的第二个参数传递:
let choices= {
childList: true,
attributes: true,
characterData: false,
subtree: false,
characterDataOldValue: false
attributeFilter: ['attr1', 'attr2'],
attributeOldValue: false,
};
不必每次都选择每个选项。然而,至少有一个子节点列表(childList),属性(attributes)或字符数据(characterData)必须设置为true,才能使MutationObserver正常工作;否则,observer()方法将返回错误。
MutationRecord对象包括以下属性:
- type:突变的类型。可以是”characterData”(字符数据)、”attributes”(属性)或”childList”(子节点列表)。
- target:发生变化的位置。
- addedNodes/removedNodes:新添加或最近添加的节点。
- 新添加或删除节点的previousSibling/nextSibling。
- attributeName/attributeNamespace:属性的新名称或命名空间。
- oldValue:只有当attributeOldValue/characterDataOldValue被设置为匹配选项,并且发生文本或属性变化时,才有先前的值。
示例
以下示例显示了具有多个选项的基本javascript mutationobserver api。
<!DOCTYPE html>
<html>
<body>
<h2> JavaScript MutationObserver Function</h2>
<div id = "elemobsId"> Click here and <b> ADD </b></div>
<ul contentEditable id = "programming_language">
<li> Java </li>
<li> PHP </li>
<li> JavaScript </li>
<li> PYTHON </li>
<li> PERL </li>
</ul>
<script>
let list_data = document.querySelector('#programming_language');
let option_data = {
childList: true,
attributes: true,
characterData: false,
subtree: false,
attributeFilter: ['one', 'two'],
attributeOldValue: false,
characterDataOldValue: false
};
let observer_var = new MutationObserver(mutationdata => {
alert("changes happen");
});
// observe each data of the changes except attributes
observer_var.observe(list_data, option_data);
</script>
</body>
</html>
输出
以下图像显示了基本的JavaScript突变观察器输出。
观察子元素的变化
突变方法可以显示子元素的开始、停止、添加和移除功能。以下步骤可以帮助显示函数的子元素的变化。
- 在这里,我们可以在HTML中创建一个数据列表。
<ul id = "programming_language">
<li> Java </li>
<li> PHP </li>
<li> JavaScript </li>
<li> PYTHON </li>
<li> PERL </li>
</ul>
- 在html中为功能创建按钮。
<button id = "dataStart"> Start Button </button>
- 使用Javascript的查询选择器创建按钮和数据标签的变量。
let list_data = document.querySelector('#programming_language');
let dataStart = document.querySelector('#dataStart');
使用变量执行变异函数和回调函数
function log_data(mutation data) {
for (let mutation of mutation data) {
if (mutation.type === 'childList') {
console.log(mutation);
}
}
}
let observer_var = new MutationObserver(log_data);
- 使用mutationobserver变量和JavaScript函数添加所需的操作
dataStart.addEventListener('click', function () {
// create a new item element
let item_value = document.createElement('li');
item_value.textContent = `Bootstrap version ${counter++}`;
// append it to the child nodes of list
list_data.appendChild(item_value);
});
示例
以下示例展示了子列表及其数据的不同操作。
示例 1
该示例展示了父元素的子元素的基本变化。
<!DOCTYPE html>
<html>
<body>
<h2> JavaScript MutationObserver Function</h2>
<ul id = "programming_language">
<li> Java </li>
<li> PHP </li>
<li> JavaScript </li>
<li> PYTHON </li>
<li> PERL </li>
</ul>
<div id = "elemobsId"> Click on the button </div>
<button id = "dataStart"> Start Button </button>
<button id = "dataStop"> Stop Button </button>
<script>
let list_data = document.querySelector('#programming_language');
let dataRemove = document.querySelector('#dataRemove');
let dataStop = document.querySelector('#dataStop');
function log_data(mutation data) {
for (let mutation of mutation data) {
if (mutation.type === 'childList') {
console.log(mutation);
}
}
}
let observer_var = new MutationObserver(log_data);
dataStop.addEventListener('click', function () {
observer_var.disconnect();
// set button states to disconnect MutationObserver Function
dataStart.disabled = false;
dataStop.disabled = true;
});
dataStart.addEventListener('click', function () {
observer_var.observe(list_data, {
childList: true
});
dataStart.disabled = true;
dataStop.disabled = false;
});
</script>
</body>
</html>
输出
该图片展示了具有子元素的JavaScript MutationObserver的输出。
输出1
点击开始按钮
输出2
点击停止按钮
示例2
该示例展示了在父元素的子元素中插入数据。
<!DOCTYPE html>
<html>
<body>
<h2> JavaScript MutationObserver Function</h2>
<ul id = "programming_language">
<li> Java </li>
<li> PHP </li>
<li> JavaScript </li>
<li> PYTHON </li>
<li> PERL </li>
</ul>
<div id = "elemobsId"> Click on the button </div>
<button id = "dataStart"> Add Button </button>
<script>
let list_data = document.querySelector('#programming_language');
let dataStart = document.querySelector('#dataStart');
function log_data(mutation data) {
for (let mutation of mutation data) {
if (mutation.type === 'childList') {
console.log(mutation);
}
}
}
let observer_var = new MutationObserver(log_data);
let counter = 1;
dataStart.addEventListener('click', function () {
alert('New Child element is added');
// create a new item element
let item_value = document.createElement('li');
item_value.textContent = `Bootstrap version ${counter++}`;
// append values to the child nodes of a given list
list_data.appendChild(item_value);
});
</script>
</body>
</html>
输出
给定的图片展示了使用JavaScript的MutationObserver处理带有子元素的输出结果。
输出1
在插入最后一个元素之前
输出2
在插入最后一个元素之后
示例 3
该示例展示了父元素的子元素中的已删除数据。
<!DOCTYPE html>
<html>
<body>
<h2> JavaScript MutationObserver Function</h2>
<ul id = "programming_language">
<li> Java </li>
<li> PHP </li>
<li> JavaScript </li>
<li> PYTHON </li>
<li> PERL </li>
</ul>
<div id = "elemobsId"> Click on the button </div>
<button id = "dataRemove">Remove Button </button>
<script>
let list_data = document.querySelector('#programming_language');
let dataRemove = document.querySelector('#dataRemove');
function log_data(mutation data) {
for (let mutation of mutation data) {
if (mutation.type === 'childList') {
console.log(mutation);
}
}
}
let observer_var = new MutationObserver(log_data);
dataRemove.addEventListener('click', function () {
// Delete the last item element of the list
alert('Child element is removed);
list_data.lastElementChild ?
list_data.removeChild(list_data.lastElementChild) :
alert('No more child element to remove');
});
</script>
</body>
</html>
输出
给定的图片显示了列表中删除的最后一个值的输出。
输出1
在删除最后一个元素之前
输出2
移除最后一个元素后
记住mutationObserver的关键细节
- 回调函数,我给它起名为mCallback,以示可以给它任何名字,每当发现有效的突变并在watch()方法结束后激活。
- 由于childList是唯一可接受的突变类型,所以在循环遍历MutationRecord时搜索它是有意义的。在这种情况下,搜索其他类型将是无用的。
- 使用childList可以向目标元素添加或删除文本节点,这也算作突变。这意味着不必添加或删除元素。
结论
javascript的mutationobserver方法观察和操作列表。在这里,我们可以使用多种选项操作和处理列表及其子数据。