zhengrenzhe's blog   About

JavaScript监听检测DOM更改

JavaScript要监听并检测DOM修改,该怎么做呢。

首先想到了一个简单的办法,就是使用 setInterval 定时执行,每隔一段时间获取一次DOM,看有没有改变。但这就有个问题,如果你的 setInterval 很多,并且也很复杂,此时就会极大的影响页面的性能。

还有一个办法,就是使用 Mutation observers。这是一个DOM4级接口,目前主流浏览器都支持,而IE则需升级到版本11才有。 Mutation observers 可以监听DOM的任何变动,有变动则调用指定的回调函数,与事件类似。

要创建一个MutationObserver,先要使用构造函数新建一个实例,在Chrome,Safari, Firefox的最新版上可以直接使用:

var mb = new MutationObserver(function(MutationRecord){
});

向构造函数中传入的参数就是当DOM改变时触发的回调函数。接着使用实例的observe 方法指定监听的DOM以及监听的类型。

var e = document.getElementById('lalala');
mb.observe(e, {
  'childList': true,
    'subtree': true
});

传入的对象可以设定监听的类型,类型有下列几种:

上面三个分别表示 监听目标节点的字节点的变动,监听目标节点的属性节点的变动,目标节点的文本内容的变化。三个必须有一个为true,否则报错。

除了目标节点,还要监听目标节点的所有后代节点,它与上面三个配合使用。

当 attributes 为 true 时,被监听的节点变化之前的值将被记录下来,存在下面的 oldValue 属性中。

作用于用法与上面相同,只不过被监听的节点是 characterData 。

一个数组,只有在该数组中包含的属性名发生改变时才会被发现,不在数组中的属性名一律被忽略。

当被监听的节点发生改变时,会像前面定义的回调函数中传入 MutationRecord 对象,这个对象中包含被监听DOM的一些信息:

当不想要监听时,可使用 disconnect 方法停止监听,之后节点再有改变时不会调用回调函数

mb.disconnect();

还可以使用 takeRecords 方法来清除 MutationRecord 对象中的变化记录,他将返回清除前的内容

mb.takeRecords();

需要注意的地方

  1. observe 传入的节点必须存在,否则报错。如果想要监听a节点的创建(此时a不存在),则必须监听a的存在的父节点,当a创建时,返回的对象中的addedNodes就是a。

  2. 在被监听的节点改变时,回调函数不会立即调用,而是等到被监听的节点变化完毕后才调用。

← Mac下安装Nginx并开启https  Chrome扩展该如何显示界面 →