亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JavaScript 工作原理之十-使用 MutationObserver 監(jiān)測(cè) DOM 變化

bbbbbb / 903人閱讀

摘要:概述是現(xiàn)代瀏覽器提供的用來(lái)檢測(cè)變化的網(wǎng)頁(yè)接口。比如通知用戶當(dāng)前所在的頁(yè)面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開(kāi)始必須使用代碼進(jìn)行檢查,確保是我們所監(jiān)聽(tīng)的動(dòng)畫(huà)。

原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。

本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。

這是 JavaScript 工作原理的第十章。

網(wǎng)絡(luò)應(yīng)用在客戶端日益復(fù)雜,這是由很多因素的造成的,比如需要更加豐富的界面交互以提供更加復(fù)雜的應(yīng)用功能,實(shí)時(shí)計(jì)算等等。

網(wǎng)絡(luò)應(yīng)用的日益復(fù)雜導(dǎo)致無(wú)法知曉其生命周期中指定時(shí)刻準(zhǔn)確的交互界面狀態(tài)。

如果你正在構(gòu)建一些框架或者一個(gè)庫(kù),這會(huì)更加的困難,比如,你無(wú)法通過(guò)監(jiān)測(cè) DOM 來(lái)響應(yīng)并執(zhí)行一些特定的操作。

概述

MutationObserver? 是現(xiàn)代瀏覽器提供的用來(lái)檢測(cè) DOM 變化的網(wǎng)頁(yè)接口。你可以使用這個(gè)接口來(lái)監(jiān)聽(tīng)新增或者刪除節(jié)點(diǎn),屬性更改,或者文本節(jié)點(diǎn)的內(nèi)容更改。

可以干點(diǎn)啥好呢?

你可以在以下幾種情況信手拈來(lái) MutationObserver 接口。比如:

通知用戶當(dāng)前所在的頁(yè)面所發(fā)生的一些變化。

通過(guò)使用一些很棒的 JavaScript 框架來(lái)根據(jù) DOM 的變化來(lái)動(dòng)態(tài)加載 JavaScript 模塊。

可能當(dāng)你在開(kāi)發(fā)一個(gè)所見(jiàn)即所得編輯器的時(shí)候,使用 MutationObserver 接口來(lái)收集任意時(shí)間點(diǎn)上的更改,從而輕松地實(shí)現(xiàn)撤消/重做功能。

這只是幾個(gè) MutationObserver 的使用場(chǎng)景。

如何使用 MutationObserver

在應(yīng)用中集成 MutationObserver 是相當(dāng)簡(jiǎn)單的。通過(guò)往構(gòu)造函數(shù) MutationObserver 中傳入一個(gè)函數(shù)作為參數(shù)來(lái)初始化一個(gè) MutationObserver 實(shí)例,該函數(shù)會(huì)在每次發(fā)生 DOM 發(fā)生變化的時(shí)候調(diào)用。MutationObserver 的函數(shù)的第一個(gè)參數(shù)即為單個(gè)批處理中的 DOM 變化集。每個(gè)變化包含了變化的類型和所發(fā)生的更改。

var mutationObserver = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation);
  });
});

創(chuàng)建的實(shí)例對(duì)象擁有三個(gè)方法:

observe-開(kāi)始進(jìn)行監(jiān)聽(tīng)。接收兩個(gè)參數(shù)-要觀察的 DOM 節(jié)點(diǎn)以及一個(gè)配置對(duì)象。

disconnect-停止監(jiān)聽(tīng)變化。

takeRecords-觸發(fā)回調(diào)前返回最新的批量 DOM 變化。

以下為開(kāi)始監(jiān)聽(tīng)的代碼片段:

// 開(kāi)始監(jiān)聽(tīng)頁(yè)面根元素 HTML 變化。
mutationObserver.observe(document.documentElement, {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true,
  attributeOldValue: true,
  characterDataOldValue: true
});

現(xiàn)在,假設(shè)你寫(xiě)了一個(gè)簡(jiǎn)單的 div 元素:

Simple div

可以使用 jQuery 來(lái)移除 div 的 class 屬性:

$("#sample-div").removeAttr("class");

當(dāng)調(diào)用 mutationObserver.observe(…) 就可以開(kāi)始監(jiān)聽(tīng) DOM 變化。

當(dāng)每次發(fā)生 DOM 變化的時(shí)候,會(huì)打印出各個(gè) MutationRecord 日志信息:

這一變化是由移除 class 屬性所引起的。

最后,如果想停止監(jiān)聽(tīng) DOM 變化可以使用如下方法:

