MutationObserver: dom變化監聽 給你代碼

2020-12-22 鯤圭雲計算

如何來監聽dom變化?

工作中突然有一個需求,必須你要監聽dom的插入,那麼就需要去監聽dom變化。在一般印象中,監聽事件應該是這麼實現的比如 xx.addEventListener(xxx)。而實際上關於這個dom變化有一套html5標準。如在mdn寫到MutationObserver接口提供了監視對DOM樹所做更改的能力。它被設計為舊的Mutation Events功能的替代品,該功能是DOM3 Events規範的一部分。

使用方法 var observer = new MutationObserver(callback); 該構造函數會在指定dom事件觸發的時候,調用回調函數。callback方法有2個參數,一個是描述所有被觸發改動的 MutationRecord 對象數組,另一個是調用該函數的MutationObserver 對象。第一個屬性比較重要,返回了改變的信息。

然後調用observer.observe(targetNode, observerOptions);該方法配置了 MutationObserver 對象的回調方法以開始接收與給定選項匹配的DOM變化的通知。根據配置,觀察者會觀察 DOM 樹中的單個 Node,也可能會觀察被指定節點的部分或者所有的子孫節點。 observerOptions記錄了選項設置。支持{attributeFilter, attributeOldValue, attributes, characterData, characterDataOldValue, childList ,subtree}。值得注意的是:當調用 observe() 方法時,childList,attributes 或者 characterData 三個屬性之中,至少有一個必須為 true,否則會拋出 TypeError 異常。要停止 MutationObserver(以便不再觸發它的回調方法),需要調用MutationObserver.disconnect()方法。

舉個詳細點的例子。一個頁面我需要在它其他元素沒有超過客戶端高度的時候,給底部容易加以fixed布局。因為這樣的話body後面就不會有空白。而內部容器是有可能實時變化的(元素插入或者刪除)。這樣就需要這個方法去監聽變化。

