首页 > 作文

JavaScript中MutationObServer监听DOM元素详情

更新时间:2023-04-03 22:55:49 阅读: 评论:0

一、基本使用

可以通过mutationobrver构造函数实例化,参数是一个回调函数。

let obrver = new mutationobrver(() => console.log("change"));console.log(obrver);

obrver对象原型链如下:

mutationobrver实例:

可以看到有disconnectobrvertakerecords方法。

1. obrver方法监听

obrver方法用于关联dom元素,并根据相关设置进行监听。

语法如下:

// 接收两个参数obrver(dom元素, mutationobrverinit对象);

其中:

第一个参数dom元素就是页面元素,比如:body、div等。第二个参数就是设置要监听的范围。比如:属性、文本、子节点等,是一个键值对数组。

示例1,监听body元素class的变化:

let obrver = new mutationobrver(() => console.log("change"));// 监听body元素的属性变化obrver.obrve(document.body, {    attributes: true});// 更改body元素的class,会异步执行创建mutationobrver对象时传入的回调函数document.body.classname = "main";console.log("修改了body属性");// 控制台输出://    修改了body属性//    change

上面 change 的输出是在 修改了body属性 之后,可见注册的回调函数是异步执行的,是在后面执行的。

2. 回调函数增加mutationrecord实例数组参数

现在回调函数非常简单,就是输出一个字符串,看不出到底发生了什么变化。

其实回调函数接收一个 mutationrecord 实例数组,实务中可以通过这个查看详细的信息。

