在這之前 DOM3 提供了 Mutation events 事件
- DOMAttrModified
- DOMAttributeNameChanged
- DOMCharacterDataModified
- DOMElementNameChanged
- DOMNodeInserted
- DOMNodeInsertedIntoDocument
- DOMNodeRemoved
- DOMNodeRemovedFromDocument
- DOMSubtreeModified
可以監聽到屬性、文本內容、節點插入刪除、子節點變化等事件。可是該事件 W3C 已廢棄,雖然一些瀏覽器仍然支持,但不建議使用。
MutationObserver目前IE11+及其它瀏覽器最新版本都已支持。可以通過以下代碼判斷是否支持
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var supportMutationObserver = !!MutationObserver;
使用如下
var mo = new MutationObserver(callback); var div = document.querySelector('div'); var options = { 'childList': true, 'arrtibutes': true }; mo.observer(div, options);
options 是配置參數,這里的配置可以觀察到 div 元素的子元素和屬於變動。
options 有如下選項
- childList: 子元素的變動
- attributes: 屬性的變動
- characterData: 節點內容或節點文本的變動
- subtree: 所有下屬節點(包括子節點和子節點的子節點)的變動
- attributeOldValueL: 值為true或者為false。如果為true,則表示需要記錄變動前的屬性值
- characterDataOldValue: 值為true或者為false。如果為true,則表示需要記錄變動前的數據值
- attributesFilter: 值為一個數組,表示需要觀察的特定屬性(比如['class', 'str'])
當變動發生時回調函數會將變動記錄 MutationRecord 對象傳入,MutationRecord 包含了 DOM 的相關信息,有如下屬性
- type: 觀察的變動類型(attribute、characterData或者childList)
- target: 發生變動的DOM對象
- addedNodes: 新增的DOM對象
- removeNodes: 刪除的DOM對象
- previousSibling: 前一個同級的DOM對象,如果沒有則返回null
- nextSibling: 下一個同級的DOM對象,如果沒有就返回null
- attributeName: 發生變動的屬性。如果設置了attributeFilter,則只返回預先指定的屬性
- oldValue: 變動前的值。這個屬性只對attribute和characterData變動有效,如果發生childList變動,則返回null
示例1:觀察子元素的變動
function callback(records) { records.forEach(function(record) { console.log(record) }) } var ob = new MutationObserver(callback) ob.observe(app1, { childList: true, subtree: true })
p1
app1配置項 childList 表示觀察子元素,subtree 表示觀察子元素的下級元素。在本頁面的瀏覽器控制台輸入以下代碼分別測試
app1.removeChild(p1)
app1.appendChild(document.createTextNode('TEST'))
示例2:觀察屬性的變化
function callback2(records) { records.forEach(function(record) { console.log(record) }) } var ob2 = new MutationObserver(callback2) ob2.observe(app2, { attribute: true, attributeOldValue: true })
配置參數跟蹤屬性變動('attributes': true),然后設定記錄變動前的值。實際發生變動時,會將變動前的值顯示在控制台。打開本頁面的瀏覽器控制台,輸入以下代碼測試
app2.id = 'apptest'
示例3:觀察文本元素的變化
function callback3(records) { records.forEach(function(record) { console.log(record) }) } var ob3 = new MutationObserver(callback3) ob3.observe(app3, { characterData: true })
示例3:觀察元素內容的變動
function callback3(records) { records.forEach(function(record) { console.log(record) }) } var ob3 = new MutationObserver(callback3) ob3.observe(app3, { childList: true, characterData: true, characterDataOldValue: true })
配置項會觀察元素文本的變化,當變動時會記錄老的文本元素。打開本頁面的瀏覽器控制台,輸入以下代碼測試
app3.appendChild(document.createTextNode(' hello'))
相關:
https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
https://dev.opera.com/articles/mutation-observers-tutorial/
http://michalbe.blogspot.com/2013/04/javascript-less-known-parts-dom.html