// MutationObserver 停止監(jiān)聽(tīng) DOM 變化
mutationObserver.disconnect();

現(xiàn)在,MutationObserver 瀏覽器兼容情況很好:

替代方法

然而,之前 MutationObserver 并沒(méi)有被廣泛使用。那么,當(dāng)沒(méi)有 MutationObserver 的時(shí)候,開(kāi)發(fā)者是如何解決監(jiān)聽(tīng) DOM 變化的呢?

有幾下幾種可用的方法:

輪詢

MutationEvents

CSS 動(dòng)畫(huà)

輪詢

最簡(jiǎn)單且粗糙的方法即使用輪詢。使用瀏覽器內(nèi)置的 setInterval 網(wǎng)頁(yè)接口你可以創(chuàng)建一個(gè)定時(shí)任務(wù)來(lái)定時(shí)檢查 DOM 的變化。當(dāng)然了,這個(gè)方法會(huì)顯著地減弱網(wǎng)絡(luò)應(yīng)用/網(wǎng)站的性能。

其實(shí),這是可以理解為臟檢查,如果有使用過(guò) AngularJS 應(yīng)該會(huì)有看過(guò)其臟檢查所導(dǎo)致的性能問(wèn)題。在我的另一個(gè)系列里面有稍微介紹了下,具體可以查看這里。

MutationEvents

早在 2000 年,就推出了 MutationEvents API 。雖然挺管用的,但是每個(gè)單一的 DOM 變化都會(huì)觸發(fā) mutation 事件,結(jié)果又會(huì)造成性能問(wèn)題。現(xiàn)在,MutationEvents 接口已經(jīng)被廢棄,不久的將來(lái),現(xiàn)代瀏覽器全都將停止支持該接口。

以下是 MutationEvents 的瀏覽器兼容情況:

CSS 動(dòng)畫(huà)

依靠 CSS 動(dòng)畫(huà) 是一個(gè)有點(diǎn)令人感到新奇的替代方案。這聽(tīng)起來(lái)會(huì)讓人有些困惑。大體上,實(shí)現(xiàn)思路是這樣的,創(chuàng)建一個(gè)動(dòng)畫(huà),一旦在 DOM 中添加一個(gè)元素就會(huì)觸發(fā)該動(dòng)畫(huà)。開(kāi)始執(zhí)行 CSS 動(dòng)畫(huà)的時(shí)候就會(huì)觸發(fā) animationstart 事件:假設(shè)為該事件添加事件監(jiān)聽(tīng)器,就可以準(zhǔn)確知曉 DOM 中添加元素的時(shí)機(jī)。動(dòng)畫(huà)的運(yùn)行時(shí)間周期必須非常的短以便讓用戶感知不到,即體驗(yàn)更佳。

首先,需要一個(gè)父級(jí)元素,在里面監(jiān)聽(tīng)節(jié)點(diǎn)添加事件:

為了處理節(jié)點(diǎn)的添加,需要?jiǎng)?chuàng)建關(guān)鍵幀序列動(dòng)畫(huà),該序動(dòng)畫(huà)在添加節(jié)點(diǎn)的時(shí)候啟動(dòng):

@keyframes nodeInserted { 
 from { opacity: 0.99; }
 to { opacity: 1; } 
}

創(chuàng)建好關(guān)鍵幀之后,在需要監(jiān)聽(tīng)的元素上應(yīng)用動(dòng)畫(huà)。注意到那個(gè)短暫的持續(xù)時(shí)間-在瀏覽器端動(dòng)畫(huà)痕跡會(huì)非常平滑(即用戶會(huì)感覺(jué)不到有動(dòng)畫(huà)發(fā)生):

#container-element * {
 animation-duration: 0.001s;
 animation-name: nodeInserted;
}

這樣會(huì)為 container-element 的所有后代節(jié)點(diǎn)添加動(dòng)畫(huà)。當(dāng)動(dòng)畫(huà)結(jié)束,觸發(fā) insertion 事件。

我們需要?jiǎng)?chuàng)建一個(gè)函數(shù)作為事件監(jiān)聽(tīng)器。在函數(shù)內(nèi)部,開(kāi)始必須使用 event.animationName 代碼進(jìn)行檢查,確保是我們所監(jiān)聽(tīng)的動(dòng)畫(huà)。

var insertionListener = function(event) {
  // 確保是所監(jiān)聽(tīng)的動(dòng)畫(huà)
  if (event.animationName === "nodeInserted") {
    console.log("Node has been inserted: " + event.target);
  }
}

為父元素綁定事件監(jiān)聽(tīng)器:

