JS随笔监听DOM内容改变
目录
前言
今天项目遇到一个需要监听DOM变化,根据DOM的变化情况,来展示不同的内容,于是上网搜索了各种方式,做一下总结,方便下次查看。
一、addEventListener
关于这个API不要查看菜鸟教程中的解释,直接看MDN即可
- addEventListener函数说明 :https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener
- addEventListener事件参考:事件参考 | MDN
1.示例
对于DOMNodeInserted事件,我们只需要知道使用函数document.addEventListener传递第一个参数为字符串DOMNodeInserted,第二个参数为事件处理函数。
事件处理函数的第一个参数为事件对象,其中属性target为被插入的对象,根据该对象的各种属性,我们执行我们的各种操作(禁用、删除、增加等等)。
代码如下:
-
<body>
-
<table id="outside">
-
<tr>
-
<td id="t1">one</td>
-
</tr>
-
<tr>
-
<td id="t2">two</td>
-
</tr>
-
</table>
-
<script>
-
// 改变 t2 的函数
-
function modifyText() {
-
var t2 = document.getElementById("t2");
-
if (t2.firstChild.nodeValue == "three") {
-
t2.firstChild.nodeValue = "two";
-
} else {
-
t2.firstChild.nodeValue = "three";
-
}
-
}
-
// 为 table 添加事件监听器
-
var el = document.getElementById("outside");
-
el.addEventListener("click", modifyText, false);
-
</script>
-
</body>
二、MutationObserver
参考文档MDN MutationObserver - Web API 接口参考 | MDN。
基础核心:
- MutationAbserver
- MutationAbserverInit
- attributes: true 【是否监听属性变化】
- attributeFilter: ['popkey'] | undefined 【监听的属性范围,如果设置为undefined | 没有设置表示监听全部的属性】
- attibuteOldValue: true 【是否把 回调函数中的MutationRecord.oldValue 对象是否包含了更改前的数据
- characterData: true 【是否监听 内部子文本节点的数据发生变化】
- characterDataOldValue: true 【是否把 之前的数据发送给 MutationRrecord】
- childList: true,【是否 监听子节点的插入/删除】
- subtree: true 【是否 把监听的范围扩展到内部的全部子孙节点】
- MutationRecor
1.示例1
代码如下:
-
<body>
-
<div id="test"></div>
-
<script>
-
const targetNode = document.getElementById('test');
-
// 观察器的配置(需要观察什么变动)
-
const config = { attributes: true, childList: true, subtree: true };
-
// 当观察到变动时执行的回调函数
-
const callback = function (mutationsList, observer) {
-
for (let mutation of mutationsList) {
-
if (mutation.type === 'childList') {
-
console.log('有节点发生改变,当前节点的内容是:');
-
console.log(item.target.innerHTML);
-
}
-
else if (mutation.type === 'attributes') {
-
console.log('修改了' item.attributeName '属性');
-
}
-
}
-
};
-
// 创建一个观察器实例并传入回调函数
-
const observer = new MutationObserver(callback);
-
// 以上述配置开始观察目标节点
-
observer.observe(targetNode, config);
-
// 之后,可停止观察
-
// observer.disconnect();
-
</script>
-
</body>
效果如下图所示:
2.示例2
-
<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</title>
-
</head>
-
<body>
-
<div class='parent'>
-
原始文本
-
</div>
-
-
<script type="text/javascript">
-
-
const el_class_parent = document.querySelector('.parent');
-
const el_div = document.createElement('div')
-
// 文本节点的data就是文本的内容
-
const node_text = el_class_parent.childNodes[0]
-
-
// observer 观察者
-
// 创建一个观察者
-
const observer = new MutationObserver(callback)
-
// 事件处理器
-
function callback(mutationRecords, observer){
-
mutationRecords.forEach(mutationRecord => {
-
console.dir(mutationRecord)
-
if(mutationRecord.type === "attributes") return console.log('属性发生了变化 target =', mutationRecord.target)
-
if(mutationRecord.type === 'childList') return console.log('添加or删除了 childList: ',mutationRecord.target)
-
if(mutationRecord.type === 'characterData') return console.log('文本节点的数据发生了变化',mutationRecord.target)
-
})
-
}
-
-
/*
-
* 配置文件
-
*/
-
const config = {
-
attributes: true,
-
attributeFilter: undefined, /*需要监听的属性名称列表,如果没有表示监听全部的属性*/
-
attributeOldValue: true, /*传递之前旧的值给mutationRecord*/
-
characterData: true, /*是否监听内部文本节点的数据变化*/
-
characterDataOldValue: true, /*mutationRecord 是否包含内部文本节点变化前的数据*/
-
childList: true,
-
subtree: true /*是否把监听的方位放到节点树中的全部子节点上*/
-
}
-
-
observer.observe(el_class_parent, config)
-
-
// 监听内部文本节点的数据变化characterData
-
setTimeout(() => {
-
node_text.data = 'aaa'
-
}, 0)
-
-
// 如果在一个事件循环内设置多个变化
-
// 会在callback中接受到多个 mutationRecord
-
setTimeout(() => {
-
Promise
-
.resolve()
-
.then(() => {
-
console.log('-------------promise 队列执行')
-
el_class_parent.setAttribute('path', "promise")
-
})
-
-
// 设置属性发生变化
-
el_class_parent.setAttribute('path', 'old-path');
-
el_class_parent.setAttribute('path', 'new-path')
-
-
// 设置内容发生变化
-
el_class_parent.innerText = "aaa"
-
-
// 每一次的设置都会调用 callback
-
el_class_parent.append(el_div)
-
-
console.error('----------------------设置更改完毕')
-
-
setTimeout(() => {
-
console.log('--------------------------------下一次事件循环')
-
el_class_parent.setAttribute('path', 'new-path-2')
-
},0)
-
-
setTimeout(() => {
-
console.log('--------------------------- 下一次事件循环')
-
el_div.setAttribute('path', 'div-path')
-
}, 0)
-
-
}, 1000)
-
</script>
-
</body>
-
</html>
总结
addEventListener是W3C
的API,历史遗留接口,很多问题,整体来说不推荐使用
。
MutationObserver是H5
的API,从设计和兼容性上都要好的多,如果在开发中,使用该api更合适。
DOM MutationObserver在不影响浏览器性能的状态下响应DOM更改
等待全部脚本任务执行完成后,才会运行,即采用异步方式
不过在Chrome测试中发现,addEventListener有些状态监控不到,MutationObserver可以弥补这种情况。而MutationObserver像是消息队列的实现方式,不能查看运行时堆栈。所以开发过程中根据需要使用不同的api,也可以同时使用两套api达到目的。
参考资料
javascript 监听DOM内容改变事件 https://juejin.cn/post/7025877062430752775
书籍《JavaScript框架设计》https://book.douban.com/subject/27133542/
Chrome设置断点的各种姿势 https://cloud.tencent.com/developer/article/1093731
参考文章:https://blog.csdn.net/kinghzking/article/details/123684377
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbcjke
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01