MutationObserver是什麼?

目錄

  • MutationObserver概覽
  • MutationObserver構造器
  • MutationObserver實戰

MutationObserver概覽

  • MutationObserver interface能夠用來監測DOM樹的變化。
  • MutationObserver 是舊的DOM3事件規範Mutation Events特性的一個替換。
  • 在DOM事件觸發的時候,會觸發MutationObserver中傳入的callback。
  • DOM監聽是不會馬上開始的,必須調用observer()方法才能監聽。

MutationObserver構造器

var observer = new MutationObserver(callback);css

callback接受MutationRecord和MutationObserver兩個入參。MutationRecord描述的是變化;MutationObserver觸發callback。html

示例

  • 下面的例子建立了一個MutationObserver
  • 這個observer watch了一個node和它的全部children element的新增和移除,以及element上的attribute的變化。
callback function
function callback(mutationList, observer) {
    mutationList.forEach((mutation) => {
        switch (mutation.type) {
            case 'childList':
                // 關注mutation.addedNodes和mutation.removedNodes屬性
                break;
            case 'attributes':
                // 關注mutation.target, mutation.attributeName, mutation.oldValue
               break;
        }
    })
}

callback() 函數會在observer用observe()開始監視DOM時,指定的觀察請求配置相匹配的更改時,將調用callback()函數。
所發生的更改(對子列表的更改或對屬性的更改)經過查看mutation.type屬性。node

建立而且啓動observer

下面的代碼設置了整個觀察進度。函數

var targetNode = document.querySelector("#someElement");
var observerOptions = {
    childList: true,
    attributes: true,
    subtree: true, // 忽略或設置爲false,只觀察父節點的更改
}
var observer = new MutationObserver(callback);
observer.observe(targetNode, observerOptions);
  • targetNode上每次元素從DOM樹上添加或者刪除,callback都會調用;屬性值發生變化,callback也會調用。
  • 直到disconnect()方法調用,targetNode纔會從DOM樹上移除。

MutationObserver實戰

自定義高德地圖panel樣式(與深度選擇器效果相同的js方案)

<style lang="scss">
// 隱藏跳轉高德地圖的按鈕
/deep/ .amap-call {
  display: none;
}
</style>
爲何要動態監聽panel子節點?
  • 全局css會影響污染全局環境,其餘地方的高德地圖panel會被影響
  • scoped單文件組件中能夠使用深度選擇器修改樣式,/deep/ .amap-all 或者 .map-container >>> .amap-all

不使用深度選擇器的話,還有沒有其餘的方式去修改?
監聽panel動態插入 .amap-all DOM或許能夠試試。this

實現步驟
  • 建立MutationObserver,監聽高德地圖panel DOM樹變化
  • 建立callback,捕捉.amap-call class元素隱藏跳轉高德地圖的按鈕
  • 組件銷燬前disconnect()取消監聽
代碼實現
<div id="panel"></div>
// 動態檢測panel的amap-call節點
observePanelAmapCallNode() {
  const callback = (mutationList, observer) => {
    mutationList.forEach((mutation) => {
      switch (mutation.type) {
        case 'childList':
          // 關注mutation.addedNodes和mutation.removedNodes屬性
          console.log(mutation, observer);
          if (mutation.addedNodes[0].className === 'amap-call') {
            mutation.addedNodes[0].style.display = 'none';
          }
          break;
        default: {
          console.log(mutation, observer);
        }
      }
    });
  };
  const targetNode = document.querySelector('#panel');
  const observerOptions = {
    childList: true,
    subtree: true,
  };
  this.panelAmapCallNodeObserver = new MutationObserver(callback);
  this.panelAmapCallNodeObserver.observe(targetNode, observerOptions);
},
// 取消監聽observer
disconnectObserver() {
  this.panelAmapCallNodeObserver.disconnect();
},
mounted() {
    this.observePanelAmapCallNode();
}
beforeDestroy() {
    this.disconnectObserver();
}

默認樣式(修改前)
imagespa

自定義樣式(修改後)
image3d

MutationObserver成功!code

參考資料:https://developer.mozilla.org...server

相關文章
相關標籤/搜索