const callback = function (mutations, ob) { for (let mutation of mutations) { if (mutation.type === 'childList') { resizeHandler(); //設置屬性style } } }; const targetNode = document.body; const observerOptions = { childList: true, // 觀察目標子節點的變化,是否有添加或者刪除 subtree: true // 觀察後代節點,默認為 false } const observer = new MutationObserver(callback); observer.observe(targetNode, observerOptions);因為監聽功能很強大,如果每次記錄屬性變化是非常複雜的,如果胡亂使用屬性監聽,瀏覽器會卡死。這裡就一般記錄節點。如果你的內容操作不是通過插入節點,而是修改屬性的話,這個監聽就會失效了。而這裡的頁面一般是自己製作的,不會有什麼問題。

給你代碼|往期回顧:

擴展的上傳與更新|給你代碼

隨機密碼生成器|給你代碼

你是否像我一樣排斥Composer?|給你代碼

相關焦點

  • 使用Intersection Observer API實現視頻隊列自動播放
    筆者也在之前的文章中詳細介紹了3種Observer(觀察者)的用法,包括位置監聽,dom變化監聽以及窗口變化監聽,它們有非常多的應用場景,所以很有必要研究明白, 感興趣的可以讀完本片文章之後學習一下(幾個非常有意思的javascript知識點總結).
  • 如何監聽頁面 DOM 變動並高效響應
    觸摸與手勢事件 但這樣寫實在有些凌亂,其中一些是 DOM3 定義的事件,有一些是單獨列出的事件,如果你覺得熟悉那麼你會發現這是 JavaScript 高級程序設計裡的敘述模式,在我看來,理解這些事件可以按照 DOM3 事件以及其他事件來做區分:其中,DOM3 級事件規定了以下幾類事件 – UI 事件, 焦點事件, 滑鼠事件, 滾輪事件, 文本事件, 鍵盤事件, 合成事件
  • 你值得擁有!更省錢地完成數據監聽
    很多時候我們希望監聽某個數據的變化,希望一旦獲悉它的變化之後便能立即採取一些舉措。按照常規的操作,我們需要開啟額外的線程來進行監聽。但開啟線程並不是最好的選擇,一是因為非常麻煩,二是會帶來額外的開銷。我們並不是用一些程序去監聽數據的變化,相反,是當數據發生變化的時候,我們去通知對應的監聽器數據產生了變化。好處我們前面也說過了,可以避免多餘的開銷。首先,我們來實現兩個監聽器。當數據發生變化之後就會觸發這兩個監聽器。
  • 喊話JavaScript開發者:玩DOM也要專業範兒
    而且如果你真的不想多打字的話:所有現代編輯器和 IDE 都提供出色的代碼完成功能。你也可以為最常用的功能加上別名,我會在後文給出示例。我們開始吧!DomParser 提供了將 HTML 或 XML 原始碼解析為 DOM 文檔的功能。
  • 用Intersection Observer API實現路由自動切換
    現在單頁面應用已經成為潮流,我們在網上瀏覽別人的網站時可能會看到這樣的網站,隨著頁面的滾動會瀏覽網站的不同部分,而瀏覽器地址欄中的地址也會隨著變化。網站這樣做的好處非常明顯,你可以隨時把當前頁面的URL添加到收藏夾,或者分享給好友。
  • VUE 響應式原理源碼:帶你一步精通 VUE
    ,帶你寫一個簡易版的 VUE,主要實現 VUE 數據響應式 (數據劫持結合發布者-訂閱者)、數組的變異方法、編譯指令,數據的雙向綁定的功能。 VUE在 MVVM 思想下,view 和model 之間沒有直接的聯繫,但是 view 和 view-model 、model和 view-model之間時交互的,當 view 視圖進行 dom 操作等使數據發生變化時,可以通過 view-model 同步到 model 中,同樣的 model 數據變化也會同步到 view 中。
  • 重學鞏固你的Vuejs知識體系(下)
    $el已經掛載在文檔內,對已有dom節點的操作可以在期間進行。beforeUpdate數據更新時調用,發生在虛擬dmo重新渲染和打補丁之前。updated當這個鉤子被調用時,組件dom已經更新,所以你現在可以執行依賴於dom的操作。activated,deactivated,beforeDestroy,destroyed。實例銷毀之前調用,vue實例銷毀後調用。
  • VUE 響應式原理源碼:帶你一步精通 VUE | 原力計劃
    ,帶你寫一個簡易版的 VUE,主要實現 VUE 數據響應式 (數據劫持結合發布者-訂閱者)、數組的變異方法、編譯指令,數據的雙向綁定的功能。VUE在 MVVM 思想下,view 和model 之間沒有直接的聯繫,但是 view 和 view-model 、model和 view-model之間時交互的,當 view 視圖進行 dom 操作等使數據發生變化時,可以通過 view-model 同步到 model 中,同樣的 model 數據變化也會同步到 view 中。
  • 教你用原生js實現具有進度監聽的文件上傳預覽組件
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫本文主要介紹如何使用原生js,通過面向對象的方式實現一個文件上傳預覽的組件,該組件利用FileReader來實現文件在前端的解析,預覽,讀取進度等功能,並對外暴露相應api來實現用戶自定義的需求,比如文件上傳,進度監聽,自定義樣式,讀取成功回調等。
  • 我一定把 React-Router 的真諦給你整地明明白白的
    _pendingLocation = null; // 通過history監聽路由變化,變化的時候,改變state上的location this.unlisten = props.history.listen(location => { if (this.
  • 淺談clickhouse的Mutation機制(附源碼分析)
    最近研究了一點ch的代碼。發現一個很有意思的詞,mutation。
  • 月薪入萬的小姐姐教你6招:如何開發一個簡單漂亮的動畫?
    Hello,大家好,今天小編給大家帶來了一人打氣球的案例,在這個案例中,運用到的知識有很多如:事件監聽,函數原型,事件源對象。這個案例可以很好地鍛鍊我們的書寫代碼的水平。事件監聽是可以獲得當dom節點的事件被觸發時,系統會向事件處理函數中傳入一個對象,這個對象記錄了事件觸發時的重要信息,例如觸發時的滑鼠位置,我們可以通過這個對象獲得事件源對象。然後進行我們想要的操作。函數原型是構造函數創建對象的原始模型。