成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

JavaScript是如何工作的:使用 MutationObserver 跟蹤 DOM 的變化

jasperyang / 574人閱讀

摘要:復(fù)雜性的增加使得在應(yīng)用程序生命周期的每個(gè)給定時(shí)刻都很難知道的確切狀態(tài)。概述用來(lái)監(jiān)視變動(dòng)。這個(gè)被創(chuàng)建的對(duì)象有三個(gè)方法啟動(dòng)監(jiān)聽(tīng)用來(lái)停止觀察返用來(lái)清除變動(dòng)記錄,即不再處理未處理的變動(dòng)。使用瀏覽器方法,可以設(shè)置一個(gè)任務(wù),定期檢查是否發(fā)生了任何更改。

這是專(zhuān)門(mén)探索 JavaScript 及其所構(gòu)建的組件的系列文章的第10篇。

想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你!

如果你錯(cuò)過(guò)了前面的章節(jié),可以在這里找到它們:

JavaScript 是如何工作的:引擎,運(yùn)行時(shí)和調(diào)用堆棧的概述!

JavaScript 是如何工作的:深入V8引擎&編寫(xiě)優(yōu)化代碼的5個(gè)技巧!

JavaScript 是如何工作的:內(nèi)存管理+如何處理4個(gè)常見(jiàn)的內(nèi)存泄漏 !

JavaScript 是如何工作的:事件循環(huán)和異步編程的崛起+ 5種使用 async/await 更好地編碼方式!

JavaScript 是如何工作的:深入探索 websocket 和HTTP/2與SSE +如何選擇正確的路徑!

JavaScript 是如何工作的:與 WebAssembly比較 及其使用場(chǎng)景 !

JavaScript 是如何工作的:Web Workers的構(gòu)建塊+ 5個(gè)使用他們的場(chǎng)景!

JavaScript 是如何工作的:Service Worker 的生命周期及使用場(chǎng)景!

JavaScript 是如何工作的:Web 推送通知的機(jī)制!

Web 應(yīng)用程序在客戶(hù)端變得越來(lái)越重,原因很多,例如需要更豐富的 UI 來(lái)容納更復(fù)雜的應(yīng)用程序提供的內(nèi)容,實(shí)時(shí)計(jì)算等等。復(fù)雜性的增加使得在 Web 應(yīng)用程序生命周期的每個(gè)給定時(shí)刻都很難知道 UI 的確切狀態(tài)。

而當(dāng)你在搭建某些框架或者庫(kù)的時(shí)候,甚至?xí)永щy,例如,前者需要根據(jù) DOM 來(lái)作出反應(yīng)并執(zhí)行特定的動(dòng)作。

概述

Mutation Observer API 用來(lái)監(jiān)視 DOM 變動(dòng)。DOM 的任何變動(dòng),比如節(jié)點(diǎn)的增減、屬性的變動(dòng)、文本內(nèi)容的變動(dòng),這個(gè) API 都可以得到通知。

概念上,它很接近事件,可以理解為 DOM 發(fā)生變動(dòng)就會(huì)觸發(fā) Mutation Observer 事件。但是,它與事件有一個(gè)本質(zhì)不同:事件是同步觸發(fā),也就是說(shuō),DOM 的變動(dòng)立刻會(huì)觸發(fā)相應(yīng)的事件;Mutation Observer 則是異步觸發(fā),DOM 的變動(dòng)并不會(huì)馬上觸發(fā),而是要等到當(dāng)前所有 DOM 操作都結(jié)束才觸發(fā)。

