今天看啥  ›  专栏  ›  筱筱酱

【译】DOM MutationObserver,在不影响浏览器性能的情况下响应DOM更改。

筱筱酱  · 掘金  ·  · 2019-07-06 10:39
阅读 56

【译】DOM MutationObserver,在不影响浏览器性能的情况下响应DOM更改。

DOM MutationObserver,在不影响浏览器性能的情况下响应DOM更改。

Dom Mutation Events 在提出时的确是一个很不错的想法, 随着web页面的动态性不断增强,web开发者非常欢迎这种能够侦听DOM中的更改并对其作出反应的事件,然而在实践中,DOM Mutation Events存在着严重的性能和稳定性问题,所以此方法已被弃用多年。

然而,DOM Mutation Events 最初的想法还是很有吸引力,因此,在2011年9月,一组谷歌和Mozilla工程师宣布了一项新提议,即DOM MutationObserver,该提议将提供性能改进后的类似功能。这个新的DOM Api可以在Firefox和Webkit以及Chrome 18中轻松构建。

简单来说,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的更改列表,然后您可以循环该列表并选择对其作出响应。

这还意味着,您编写的任何代码都需要处理观察者结果,以便对您正在寻找的更改做出反应。下面是一个紧凑的观察者的例子,它监听可编辑有序列表中的变化:

<!DOCTYPE html>
<ol contenteditable oninput="">
  <li>Press enter</li>
</ol>
<script>
  var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  var list = document.querySelector('ol');
 
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.type === 'childList') {
        var list_values = [].slice.call(list.children)
            .map( function(node) { return node.innerHTML; })
            .filter( function(s) {
              if (s === '<br />') {
                return false;
              }
              else {
                return true;
              }
        });
        console.log(list_values);
      }
    });
  });
 
  observer.observe(list, {
  	attributes: true,
  	childList: true,
  	characterData: true
   });
</script>
复制代码

如果你运行这个示例,你会发现一个奇怪之处,它将在每个li中按enter键时触发回调,用户操作导致从DOM添加或删除节点时触发回调。这是与其他技术(如将事件绑定到按键或更常见的事件(如“click”)的重要区别。mutationobserver的工作方式与这些技术不同,因为它们是由DOM本身的更改触发的,而不是由通过JS或用户交互生成的事件触发的。

这些有什么用呢?

我不认为大多数JS黑客会马上在他们的代码中添加mutation observers。这个新api的最大受众可能是那些编写JS框架的人,他们主要是为了解决问题和创建以前无法完成的交互,或者至少没有合理的性能。另一个用例是这样一种情况:您正在使用框架来操作DOM,并且需要对这些修改做出有效的反应(而且没有setTimeout攻击!) Dom Mutation Events api的另一个常见用法是在浏览器扩展中。

原文地址:DOM MutationObserver – reacting to DOM changes without killing browser performance.




原文地址:访问原文地址
快照地址: 访问文章快照