let obrver = new mutationobrver(    // 回调函数是一个 mutationrecord 实例数组。格式如下:    //     [mutationrecord, mutationrecord, mutationrecord, ...]    (mutationrecords) => console.log(mutationrecords));obrver.obrve(document.body, {    attributes: true});document.body.classname = "main";console.log("修改了body属性");// 控制台输出://    修改了body属性//     (1) [mutationrecord]

其中 mutationrecords信息 如下:

mutationrecord实例

其中几个比较关键的信息:

attributename 表示修改的属性名称target 修改的目标type 类型

如果多次修改body的属性,那么会有多条记录:

// mutationrecordlet obrver = new mutationobrver(    // 回调函数接收一个 mutationrecord 实例,是一个数组。    (mutationrecords) => console.log(mutationrecords));obrver.obrve(document.body, {    attributes: true}); // 修改三次document.body.classname = "main";document.body.classname = "container";document.body.classname = "box"; // 控制台打印如下://     (3) [mutationrecord, mutationrecord, mutationrecord]

注意:

这里不是修改一次就执行一次回调,而是每修改一次就往 mutationrecords 参数加入一个 mutationrecord 实例,最后执行一次回调打印出来。

如果修改一次就执行一次回调,那么性能就会比较差。

3. disconnect方法终止回调

如果要终止回调,可以使用disconnect方法。

let obrver = new mutationobrver(    (mutationrecords) => console.log(mutationrecords));obrver.obrve(document.body, {    attributes: true});// 第一次修改document.body.classname = "main"; // 终止obrver.disconnect(); // 第二次修改document.body.classname = "container"; // 没有日志输出

这里没有日志输出,包括第一次修改也没有日志输出,因为回调函数的执行是异步的,是在最后执行的。后面把obrver终止了,所以就不会执行了。

可以用ttimeout控制最后才终止,这样回调就会正常执行。

let obrver = new mutationobrver(    (mutationrecords) => console.log(mutationrecords));obrver.obrve(document.body, {    attributes: true});// 第一次修改document.body.classname = "main"; // 终止ttimeout(() => {    obrver.disconnect();    // 第三次修改,下面修改不会回调了    document.body.classname = "container";}, 0); // 第二次修改document.body.classname = "container"; // 页面输出://    (2) [mutationrecord, mutationrecord]

终止之后再启用

终止了之后可以再次启动,请看下面示例:

let obrver = new mutationobrver(    (mutationrecords) => console.log(mutationrecords));obrver.obrve(document.body, {    attributes: true});// 第一次修改,会入 mutationrecords 数组document.body.classname = "main";// 终止ttimeout(() => {    obrver.disconnect();    // 第二次修改,因为终止了,下面修改不会入 mutationrecords 数组    document.body.classname = "container";}, 0);ttimeout(() => {    // 再次启用    obrver.obrve(document.body, {        attributes: true    });    // 修改body属性,会入 mutationrecords 数组    document.body.classname = "container";}, 0); // 控制台输出://    [mutationrecord]//    [mutationrecord]

这边回调函数是执行了两次,打印了两个,其中:

第一个输出是在第一次修改,后面没有同步代码了,就执行了回调。第二个输出是在第三次修改,因为重新启用了,所以就正常执行了回调。

第二次修改,因为obrver被终止了,所以修改body的属性不会入 mutationrecords 数组国庆节图片绘画。

4. takerecords方法获取修改记录

如果希望在终止obrver之前,对已有的 mutationrecords 记录进行处理,可以用takerecords方法获取。

let obrver = new mutationobrver(    (mutationrecords) => console.log(mutationrecords));obrver.obrve(document.body, {    attributes: true}); // 第一次修改,会入 mutationrecords 数组document.body.classname = "main";// 第二次修改,会入 mutationrecords 数组document.body.classname = "container";// 第三次修改,会入 mutationrecords 数组document.body.classname = "box";// 取到修改记录,可以对其进行处理let mutationrecords =  obrver.takerecords();console.log(mutationrecords);// 控制台打印://     (3) [mutationrecord, m湖南文理学院芙蓉学院utationrecord, mutationrecord]console.log(obrver.takerecords());// 控制台打印://    []// 终止obrver.disconnect();

二、监听多个元素

上面监听都是只有一个元素,如果要监听多个元素可以复用mutationobrver实例

let obrver = new mutationobrver(    (mutationrecords) => console.log(mutationrecords));// 创建 div1 元素,并监听let div1 = document.createelement("div");obrver.obrve(div1, {    attributes: true});div1.id = "box1"; // 创建div2并监听let div2 = document.createelement("div");obrver.obrve(div2, {    attributes: true});div2.id = "box2"; // 控制台打印://    (2) [mutationrecord, mutationrecord]

控制台打印了两个mutationrecord,其中:

第一个 mutationrecord 就是 div1 的id属性修改记录。第二个 mutationrecord 就是 div2 的id属性修改记录。

其他使用方式和上面的类似。

三、监听范围mutationobrverinit对象

上面的监听都是监听属性,当然也可以监听其他的东西,比如:文本、子节点等。

1. 观察属性

上面的例子都是观察元素自有的属性,这里再举一个自定义属性的例子。

let obrver = new mutationobrver(    (mutationrecords) => console.log(mutationrecords));obrver.obrve(document.body, {    attributes: true});// 修改自定义的属性document.body.tattribute("data-id", 1); // 控制台打印://    [mutationrecord]

修改自定义的属性一样会加入到 mutationrecords 数组。

另外值的一提的是 data-id 经常用来给元素标记一些数据啥的,如果发生变化,程序就可以监听到,就可以处理一些相应的逻辑。

attributefilter过滤:

如果要监听指定的属性变化,可以用 attributefilter 过滤。

let obrver = new mutationobrver(    (mutationrecords) => console.log(mutationrecords));obrver.obrve(document.body, {    attributes: true,    // 设置白名单    attributefilter: ["data-id"]}); // 修改白名单 attributefilter 内的属性,会入 mutationrecordsdocument.body.tattribute("data-id", 1); // 修改不在白名单 attributefilter 内的属性,不会入 mutationrecordsdocument.body.tattribute("class", "main"); // 控制台打印://    [mutationrecord]

attributeoldvalue记录旧值

如果要记录旧值,可以设置 attributeoldvalue true

let obrver = new mutationobrver(    // mutationrecord对象中oldvalue表示旧值    (mutationrecords) => console.log(mutationrecords.map((x) => x.oldvalue)));obrver.obrve(document.body, {    attributes: true,    attributeoldvalue: true,});// 第一次修改,因为原来没有值,所以旧值 oldvalue = nulldocument.body.tattribute("class", "main");// 第二次修改,因为前面有改了一次,所以旧值 oldvalue = maindocument.body.tattribute("class", "container"); // 控制台打印://    (2) [null, 'main']

2. 观察文本

观察文本设置 characterdatatrue 即可,不过只能观察文本节点。

请看如下示例:

<!-- 一个性感的div --><div id="box">hello</div><script type="text/javascript">    let obrver = new mutationobrver(        (mutationrecords) => console.log(mutationrecords)    );    // 获取文本节点    let textnode = document.getelementbyid("box").childnodes[0];    obrver.obrve(textnode, {        // 观察文本变化        characterdata: true    });    // 修改文本    textnode.textcontent = "hi";     // 控制台打印:    //    [mutationrecord]</script>意识形态总结;

如果直接监听div元素,那么是不生效的:

<!-- 一个性感的div --><div id="box">hello</div><script type="text/javascript">    let obrver = new mutationobrver(        (mutationrecords) => console.log(mutationrecords)    );    // 监听div不会生效    let box = document.getelementbyid("box");    obrver.obrve(box, {        characterdata: true    });    box.textcontent = "hi";     // 控制台无输出</script>

characterdataoldvalue记录旧值:

如果要记录文本旧值,可以设置 characterdataoldvaluetrue

<!-- 一个性感的div --><div id="box">hello</div> <script type="text/javascript">    let obrver = new mutationobrver(        (mutationrecords) => console.log(mutationrecords.map((x) => x.oldvalue))    );    // 获取文本节点    let textnode = document.getelementbyid("box").childnodes[0];    obrver.obrve(textnode, {        // 观察文本变化        characterdata: true,        // 保留旧数据        characterdataoldvalue: true,    });    // 修改文本两次    textnode.textcontent = "hi";    textnode.textcontent = "nice";     // 控制台打印:    //    (2) ['hello', 'hi']</script>

因为div内的内容原本为hello,先修改为hi,又修改为nice,所以两次修改的旧值就为:hello 和 hi 了。

3. 观察子节点

mutationobrver 实例也可以观察目标节点子节点的变化。

<!-- 一个性感的div --><div id="box">hello</div><script type="text/javascript">    let obrver = new mutationobrver(        (mutationrecords) => console.log(mutationrecords)    );    // 获取div    let box = document.getelementbyid("box");    obrver.obrve(box, {        // 观察子节点变化        childlist: tr心中的太阳 作文ue,    });    // 添加元素    let span = document.createelement("span")    span.textcontent = "world";    box.appendchild(span);     // 控制台打印:    //    [mutationrecord]</script>

mutationrecord中的addednodes属性记录了增加的节点。

移除节点:

<!-- 一个性感的div --><div id="box">hello</div> <script type="text/javascript">    let obrver = new mutationobrver(        (mutationrecords) => console.log(mutationrecords)    );     // 获取div    let box = document.getelementbyid("box");    obrver.obrve(box, {        // 观察子节点变化        childlist: true,    });    // 移除第一个子节点,就是hello文本节点    box.removechild(box.childnodes[0]);     // 控制台打印:    //    [mutationrecord]</script>

mutationrecord中的removednodes属性记录了移除的节点。

移动节点:

对于已有的节点进行移动,那么会记录两条mutationrecord记录,因为移动现有的节点是先删除,后添加。

<!-- 一个性感的div --><div id="box">hello<span>world</span></div> <script type="text/javascript">    let obrver = new mutationobrver(        (mutationrecords) => console.log(mutationrecords)    );     // 获取div    let box = document.getelementbyid("box");    obrver.obrve(box, {        // 观察子节点变化        childlist: true,    });    // 将span节点移动到hello节点前面    b销售总监ox.inrtbefore(box.childnodes[1], box.childnodes[0]);    // 移动节点,实际是先删除,后添加。     // 控制台打印:    //    (2) [mutationrecord, mutationrecord]</script>

4. 观察子树

上面观察的节点都是当前设置的目标节点,比如body,就只能观察body元素和其子节点的变化。

如果要观察body及其所有后代节点的变化,那么可以设置subtree属性为true

<!-- 一个性感的div --><div id="box">hello<span>world</span></div> <script type="text/javascript">    let obrver = new mutationobrver(        (mutationrecords) => console.log(mutationrecords)    );     let box = document.getelementbyid("box");    obrver.obrve(box, {        attributes: true,        // 观察子树的变化        subtree: true    });    // span元素的id属性变化就可以观察到    box.childnodes[1].id = "text";    // 控制台打印:    //    [mutationrecord]</script>

subtree设置为true后,不光div元素本身,span元素也可以观察到了。

总结:

1. mutationobrver实例可以用来观察对象。2. mutationrecord实例记录了每一次的变化。3. 回调函数需要所有脚本任务完成后,才会执行,即采用异步方式。4. 可以观察的访问有属性、文本、子节点、子树。

到此这篇关于javascriptmutationobrver监听dom元素详情的文章就介绍到这了,更多相关javascript中mutationobrver监听dom元素内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-03 22:55:47,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/2dd69e4374ff57adec11f8f49135e770.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:JavaScript中MutationObServer监听DOM元素详情.doc

本文 PDF 下载地址:JavaScript中MutationObServer监听DOM元素详情.pdf

标签:节点   属性   控制台   回调
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图