首先咱們來認識下這個api,參考自阮一峯的js教程,Mutation Observer 是用來監視DOM元素的變更。相似於事件,作了一個對應操做,觸發對應事件的執行,可是它們有着根本之間的區別:事件的執行時同步的,觸發的同時,每一個事件依次執行,可是observer是異步觸發的,等到全部dom操做結束,再執行javascript
Mutation Observer API有以下特色:html
1.它等待全部腳本任務完成後,纔會運行(即異步觸發方式)。 2.它把 DOM 變更記錄封裝成一個數組進行處理,而不是一條條個別處理 DOM 變更。 4.它既能夠觀察 DOM 的全部類型變更,也能夠指定只觀察某一類變更。java
來看一個案例,在技術交流羣內一個羣友遇到的問題,一次冒泡執行的observer觸發:api
<body>
<div id="1">
<div id="2">
</div>
</div>
</body>
<script>
const id1 = document.getElementById('1')
const id2 = document.getElementById('2')
id1.addEventListener('click',function(){
id1.setAttribute('name', '222')
console.log('1')
})
id2.addEventListener('click',function(){
console.log('2')
id2.setAttribute('name', '222')
})
new MutationObserver(function() {
console.log('11')
}).observe(id2,{
'attributes': true
})
new MutationObserver(function() {
console.log('22')
}).observe(id1,{
'attributes': true
})
id2.click() // 2, 1,11,22
</script>
複製代碼
不能理解的地方在於爲啥不是這兩種狀況:數組
a. 2, 22 , 1 , 11bash
b. 2, 1, 22 , 11dom
首先,script根據建立的順序,將觀察者push進觀察者數組,也能夠說觀察者隊列。異步
observer是異步觸發,在dom操做以後,而click監聽事件又是同步的,每次操做都會同步觸發,所以,執行狀況是id2元素觸發點擊冒泡,執行點擊事件,修改name值,id2上的observer監聽到name變更,將對應觀察者標記爲待執行。而後是id1元素接收冒泡,執行點擊事件,修改name值,同時id2上的observer監聽到name變更,也將觀察者標記爲待執行。spa
dom操做結束後,遍歷觀察者數組,依次執行執行待執行的觀察者code
從上面流程能夠明白,a狀況確定是不行的,observer是異步執行。而後,根據隊列執行規則,observer回調輸出順序應該是11 , 22。驗證一下也很容易,交換observer的建立順序:
new MutationObserver(function() {
console.log('22')
}).observe(id1,{
'attributes': true
})
new MutationObserver(function() {
console.log('11')
}).observe(id2,{
'attributes': true
})
複製代碼
能夠看到執行結果爲22 ,11