【譯】DOM MutationObserver,在不影響瀏覽器性能的狀況下響應DOM更改。

DOM MutationObserver,在不影響瀏覽器性能的狀況下響應DOM更改。

Dom Mutation Events 在提出時的確是一個很不錯的想法, 隨着web頁面的動態性不斷加強,web開發者很是歡迎這種可以偵聽DOM中的更改並對其做出反應的事件,然而在實踐中,DOM Mutation Events存在着嚴重的性能和穩定性問題,因此此方法已被棄用多年。html

然而,DOM Mutation Events 最初的想法仍是頗有吸引力,所以,在2011年9月,一組谷歌和Mozilla工程師宣佈了一項新提議,即DOM MutationObserver,該提議將提供性能改進後的相似功能。這個新的DOM Api能夠在Firefox和Webkit以及Chrome 18中輕鬆構建。node

簡單來講,MutationObserver實現是這樣的:react

// 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的更改列表,而後您能夠循環該列表並選擇對其做出響應。web

這還意味着,您編寫的任何代碼都須要處理觀察者結果,以便對您正在尋找的更改作出反應。下面是一個緊湊的觀察者的例子,它監聽可編輯有序列表中的變化:api

<!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的另外一個常見用法是在瀏覽器擴展中。bash

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

相關文章
相關標籤/搜索