用 MutationObserver 监控页面元素属性、Dom结构已经内容是否发生变化
DOM Mutation Events 在当时似乎是个不错的主意–随着网络开发人员创建出更加动态的网络,我们自然会欢迎能够监听 DOM 中的变化并对其做出反应的功能。但实际上,DOM Mutation Events 在性能和稳定性方面都存在很大问题,而且已经废弃一年多了。
然而,DOM Mutation Events 背后的原始想法仍然很有吸引力,因此在 2011 年 9 月,一组 Google 和 Mozilla 工程师宣布了一项新的提案,该提案将提供类似的功能并改进性能:DOM MutationObserver。这一新的 DOM Api 已在 Firefox 和 Webkit 以及 Chrome 中提供。
最简单的 MutationObserver 实现如下:
// select the target node
var target = document.querySelector('#some-id');
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true }
// pass in the target node, as well as the observer options
observer.observe(target, config);
// later, you can stop observing
observer.disconnect();
与已废弃的 DOM Mutation Events 规范相比,新规范的主要优势在于效率。如果您正在观察一个节点的变化,您的回调将在 DOM 完成变化后才被触发。当触发回调时,它将收到 DOM 变化的列表,然后您可以循环查看并选择对其做出反应。
这也意味着您编写的任何代码都需要处理观察结果,以便对您正在寻找的变化做出反应。下面是一个观察器的简洁示例,该观察器可侦听可编辑有序列表中的变化:
如果您玩一下实时示例,您会注意到行为上的一些怪异之处,特别是当您在每个 li
中按下回车键时,尤其是当用户操作导致从 DOM 中添加或删除节点时,回调就会被触发。这是与其他技术(如将事件绑定到按键或 “点击 “等更常见的事件上)的重要区别。MutationObservers 的工作原理与这些技术不同,因为它们是由 DOM 本身的变化触发的,而不是由 JS 或用户交互产生的事件触发的。
那么 MutationObservers 有什么用呢?
我不指望大多数 JS 黑客现在就跑出去开始在他们的代码中添加 mutation observers。这个新 api 的最大受众可能是编写 JS 框架的人,他们主要是为了解决问题和创建以前无法实现的交互,或者至少是无法实现合理性能的交互。另一个用例是您使用的框架会操作 DOM,并且需要高效地对这些修改做出反应(而且不需要 setTimeout!)。
Dom Mutation Events api 的另一个常见用法是在浏览器扩展中使用,在接下来的一周左右,我将发布一篇后续文章,介绍 MutationObservers 在 Firefox 附加组件中与网页内容交互时是如何发挥特殊作用的。