MutationObserverHtml5新属性监听Dom的变化

it2024-03-18  53

       在最近的项目当中有一个业务是前端监听一个数值的变化 从而给用户进行页面上的提醒(在浏览器的标签处动态跳动当前的信息提醒),在老版本的html可能感觉这个是一个无从下手的需求,需要监听页面的一个节点属性的状态,在之前的老版本html中是没有这个属性了,先将使用这个属性的过程总结如下:

Mutation Observer介绍说明

Mutation Observer(变动观察器)是监视DOM变动的接口。当DOM对象树发生任何变动时,Mutation Observer会得到通知

可以理解为,当DOM发生变动会触发Mutation Observer事件。但是,它与事件有一个本质不同:事件是同步触发,也就是说DOM发生变动立刻会触发相应的事件;Mutation Observer则是异步触发,DOM发生变动以后,并不会马上触发,而是要等到当前所有DOM操作都结束后才触发。

这样设计是为了应付DOM变动频繁的情况。举例来说,如果在文档中连续插入1000个段落(p元素),会连续触发1000个插入事件,执行每个事件的回调函数,这很可能造成浏览器的卡顿;而Mutation Observer完全不同,只在1000个段落都插入结束后才会触发,而且只触发一次。

Mutation Observer有以下特点:

它等待所有脚本任务完成后,才会运行,即采用异步方式它把DOM变动记录封装成一个数组进行处理,而不是一条条地个别处理DOM变动。它即可以观察发生在DOM节点的所有变动,也可以观察某一类变动

如果使用该属性的时候不知道浏览器是否支持可以采用:

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var mutationObserverSupport = !!MutationObserver;

使用方法总结如下;

1,创建一个实例

let observer = new MutationObserver(callback);

2,指定该方法的监听对象

let totalNums = window.document.getElementById('totalNums'); //需要采取原生的js获取元素的方法

3,将监听的方法绑定到查找的对象上面

observer.observe(totalNums, options) 针对options的参数说明:

MutationObserver所观察的DOM变动(即上面代码的option对象),包含以下类型:

其中的可选参数 MutationObserverInit的属性如下:

childLIst 观察目标节点的子节点的新增和删除。attributes 观察目标节点的属性节点(新增或删除了某个属性,以及某个属性的属性值发生了变化)。characterData 如果目标节点为characterData节点(一种抽象接口,具体可以为文本节点,注释节点,以及处理指令节点)时,也要观察该节点的文本内容是否发生变化subtree 观察目标节点的所有后代节点(观察目标节点所包含的整棵DOM树上的上述三种节点变化)attributeOldValue 在attributes属性已经设为true的前提下, 将发生变化的属性节点之前的属性值记录下来(记录到下面MutationRecord对象的oldValue属性中)characterDataOldValue 在characterData属性已经设为true的前提下,将发生变化characterData节点之前的文本内容记录下来(记录到下面MutationRecord对象的oldValue属性中)attributeFilter 一个属性名数组(不需要指定命名空间),只有该数组中包含的属性名发生变化时才会被观察到,其他名称的属性发生变化后会被忽略想要设置那些删选参数的话,

如果想要使用哪个参数的话,就将其值设定为true

disconnect

暂定在观察者对象上设置的节点的变化监听,直到重新调用observe方法

takeRecords

在观察者对象上调用takeRecords 会返回 其观察节点上的变化记录(MutationRecord)数组 其中MutationRecord数组也会作为,观察者初始化时的回调函数的第一个参数 其包含的属性如下:

type 如果是属性发生变化,则返回attributes.如果是一个CharacterData节点发生变化,则返回characterData,如果是目标节点的某个子节点发生了变化,则返回childList.target 返回此次变化影响到的节点,具体返回那种节点类型是根据type值的不同而不同的,如果type为attributes,则返回发生变化的属性节点所在的元素节点,如果type值为characterData,则返回发生变化的这个characterData节点.如果type为childList,则返回发生变化的子节点的父节点.addedNodes 返回被添加的节点removedNodes 返回被删除的节点previousSibling 返回被添加或被删除的节点的前一个兄弟节点nextSibling 返回被添加或被删除的节点的后一个兄弟节点attributeName 返回变更属性的本地名称oldValue 根据type值的不同,返回的值也会不同.如果type为attributes,则返回该属性变化之前的属性值.如果type为characterData,则返回该节点变化之前的文本数据.如果type为childList,则返回null

 

想要观察哪一种变动类型,就在option对象中指定它的值为true。需要注意的是,不能单独观察subtree变动,必须同时指定childList、attributes和characterData中的一种或多种。

除了变动类型,option对象还可以设定以下属性:

attributeOldValue:值为true或者为false。如果为true,则表示需要记录变动前的属性值。characterDataOldValue:值为true或者为false。如果为true,则表示需要记录变动前的数据值。attributesFilter:值为一个数组,表示需要观察的特定属性(比如['class', 'str'])。 // 随后,你还可以停止观察 observer.disconnect();

DOM对象每次发生变化,就会生成一条变动记录。这个变动记录对应一个MutationRecord对象,该对象包含了与变动相关的所有信息。Mutation Observer进行处理的一个个变动对象所组成的数组。

子元素的变动

下面的例子说明如果读取变动记录。

var callback = function(records) { records.map(function(record) { console.log('Mutation type: ' + record.type); console.log('Mutation target: ' + record.target); }); }; var mo = new MutationObserver(callback); var option = { 'childList': true, 'subtree': true }; mo.observer(document.body, option);

属性的变动

var callback = function(records) { records.map(function(record) { console.log('Previous attribute value: ' + record.oldValue); }); }; var mo = new MutationObserver(callback); var element = document.getElementById('#my_element'); var option = { 'attribute': true, 'attributeOldValue': true }; mo.observer(element, option);

上面代码先设定追踪属性变动('attributes': true),然后设定记录变动前的值。实际发生变动时,会将变动前的值显示在控制台。

说下这个使用的采坑点:

Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.

试了好半天 因为项目当中引入了jquery  因此查找需要监听的元素的时候使用了$的方法,这个报错就是指执行需要的是节点(dom元素),不是jq的方法,所以请使用js获取元素;

参考博客来源:

https://www.jianshu.com/p/b5c9e4c7b1e1

https://www.cnblogs.com/jscode/p/3600060.html

技术参考 https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver

 

最新回复(0)