摘要:復雜性的增加使得在應用程序生命周期的每個給定時刻都很難知道的確切狀態(tài)。概述用來監(jiān)視變動。這個被創(chuàng)建的對象有三個方法啟動監(jiān)聽用來停止觀察返用來清除變動記錄,即不再處理未處理的變動。使用瀏覽器方法,可以設(shè)置一個任務,定期檢查是否發(fā)生了任何更改。
這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第10篇。
想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!
如果你錯過了前面的章節(jié),可以在這里找到它們:
JavaScript 是如何工作的:引擎,運行時和調(diào)用堆棧的概述!
JavaScript 是如何工作的:深入V8引擎&編寫優(yōu)化代碼的5個技巧!
JavaScript 是如何工作的:內(nèi)存管理+如何處理4個常見的內(nèi)存泄漏 !
JavaScript 是如何工作的:事件循環(huán)和異步編程的崛起+ 5種使用 async/await 更好地編碼方式!
JavaScript 是如何工作的:深入探索 websocket 和HTTP/2與SSE +如何選擇正確的路徑!
JavaScript 是如何工作的:與 WebAssembly比較 及其使用場景 !
JavaScript 是如何工作的:Web Workers的構(gòu)建塊+ 5個使用他們的場景!
JavaScript 是如何工作的:Service Worker 的生命周期及使用場景!
JavaScript 是如何工作的:Web 推送通知的機制!
Web 應用程序在客戶端變得越來越重,原因很多,例如需要更豐富的 UI 來容納更復雜的應用程序提供的內(nèi)容,實時計算等等。復雜性的增加使得在 Web 應用程序生命周期的每個給定時刻都很難知道 UI 的確切狀態(tài)。
而當你在搭建某些框架或者庫的時候,甚至會更加困難,例如,前者需要根據(jù) DOM 來作出反應并執(zhí)行特定的動作。
概述Mutation Observer API 用來監(jiān)視 DOM 變動。DOM 的任何變動,比如節(jié)點的增減、屬性的變動、文本內(nèi)容的變動,這個 API 都可以得到通知。
概念上,它很接近事件,可以理解為 DOM 發(fā)生變動就會觸發(fā) Mutation Observer 事件。但是,它與事件有一個本質(zhì)不同:事件是同步觸發(fā),也就是說,DOM 的變動立刻會觸發(fā)相應的事件;Mutation Observer 則是異步觸發(fā),DOM 的變動并不會馬上觸發(fā),而是要等到當前所有 DOM 操作都結(jié)束才觸發(fā)。
這樣設(shè)計是為了應付 DOM 變動頻繁的特點。舉例來說,如果文檔中連續(xù)插入1000個 元素,就會連續(xù)觸發(fā)1000個插入事件,執(zhí)行每個事件的回調(diào)函數(shù),這很可能造成瀏覽器的卡頓;而 Mutation Observer 完全不同,只在 1000 個段落都插入結(jié)束后才會觸發(fā),而且只觸發(fā)一次。
Mutation Observer有以下特點:
它等待所有腳本任務完成后,才會運行,即采用異步方式
它把 DOM 變動記錄封裝成一個數(shù)組進行處理,而不是一條條地個別處理 DOM 變動
它即可以觀察發(fā)生在 DOM 節(jié)點的所有變動,也可以觀察某一類變動
為什么要要監(jiān)聽 DOM?
在很多情況下,MutationObserver API 都可以派上用場。例如:
你希望通知 Web 應用程序訪問者,他當前所在的頁面發(fā)生了一些更改。
你正在開發(fā)一個新的 JavaScript 框架,需要根據(jù) DOM 的變化動態(tài)加載 JavaScript 模塊。
也許你正在開發(fā)一個所見即所得(WYSIWYG) 編輯器,試圖實現(xiàn)撤消/重做功能。通過利用 MutationObserver API,你可以知道在任何給定的點上進行了哪些更改,因此可以輕松地撤消這些更改。
這些只是 MutationObserver 可以提供幫助的幾個例子。
MutationObserver 用法在應用程序中實現(xiàn) MutationObserver 相當簡單。你需要通過傳入一個函數(shù)來創(chuàng)建一個 MutationObserver 實例,每當有變化發(fā)生,這個函數(shù)將會被調(diào)用。函數(shù)的第一個參數(shù)是變動數(shù)組,每個變化都會提供它的類型和已經(jīng)發(fā)生的變化的信息。
var mutationObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation); }); });
這個被創(chuàng)建的對象有三個方法:
observe??— 啟動監(jiān)聽
disconnect — 用來停止觀察
takeRecords?— 返用來清除變動記錄,即不再處理未處理的變動。
observe()observe 方法用來啟動監(jiān)聽,它接受兩個參數(shù)。
第一個參數(shù):所要觀察的 DOM 節(jié)點
第二個參數(shù):一個配置對象,指定所要觀察的特定變
下面的片段展示了如何開始啟動監(jiān)聽(observe??):
// 開始偵聽頁面的根 HTML 元素中的更改。 mutationObserver.observe(document.documentElement, { attributes: true, characterData: true, childList: true, subtree: true, attributeOldValue: true, characterDataOldValue: true });
現(xiàn)在,假設(shè) DOM 中有一些非常簡單的 div:
Simple div
使用 JQuery 來移除這個 div 上的 class:
$("#sample-div").removeAttr("class");
正如我們已經(jīng)開始觀察到的,在調(diào)用 mutationObserver.observe(…) 之后,將在控制臺中看到相應 MutationRecord 的日志:
這個是由移除 class 屬性導致的變化。
MutationRecord 對象包含了DOM的相關(guān)信息,有如下屬性:
type:觀察的變動類型(attribute、characterData或者childList)
target:發(fā)生變動的 DOM 節(jié)點
addedNodes:新增的 DOM 節(jié)點
removedNodes:刪除的 DOM 節(jié)點
previousSibling:前一個同級節(jié)點,如果沒有則返回 null
nextSibling:下一個同級節(jié)點,如果沒有則返回 null
attributeName:發(fā)生變動的屬性。如果設(shè)置了attributeFilter,則只返回預先指定的屬性。
oldValue:變動前的值。這個屬性只對 attribute 和 characterData 變動有效,如果發(fā)生 childList 變動,則返回 null
最后,為了在任務完成后停止觀察 DOM,可以執(zhí)行以下操作:
mutationObserver.disconnect();
現(xiàn)在,MutationObserver 已經(jīng)被廣泛支持:
備擇方案MutationObserver 在之前還沒有的,那么在 MutationObserver 還沒出現(xiàn)之前,開發(fā)者采用什么方案呢?
這是幾個可用的其他選項:
輪詢(Polling)
MutationEvents
CSS animations
輪詢(Polling)最簡單和最簡單的方法是輪詢。使用瀏覽器 setInterval 方法,可以設(shè)置一個任務,定期檢查是否發(fā)生了任何更改。當然,這種方法會顯著降低web 應用程序/網(wǎng)站的性能。
MutationEvents在2000年,MutationEvents API 被引入。雖然很有用,但在 DOM中 的每一次更改都會觸發(fā)改變事件,這同樣會導致性能問題。現(xiàn)在 MutationEvents API 已經(jīng)被棄用,很快現(xiàn)代瀏覽器將完全停止支持它。
CSS animations另一個有點奇怪的選擇是依賴 CSS 動畫。這聽起來可能有點令人困惑。基本上,我們的想法是創(chuàng)建一個動畫,一旦元素被添加到 DOM 中,動畫就會被觸發(fā)。動畫開始的那一刻,animationstart 事件將被觸發(fā):如果已經(jīng)將事件處理程序附加到該事件,那么你將確切地知道元素何時被添加到 DOM 中。動畫的執(zhí)行時間周期應該很小,用戶幾乎看不到它。
首先,需要一個父級元素,我們在它的內(nèi)部監(jiān)聽節(jié)點的插入:
為了得到節(jié)點插入的處理器,需要設(shè)置一系列的 keyframe 動畫,當節(jié)點插入的時候,動畫將會開始。
@keyframes nodeInserted { from { opacity: 0.99; } to { opacity: 1; } }
創(chuàng)建 keyfram 后,還需要把它放入你想監(jiān)聽的元素上,注意應設(shè)置很小的 duration 值 —— 它們將會減弱動畫在瀏覽器上留下的痕跡。
#container-element * { animation-duration: 0.001s; animation-name: nodeInserted; }
這會將動畫添加到 container-element 的所有子節(jié)點。 動畫結(jié)束時,將觸發(fā)插入事件。
我們需要一個 JavaScript 函數(shù)作為事件監(jiān)聽器。在函數(shù)中,必須進行初始的 event.animationName 檢查以確保它是我們想要的動畫。
var insertionListener = function(event) { // Making sure that this is the animation we want. if (event.animationName === "nodeInserted") { console.log("Node has been inserted: " + event.target); } }
現(xiàn)在是時候為父級元素添加事件監(jiān)聽了:
document.addEventListener(“animationstart”, insertionListener, false); // standard + firefox document.addEventListener(“MSAnimationStart”, insertionListener, false); // IE document.addEventListener(“webkitAnimationStart”, insertionListener, false); // Chrome + Safari
瀏覽器對CSS動畫的支持情況:
MutationObserver 比上述解決方案有許多優(yōu)點。本質(zhì)上,它涵蓋了 DOM 中可能發(fā)生的每一個更改,并且在批量觸發(fā)更改時,它的優(yōu)化程度更高。最重要的是,所有主要的現(xiàn)代瀏覽器都支持 MutationObserver,還有一些使用引擎下 MutationEvents 的 polyfill。
原文:
https://blog.sessionstack.com...
代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行l(wèi)og 調(diào)試,這邊順便給大家推薦一個好用的BUG監(jiān)控工具 Fundebug。
你的點贊是我持續(xù)分享好東西的動力,歡迎點贊!
歡迎加入前端大家庭,里面會經(jīng)常分享一些技術(shù)資源。文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/100860.html
摘要:概觀是現(xiàn)代瀏覽器提供的,用于檢測中的變化。您可能正在使用所見即所得的編輯器,試圖實現(xiàn)撤銷重做功能。函數(shù)的第一個參數(shù)是在一個批次中發(fā)生的所有改變的集合。雖然有用,但中的每一次更改都會觸發(fā)突變事件,這又會導致性能問題。 showImg(https://segmentfault.com/img/bV9Z7q?w=1016&h=252);Web應用程序在客戶端越來越重要,原因很多,比如需要更豐...
摘要:概述是現(xiàn)代瀏覽器提供的用來檢測變化的網(wǎng)頁接口。比如通知用戶當前所在的頁面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開始必須使用代碼進行檢查,確保是我們所監(jiān)聽的動畫。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十章。 網(wǎng)絡(luò)應用...
摘要:概述是現(xiàn)代瀏覽器提供的用來檢測變化的網(wǎng)頁接口。比如通知用戶當前所在的頁面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開始必須使用代碼進行檢查,確保是我們所監(jiān)聽的動畫。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十章。 網(wǎng)絡(luò)應用...
摘要:概述是現(xiàn)代瀏覽器提供的用來檢測變化的網(wǎng)頁接口。比如通知用戶當前所在的頁面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開始必須使用代碼進行檢查,確保是我們所監(jiān)聽的動畫。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十章。 網(wǎng)絡(luò)應用...
摘要:為了方便大家共同學習,整理了之前博客系列的文章,目前已整理是如何工作這個系列,可以請猛戳博客查看。以下列出該系列目錄,歡迎點個星星,我將更友動力整理理優(yōu)質(zhì)的文章,一起學習。 為了方便大家共同學習,整理了之前博客系列的文章,目前已整理 JavaScript 是如何工作這個系列,可以請猛戳GitHub博客查看。 以下列出該系列目錄,歡迎點個星星,我將更友動力整理理優(yōu)質(zhì)的文章,一起學習。 J...
閱讀 1964·2023-04-25 15:45
閱讀 1197·2021-09-29 09:34
閱讀 2497·2021-09-03 10:30
閱讀 2000·2019-08-30 15:56
閱讀 1456·2019-08-29 15:31
閱讀 1267·2019-08-29 15:29
閱讀 3196·2019-08-29 11:24
閱讀 3047·2019-08-26 13:45