這樣設(shè)計(jì)是為了應(yīng)付 DOM 變動(dòng)頻繁的特點(diǎn)。舉例來(lái)說(shuō),如果文檔中連續(xù)插入1000個(gè)

  • 元素,就會(huì)連續(xù)觸發(fā)1000個(gè)插入事件,執(zhí)行每個(gè)事件的回調(diào)函數(shù),這很可能造成瀏覽器的卡頓;而 Mutation Observer 完全不同,只在 1000 個(gè)段落都插入結(jié)束后才會(huì)觸發(fā),而且只觸發(fā)一次。

    Mutation Observer有以下特點(diǎn):

    它等待所有腳本任務(wù)完成后,才會(huì)運(yùn)行,即采用異步方式

    它把 DOM 變動(dòng)記錄封裝成一個(gè)數(shù)組進(jìn)行處理,而不是一條條地個(gè)別處理 DOM 變動(dòng)

    它即可以觀察發(fā)生在 DOM 節(jié)點(diǎn)的所有變動(dòng),也可以觀察某一類(lèi)變動(dòng)

    為什么要要監(jiān)聽(tīng) DOM?

    在很多情況下,MutationObserver API 都可以派上用場(chǎng)。例如:

    你希望通知 Web 應(yīng)用程序訪問(wèn)者,他當(dāng)前所在的頁(yè)面發(fā)生了一些更改。

    你正在開(kāi)發(fā)一個(gè)新的 JavaScript 框架,需要根據(jù) DOM 的變化動(dòng)態(tài)加載 JavaScript 模塊。

    也許你正在開(kāi)發(fā)一個(gè)所見(jiàn)即所得(WYSIWYG) 編輯器,試圖實(shí)現(xiàn)撤消/重做功能。通過(guò)利用 MutationObserver API,你可以知道在任何給定的點(diǎn)上進(jìn)行了哪些更改,因此可以輕松地撤消這些更改。

    這些只是 MutationObserver 可以提供幫助的幾個(gè)例子。

    MutationObserver 用法

    在應(yīng)用程序中實(shí)現(xiàn) MutationObserver 相當(dāng)簡(jiǎn)單。你需要通過(guò)傳入一個(gè)函數(shù)來(lái)創(chuàng)建一個(gè) MutationObserver 實(shí)例,每當(dāng)有變化發(fā)生,這個(gè)函數(shù)將會(huì)被調(diào)用。函數(shù)的第一個(gè)參數(shù)是變動(dòng)數(shù)組,每個(gè)變化都會(huì)提供它的類(lèi)型和已經(jīng)發(fā)生的變化的信息。

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

    這個(gè)被創(chuàng)建的對(duì)象有三個(gè)方法:

    observe??— 啟動(dòng)監(jiān)聽(tīng)

    disconnect — 用來(lái)停止觀察

    takeRecords?— 返用來(lái)清除變動(dòng)記錄,即不再處理未處理的變動(dòng)。

    observe()

    observe 方法用來(lái)啟動(dòng)監(jiān)聽(tīng),它接受兩個(gè)參數(shù)。

    第一個(gè)參數(shù):所要觀察的 DOM 節(jié)點(diǎn)

    第二個(gè)參數(shù):一個(gè)配置對(duì)象,指定所要觀察的特定變

    下面的片段展示了如何開(kāi)始啟動(dòng)監(jiān)聽(tīng)(observe??):

    // 開(kāi)始偵聽(tīng)頁(yè)面的根 HTML 元素中的更改。
    mutationObserver.observe(document.documentElement, {
      attributes: true,
      characterData: true,
      childList: true,
      subtree: true,
      attributeOldValue: true,
      characterDataOldValue: true
    });
    

    現(xiàn)在,假設(shè) DOM 中有一些非常簡(jiǎn)單的 div:

    Simple div

    使用 JQuery 來(lái)移除這個(gè) div 上的 class:

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

    正如我們已經(jīng)開(kāi)始觀察到的,在調(diào)用 mutationObserver.observe(…) 之后,將在控制臺(tái)中看到相應(yīng) MutationRecord 的日志:

    這個(gè)是由移除 class 屬性導(dǎo)致的變化。

    MutationRecord 對(duì)象包含了DOM的相關(guān)信息,有如下屬性:

    type:觀察的變動(dòng)類(lèi)型(attribute、characterData或者childList)
    target:發(fā)生變動(dòng)的 DOM 節(jié)點(diǎn)
    addedNodes:新增的 DOM 節(jié)點(diǎn)
    removedNodes:刪除的 DOM 節(jié)點(diǎn)
    previousSibling:前一個(gè)同級(jí)節(jié)點(diǎn),如果沒(méi)有則返回 null
    nextSibling:下一個(gè)同級(jí)節(jié)點(diǎn),如果沒(méi)有則返回 null
    attributeName:發(fā)生變動(dòng)的屬性。如果設(shè)置了attributeFilter,則只返回預(yù)先指定的屬性。
    oldValue:變動(dòng)前的值。這個(gè)屬性只對(duì) attribute 和 characterData 變動(dòng)有效,如果發(fā)生 childList 變動(dòng),則返回 null

    最后,為了在任務(wù)完成后停止觀察 DOM,可以執(zhí)行以下操作:

    mutationObserver.disconnect();
    

    現(xiàn)在,MutationObserver 已經(jīng)被廣泛支持:

    備擇方案

    MutationObserver 在之前還沒(méi)有的,那么在 MutationObserver 還沒(méi)出現(xiàn)之前,開(kāi)發(fā)者采用什么方案呢?

    這是幾個(gè)可用的其他選項(xiàng):

    輪詢(xún)(Polling)

    MutationEvents

    CSS animations

    輪詢(xún)(Polling)

    最簡(jiǎn)單和最簡(jiǎn)單的方法是輪詢(xún)。使用瀏覽器 setInterval 方法,可以設(shè)置一個(gè)任務(wù),定期檢查是否發(fā)生了任何更改。當(dāng)然,這種方法會(huì)顯著降低web 應(yīng)用程序/網(wǎng)站的性能。

    MutationEvents

    在2000年,MutationEvents API 被引入。雖然很有用,但在 DOM中 的每一次更改都會(huì)觸發(fā)改變事件,這同樣會(huì)導(dǎo)致性能問(wèn)題?,F(xiàn)在 MutationEvents API 已經(jīng)被棄用,很快現(xiàn)代瀏覽器將完全停止支持它。

    CSS animations

    另一個(gè)有點(diǎn)奇怪的選擇是依賴(lài) CSS 動(dòng)畫(huà)。這聽(tīng)起來(lái)可能有點(diǎn)令人困惑?;旧?,我們的想法是創(chuàng)建一個(gè)動(dòng)畫(huà),一旦元素被添加到 DOM 中,動(dòng)畫(huà)就會(huì)被觸發(fā)。動(dòng)畫(huà)開(kāi)始的那一刻,animationstart 事件將被觸發(fā):如果已經(jīng)將事件處理程序附加到該事件,那么你將確切地知道元素何時(shí)被添加到 DOM 中。動(dòng)畫(huà)的執(zhí)行時(shí)間周期應(yīng)該很小,用戶(hù)幾乎看不到它。

    首先,需要一個(gè)父級(jí)元素,我們?cè)谒膬?nèi)部監(jiān)聽(tīng)節(jié)點(diǎn)的插入:

    為了得到節(jié)點(diǎn)插入的處理器,需要設(shè)置一系列的 keyframe 動(dòng)畫(huà),當(dāng)節(jié)點(diǎn)插入的時(shí)候,動(dòng)畫(huà)將會(huì)開(kāi)始。

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

    創(chuàng)建 keyfram 后,還需要把它放入你想監(jiān)聽(tīng)的元素上,注意應(yīng)設(shè)置很小的 duration 值 —— 它們將會(huì)減弱動(dòng)畫(huà)在瀏覽器上留下的痕跡。

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

    這會(huì)將動(dòng)畫(huà)添加到 container-element 的所有子節(jié)點(diǎn)。 動(dòng)畫(huà)結(jié)束時(shí),將觸發(fā)插入事件。

    我們需要一個(gè) JavaScript 函數(shù)作為事件監(jiān)聽(tīng)器。在函數(shù)中,必須進(jìn)行初始的 event.animationName 檢查以確保它是我們想要的動(dòng)畫(huà)。

    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)在是時(shí)候?yàn)楦讣?jí)元素添加事件監(jiān)聽(tīng)了:

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

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

    MutationObserver 比上述解決方案有許多優(yōu)點(diǎn)。本質(zhì)上,它涵蓋了 DOM 中可能發(fā)生的每一個(gè)更改,并且在批量觸發(fā)更改時(shí),它的優(yōu)化程度更高。最重要的是,所有主要的現(xiàn)代瀏覽器都支持 MutationObserver,還有一些使用引擎下 MutationEvents 的 polyfill。

    原文:

    https://blog.sessionstack.com...

    代碼部署后可能存在的BUG沒(méi)法實(shí)時(shí)知道,事后為了解決這些BUG,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。

    你的點(diǎn)贊是我持續(xù)分享好東西的動(dòng)力,歡迎點(diǎn)贊!

    歡迎加入前端大家庭,里面會(huì)經(jīng)常分享一些技術(shù)資源。

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

    轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/100860.html

    相關(guān)文章

    • JavaScript工作原理(九):使用MutationObserver跟蹤DOM改變

      摘要:概觀是現(xiàn)代瀏覽器提供的,用于檢測(cè)中的變化。您可能正在使用所見(jiàn)即所得的編輯器,試圖實(shí)現(xiàn)撤銷(xiāo)重做功能。函數(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)用程序在客戶(hù)端越來(lái)越重要,原因很多,比如需要更豐...

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

      摘要:概述是現(xiàn)代瀏覽器提供的用來(lái)檢測(cè)變化的網(wǎng)頁(yè)接口。比如通知用戶(hù)當(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)用...

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

      摘要:概述是現(xiàn)代瀏覽器提供的用來(lái)檢測(cè)變化的網(wǎng)頁(yè)接口。比如通知用戶(hù)當(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è)接口。比如通知用戶(hù)當(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 如何工作系列文章已更新到22篇

      摘要:為了方便大家共同學(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...

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

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

    0條評(píng)論

    閱讀需要支付1元查看
    <