摘要:概觀是現(xiàn)代瀏覽器提供的,用于檢測(cè)中的變化。您可能正在使用所見即所得的編輯器,試圖實(shí)現(xiàn)撤銷重做功能。函數(shù)的第一個(gè)參數(shù)是在一個(gè)批次中發(fā)生的所有改變的集合。雖然有用,但中的每一次更改都會(huì)觸發(fā)突變事件,這又會(huì)導(dǎo)致性能問題。
Web應(yīng)用程序在客戶端越來越重要,原因很多,比如需要更豐富的用戶界面來容納更復(fù)雜的應(yīng)用程序必須提供的功能,實(shí)時(shí)計(jì)算等等。
復(fù)雜性的增加使得在Web應(yīng)用程序的生命周期中的每個(gè)特定時(shí)刻都很難知道UI的確切狀態(tài)。
如果你正在構(gòu)建某種框架或僅僅是一個(gè)庫,這會(huì)變得更加困難,例如,它必須作出反應(yīng)并執(zhí)行某些依賴于DOM的操作。
概觀MutationObserver是現(xiàn)代瀏覽器提供的Web API,用于檢測(cè)DOM中的變化。使用此API,可以偵聽新添加或刪除的節(jié)點(diǎn),屬性更改或文本節(jié)點(diǎn)文本內(nèi)容的更改。
你為什么想這么做?
MutationObserver API在很多情況下可以非常方便地使用。例如:
您希望通知您的網(wǎng)絡(luò)應(yīng)用訪問者在他當(dāng)前所在的頁面上發(fā)生了一些變化。
您正在研究一種新的花式JavaScript框架,該框架可根據(jù)DOM如何變化來動(dòng)態(tài)加載JavaScript模塊。
您可能正在使用所見即所得的編輯器,試圖實(shí)現(xiàn)撤銷/重做功能。通過利用MutationObserver API,你可以在任何時(shí)候都能很容易u(yù)ndo他們
這些只是MutationObserver如何提供幫助的幾個(gè)例子。
如何使用MutationObserver在你的應(yīng)用中實(shí)現(xiàn)MutationObserver相當(dāng)容易。您需要通過傳遞一個(gè)函數(shù)來創(chuàng)建一個(gè)MutationObserver實(shí)例,該函數(shù)在每次發(fā)生突變時(shí)都會(huì)被調(diào)用。函數(shù)的第一個(gè)參數(shù)是在一個(gè)批次中發(fā)生的所有改變的集合。每個(gè)改變都提供有關(guān)其類型和已發(fā)生變化的信息。
MutationObserver API,您可以在任何給定的位置知道進(jìn)行了哪些更改,因此您可以輕松地撤消它們。
var mutationObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation); }); });
創(chuàng)建的對(duì)象有三個(gè)方法:
observe - 開始傾聽變化。需要兩個(gè)參數(shù) - 您要觀察的DOM節(jié)點(diǎn)和一個(gè)設(shè)置對(duì)象
disconnect - 停止監(jiān)聽更改
takeRecords - 在回調(diào)被觸發(fā)前返回最后一批更改。
以下片段顯示了如何開始觀察:
// Starts listening for changes in the root HTML element of the page. mutationObserver.observe(document.documentElement, { attributes: true, characterData: true, childList: true, subtree: true, attributeOldValue: true, characterDataOldValue: true });
現(xiàn)在假設(shè)你有一些簡(jiǎn)單的DIV在DOM中:
Simple div
使用jQuery,你你可以移除div的class屬性:
$("#sample-div").removeAttr("class");
正如我們開始觀察的那樣,在調(diào)用mutationObserver.observe(...)之后,我們將在相應(yīng)的MutationRecord的控制臺(tái)中看到一個(gè)日志:
這是由刪除class屬性引起的變異。
最后,為了在完成后停止觀察DOM,可以執(zhí)行以下操作:
// Stops the MutationObserver from listening for changes. mutationObserver.disconnect();
如今,MutationObserver得到了廣泛的支持:
然而,MutationObserver并不總是可用的。那么在MutationObserver出現(xiàn)之前開發(fā)者會(huì)采取什么措施呢?
還有其他幾個(gè)選項(xiàng)可用:
輪詢
MutationEvents
CSS動(dòng)畫
輪詢最簡(jiǎn)單和最簡(jiǎn)單的方式是通過輪詢。使用瀏覽器setInterval WebAPI,您可以設(shè)置一個(gè)任務(wù),定期檢查是否發(fā)生了任何更改。當(dāng)然,這種方法會(huì)顯著降低網(wǎng)絡(luò)應(yīng)用程序/網(wǎng)站的性能。
MutationEvents在2000年,引入了MutationEvents API。雖然有用,但DOM中的每一次更改都會(huì)觸發(fā)突變事件,這又會(huì)導(dǎo)致性能問題?,F(xiàn)在,MutationEvents API已被棄用,很快,現(xiàn)代瀏覽器將不再支持它。
這是MutationEvents的瀏覽器支持:
一個(gè)有點(diǎn)奇怪的選擇是依賴CSS動(dòng)畫。這聽起來有點(diǎn)混亂?;旧?,這個(gè)想法是創(chuàng)建一個(gè)動(dòng)畫,一旦一個(gè)元素被添加到DOM就會(huì)觸發(fā)該動(dòng)畫。動(dòng)畫開始的那一刻,animationstart事件將被觸發(fā):如果您已將事件處理程序附加到該事件,則您將確切知道元素何時(shí)添加到DOM。 動(dòng)畫的執(zhí)行時(shí)間應(yīng)該很小,以至于用戶幾乎看不到它。
首先,我們需要一個(gè)父元素,在其中我們想要聽節(jié)點(diǎn)插入:
為了獲得節(jié)點(diǎn)插入的句柄,我們需要設(shè)置一系列關(guān)鍵幀動(dòng)畫,這些動(dòng)畫將在插入節(jié)點(diǎn)時(shí)開始:
@keyframes nodeInserted { from { opacity: 0.99; } to { opacity: 1; } }
在創(chuàng)建關(guān)鍵幀后,需要將動(dòng)畫應(yīng)用到您想要的元素上。請(qǐng)注意,持續(xù)時(shí)間較短 - 他們正在放松瀏覽器中的動(dòng)畫腳印:
#container-element * { animation-duration: 0.001s; animation-name: nodeInserted; }
這將動(dòng)畫添加到容器元素的所有子節(jié)點(diǎn)。當(dāng)動(dòng)畫結(jié)束時(shí),插入事件將觸發(fā)。
我們需要一個(gè)JavaScript函數(shù)作為事件監(jiān)聽器。在該函數(shù)中,必須進(jìn)行初始event.animationName檢查以確保它是我們想要的動(dòng)畫。
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); } }
顯示是時(shí)候添加監(jiān)聽器到父容器了:
document.addEventListener(“animationstart”, insertionListener, false); // standard + firefox document.addEventListener(“MSAnimationStart”, insertionListener, false); // IE document.addEventListener(“webkitAnimationStart”, insertionListener, false); // Chrome + Safari
CSS動(dòng)畫的瀏覽器支持:
與上述解決方案相比,MutationObserver具有許多優(yōu)點(diǎn)。 從本質(zhì)上講,它涵蓋了DOM中可能發(fā)生的每一個(gè)變化,并且它在批處理中引發(fā)更改時(shí)更加優(yōu)化。最重要的是,所有主要的現(xiàn)代瀏覽器都支持MutationObserver,以及一些使用MutationEvents的polyfill。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94731.html
摘要:復(fù)雜性的增加使得在應(yīng)用程序生命周期的每個(gè)給定時(shí)刻都很難知道的確切狀態(tài)。概述用來監(jiān)視變動(dòng)。這個(gè)被創(chuàng)建的對(duì)象有三個(gè)方法啟動(dòng)監(jiān)聽用來停止觀察返用來清除變動(dòng)記錄,即不再處理未處理的變動(dòng)。使用瀏覽器方法,可以設(shè)置一個(gè)任務(wù),定期檢查是否發(fā)生了任何更改。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第10篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! ...
摘要:概述是現(xiàn)代瀏覽器提供的用來檢測(cè)變化的網(wǎng)頁接口。比如通知用戶當(dāng)前所在的頁面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開始必須使用代碼進(jìn)行檢查,確保是我們所監(jiān)聽的動(dòng)畫。 原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第十章。 網(wǎng)絡(luò)應(yīng)用...
摘要:概述是現(xiàn)代瀏覽器提供的用來檢測(cè)變化的網(wǎng)頁接口。比如通知用戶當(dāng)前所在的頁面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開始必須使用代碼進(jìn)行檢查,確保是我們所監(jiān)聽的動(dòng)畫。 原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第十章。 網(wǎng)絡(luò)應(yīng)用...
摘要:概述是現(xiàn)代瀏覽器提供的用來檢測(cè)變化的網(wǎng)頁接口。比如通知用戶當(dāng)前所在的頁面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開始必須使用代碼進(jìn)行檢查,確保是我們所監(jiān)聽的動(dòng)畫。 原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第十章。 網(wǎng)絡(luò)應(yīng)用...
摘要:為了方便大家共同學(xué)習(xí),整理了之前博客系列的文章,目前已整理是如何工作這個(gè)系列,可以請(qǐng)猛戳博客查看。以下列出該系列目錄,歡迎點(diǎn)個(gè)星星,我將更友動(dòng)力整理理優(yōu)質(zhì)的文章,一起學(xué)習(xí)。 為了方便大家共同學(xué)習(xí),整理了之前博客系列的文章,目前已整理 JavaScript 是如何工作這個(gè)系列,可以請(qǐng)猛戳GitHub博客查看。 以下列出該系列目錄,歡迎點(diǎn)個(gè)星星,我將更友動(dòng)力整理理優(yōu)質(zhì)的文章,一起學(xué)習(xí)。 J...
閱讀 1970·2021-11-22 09:34
閱讀 1192·2021-10-09 09:44
閱讀 3067·2021-09-29 09:35
閱讀 3653·2021-09-14 18:01
閱讀 1519·2021-08-16 10:49
閱讀 1119·2019-08-29 14:11
閱讀 877·2019-08-29 12:47
閱讀 3102·2019-08-26 13:47