document.addEventListener(“animationstart”, insertionListener, false); // standard + firefox
document.addEventListener(“MSAnimationStart”, insertionListener, false); // IE
document.addEventListener(“webkitAnimationStart”, insertionListener, false); // Chrome + Safari

這里采用了事件委托。

CSS 動(dòng)畫(huà)瀏覽器支持情況:

相比以上幾種替代方案 MutationObserver 有幾點(diǎn)優(yōu)勢(shì)。本質(zhì)上,它會(huì)監(jiān)聽(tīng) DOM 可能發(fā)生的每個(gè)變化并且性能更優(yōu),因其會(huì)批量 DOM 變化之后才觸發(fā)回調(diào)事件??傊?b>MutationObserver 的兼容性很好,并且還有一些墊片,這些墊片底層是基于 MutationEvents 的。

本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/113471.html

相關(guān)文章

  • JavaScript 工作原理之十使用 MutationObserver 監(jiān)測(cè) DOM 變化

    摘要:概述是現(xiàn)代瀏覽器提供的用來(lái)檢測(cè)變化的網(wǎng)頁(yè)接口。比如通知用戶當(dāng)前所在的頁(yè)面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開(kāi)始必須使用代碼進(jìn)行檢查,確保是我們所監(jiān)聽(tīng)的動(dòng)畫(huà)。 原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第十章。 網(wǎng)絡(luò)應(yīng)用...

    zone 評(píng)論0 收藏0
  • JavaScript 工作原理之十使用 MutationObserver 監(jiān)測(cè) DOM 變化

    摘要:概述是現(xiàn)代瀏覽器提供的用來(lái)檢測(cè)變化的網(wǎng)頁(yè)接口。比如通知用戶當(dāng)前所在的頁(yè)面所發(fā)生的一些變化。觸發(fā)回調(diào)前返回最新的批量變化。在函數(shù)內(nèi)部,開(kāi)始必須使用代碼進(jìn)行檢查,確保是我們所監(jiān)聽(tīng)的動(dòng)畫(huà)。 原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第十章。 網(wǎng)絡(luò)應(yīng)用...

    Richard_Gao 評(píng)論0 收藏0
  • JavaScript工作原理(九):使用MutationObserver跟蹤DOM的改變

    摘要:概觀是現(xiàn)代瀏覽器提供的,用于檢測(cè)中的變化。您可能正在使用所見(jiàn)即所得的編輯器,試圖實(shí)現(xiàn)撤銷重做功能。函數(shù)的第一個(gè)參數(shù)是在一個(gè)批次中發(fā)生的所有改變的集合。雖然有用,但中的每一次更改都會(huì)觸發(fā)突變事件,這又會(huì)導(dǎo)致性能問(wèn)題。 showImg(https://segmentfault.com/img/bV9Z7q?w=1016&h=252);Web應(yīng)用程序在客戶端越來(lái)越重要,原因很多,比如需要更豐...

    1fe1se 評(píng)論0 收藏0
  • js mutationobserver簡(jiǎn)要介紹

    摘要:觀察者模式介紹觀察者設(shè)計(jì)模式定義了對(duì)象間的一種一對(duì)多的依賴關(guān)系,以便一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí),所有依賴于它的對(duì)象都得到通知并自動(dòng)刷新。 觀察者模式介紹 觀察者設(shè)計(jì)模式定義了對(duì)象間的一種一對(duì)多的依賴關(guān)系,以便一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí), 所有依賴于它的對(duì)象都得到通知并自動(dòng)刷新。 一些好的文章觀察者模式與委托模式的區(qū)別深入理解JavaScript系列(32):設(shè)計(jì)模式之觀察者模式【Ja...

    leone 評(píng)論0 收藏0
  • MutationObserver 監(jiān)聽(tīng) DOM 樹(shù)變化

    摘要:是用于代替作為觀察樹(shù)結(jié)構(gòu)發(fā)生變化時(shí),做出相應(yīng)處理的。觸發(fā)回調(diào)前返回最新的批量變化。發(fā)生相應(yīng)變動(dòng)時(shí),不再調(diào)用回調(diào)函數(shù)。其中數(shù)組也會(huì)作為,觀察者初始化時(shí)的回調(diào)函數(shù)的第一個(gè)參數(shù)。如果為,則表示需要記錄變動(dòng)前的屬性值。 MutationObserver 是用于代替 MutationEvents 作為觀察 DOM 樹(shù)結(jié)構(gòu)發(fā)生變化時(shí),做出相應(yīng)處理的 API 。為什么要使用 MutationObse...

    psychola 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<