有时候我们需要获取一个Dom节点未发生变化前的所有相关信息,那么就需要有一个函数去监听它变化前的所有状态,这里要讲的就是MutationObserve,该构造函数出现在DOM4中,是为了替换在DOM3事件规范中引入的Mutation事件.
首先该构造函数创建实例,并且接受一个回调函数,该回调函数含有一个参数MutationRecord,其实就是为了记录有多少个节点发生了变化
MutationRecord有以下几个属性:
在MutationObserve构造函数创建了实例之后就是怎样去使用了。
实例有一个observe方法,接受两个参数,一个是要监听的节点,第二个参数是MutationObserverInit,就是用来配置观察者行为的一个对象,该对象含有以下属性
接下来就是实战了,我们打印一个节点文本变化前的值,即oldValue
首先定义一段html,监听其中text的变化
<a id = "pp">aaa</a>
接下来监听当aaa发生变化时其oldValue,
首先获取要进行观察的元素
let p = document.getElementById(“pp”)
创建MutationObserve的实例
var observer = new MutationObserver(function(mutations){
console.log(mutations.length) //变化节点的个数
mutations.forEach(function(mutation){
console.log(mutation)
console.log(mutation.type)
console.log(mutation.target)
console.log(mutation.addedNodes)
console.log(mutation.removedNodes)
console.log(mutation.previousSibling)
console.log(mutation.attributeName)
console.log(mutation.oldValue)
})
})
创建MutationObserverInit,即哪些属性需要进行观察
var options = {
subtree:true,
characterData:true,
characterDataOldValue:true
}
characterDataOldValue 在characterData属性已经设为true的前提下,如果需要将发生变化的characterData节点之前的文本内容记录下来(记录到下面MutationRecord对象的oldValue属性中),则设置为true.
创建观察:
observer.observe(p,option)
创建了观察之后,要有事件去触发它的值的变化
function changeClass(){
p.innerText = "bbb"
}
function changeClass1(){
p.innerText = "ccc"
}
changeClass()
setTimeout("changeClass1()",1000)
将他的信息逐一打印出来,让文本节点的值变化两次,打印的信息如下
两次的oldValue分别为aaa和bbb,利用这样的变化,你就可以在值变化的时候加一些特定的效果了,比如在股票涨跌时,如果现在的值大于oldValue时让它添加一个红色背景的效果,让人一眼觉得股票是涨是跌。
当然MutationObserve不仅限于观察一个文本的变化,还有各种属性的变化,比如id,class等等。
接下来,来检测一下class的变化
<div id = "pp" class = "text">aaa</div>
创建mutationObserve实例不变,接下来主要是options的配置
由于观察class的变化,所以和观察文本变化一样
var options = {
subtree:true,
attribute:true,
attributeOldValue:true,
}
创建一些函数来该变class
function changeClass(){
p.setAttribute("class","123")
}
function changeClass1(){
p.setAttribute("class","456")
}
changeClass()
setTimeout(“changeClass1()”,1000)
打印的结果和预期一样
注意:要观察文本变化必须设置
characterData:true,
characterDataOldValue:true
观察属性的变化设置
attribute:true,
attributeOldValue:true,
有时候大部分的属性都会变动,我们只需要监测特定的属性变动,所以可以使用
attributeFilter:['class','id']
来代替
attribute:true,
这样只有当class 和id发生变化时才会观察得到。
还有一句话特别注意
oldValue String
根据type值的不同,返回的值也会不同.如果type为 attributes,则返回该属性变化之前的属性值.如果type为characterData,则返回该节点变化之前的文本数据.如果type为childList,则返回null.
如果获取不到预期的oldValue的值,就MutationRecord的type打印出来,若type为childList就要考虑观察的是不是一个文本节点了。