成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

了解HTML5中的MutationObserver

Simon / 3441人閱讀

摘要:的出現(xiàn)就是為了解決帶來的問題。對于,它是其中這兩個屬性不管是哪種觀察方式都會有返回值,其他屬性返回值與觀察方式有關(guān),比如只有當(dāng)或者為時才有返回值,只有改變屬性時,才有返回值等。

MutationObserver翻譯過來就是變動觀察器,字面上就可以理解這是用來觀察Node(節(jié)點)變化的。MutationObserver是在DOM4規(guī)范中定義的,它的前身是MutationEvent事件,該事件最初在DOM2事件規(guī)范中介紹,到來了DOM3事件規(guī)范中正式定義,但是由于該事件存在兼容性以及性能上的問題被棄用。

MutationEvent

雖然MutationEvent已經(jīng)被棄用,但是我們還是需要了解它,可能你會為了瀏覽器兼容性的問題而遇到它(萬惡的瀏覽器兼容性)。

MutationEvent總共有7種事件:DOMNodeInserted、DOMNodeRemovedDOMSubtreeModified、DOMAttrModified
DOMCharacterDataModified、DOMNodeInsertedIntoDocumentDOMNodeRemovedFromDocument

MutationEvent的兼容性:

MutationEvent在IE瀏覽器中最低支持到IE9

在webkit內(nèi)核的瀏覽器中,不支持DOMAttrModified事件

IE,Edge以及Firefox瀏覽器下不支持DOMNodeInsertedIntoDocumentDOMNodeRemovedFromDocument事件

MutationEvent中的所有事件都被設(shè)計成無法取消,如果可以取消MutationEvent事件則會導(dǎo)致現(xiàn)有的DOM接口無法對文檔進行改變,比如appendChild,remove等添加和刪除節(jié)點的DOM操作。
MutationEvent中最令人詬病的就是性能以及安全性的問題,比如下面這個例子:

document.addEventListener("DOMNodeInserted", function() {
    var newEl = document.createElement("div");
    document.body.appendChild(newEl);
});

document下的所有DOM添加操作都會觸發(fā)DOMNodeInserted方法,這時就會出現(xiàn)循環(huán)調(diào)用DOMNodeInserted方法,導(dǎo)致瀏覽器崩潰。還有就是MutationEvent是事件機制,因此會有一般事件都存在的捕獲和冒泡階段,此時如果在捕獲和冒泡階段又對DOM進行了操作會拖慢瀏覽器的運行。

另一點就是MutationEvent事件機制是同步的,也就是說每次DOM修改就會觸發(fā),修改幾次就觸發(fā)幾次,嚴(yán)重降低瀏覽器的運行,嚴(yán)重時甚至導(dǎo)致線程崩潰

var i=0;
block.addEventListener("DOMNodeInserted", function(e) {
     i++                                  
});
block.appendChild(docuemnt.createTextNode("1"));
console.log(i)                  //1
block.appendChild(docuemnt.createTextNode("2"));
console.log(i)                  //2
block.appendChild(docuemnt.createTextNode("3"));
console.log(i)                  //3

再看個例子:

Text
block.addEventListener("DOMNodeInserted", function(e) {
     console.log("1");                                  //1
});
span.appendChild(docuemnt.createTextNode("other Text"));

span元素中添加節(jié)點會觸發(fā)block中的DOMNodeInserted事件,可是你只想觀察block的變化,不想觀察block中子節(jié)點的變化,這時你不得不在DOMNodeInserted事件中進行過濾,把對span的操作忽略掉,這無疑增加了操作的復(fù)雜性。

MutationObserver

MutationObserver的出現(xiàn)就是為了解決MutationEvent帶來的問題。
先看一下MutationObserver的瀏覽器兼容性:

我們可以看到MutationObserver在IE中最低要就是IE11,如果你的網(wǎng)站不需要支持IE或者只支持到IE11,那么你可以放心的使用MutationObserver,否則你可能需要用到上面提到的MutationEvent事件,當(dāng)然如果你的網(wǎng)站還要支持IE8及以下版本,那么你只能和Mutation說拜拜了。

MutationObserver是一個構(gòu)造器,接受一個callback參數(shù),用來處理節(jié)點變化的回調(diào)函數(shù),返回兩個參數(shù),mutations:節(jié)點變化記錄列表(sequence),observer:構(gòu)造MutationObserver對象。

var observe = new MutationObserver(function(mutations,observer){
})

MutationObserver對象有三個方法,分別如下:

observe:設(shè)置觀察目標(biāo),接受兩個參數(shù),target:觀察目標(biāo),options:通過對象成員來設(shè)置觀察選項

disconnect:阻止觀察者觀察任何改變

takeRecords:清空記錄隊列并返回里面的內(nèi)容

關(guān)于observe方法中options參數(shù)有已下幾個選項:

childList:設(shè)置true,表示觀察目標(biāo)子節(jié)點的變化,比如添加或者刪除目標(biāo)子節(jié)點,不包括修改子節(jié)點以及子節(jié)點后代的變化

attributes:設(shè)置true,表示觀察目標(biāo)屬性的改變

characterData:設(shè)置true,表示觀察目標(biāo)數(shù)據(jù)的改變

subtree:設(shè)置為true,目標(biāo)以及目標(biāo)的后代改變都會觀察

attributeOldValue:如果屬性為true或者省略,則相當(dāng)于設(shè)置為true,表示需要記錄改變前的目標(biāo)屬性值,設(shè)置了attributeOldValue可以省略attributes設(shè)置

characterDataOldValue:如果characterData為true或省略,則相當(dāng)于設(shè)置為true,表示需要記錄改變之前的目標(biāo)數(shù)據(jù),設(shè)置了characterDataOldValue可以省略characterData設(shè)置

attributeFilter:如果不是所有的屬性改變都需要被觀察,并且attributes設(shè)置為true或者被忽略,那么設(shè)置一個需要觀察的屬性本地名稱(不需要命名空間)的列表

下表描述了MutationObserver選項與MutationEvent名稱之間的對應(yīng)關(guān)系:

MutationEvent MutationObserver options
DOMNodeInserted { childList: true, subtree: true }
DOMNodeRemoved { childList: true, subtree: true }
DOMSubtreeModified { childList: true, subtree: true }
DOMAttrModified { attributes: true, subtree: true }
DOMCharacterDataModified { characterData: true, subtree: true }

從上表我們也可以看出相比與MutationEvent而言MutationObserver極大地增加了靈活性,可以設(shè)置各種各樣的選項來滿足程序員對目標(biāo)的觀察。

我們簡單看幾個例子:

target的第一個子節(jié)點

target的后代

1.callback的回調(diào)次數(shù)

var target=document.getElementById("target");
var i=0
var observe=new MutationObserver(function (mutations,observe) {
    i++   
});
observe.observe(target,{ childList: true});
target.appendChild(docuemnt.createTextNode("1"));
target.appendChild(docuemnt.createTextNode("2"));
target.appendChild(docuemnt.createTextNode("3"));
console.log(i)                //1

MutationObserver的callback回調(diào)函數(shù)是異步的,只有在全部DOM操作完成之后才會調(diào)用callback。

2.當(dāng)只設(shè)置{ childList: true}時,表示觀察目標(biāo)子節(jié)點的變化

var observe=new MutationObserver(function (mutations,observe) {
    debugger;
    console.log(mutations);
    //observe.discount();     
});

observe.observe(target,{ childList: true});
target.appendChild(document.createTextNode("新增Text節(jié)點"));   //增加節(jié)點,觀察到變化
target.childNodes[0].remove();                                //刪除節(jié)點,可以觀察到
target.childNodes[0].textContent="改變子節(jié)點的后代";             //不會觀察到

如果想要觀察到子節(jié)點以及后代的變化需設(shè)置{childList: true, subtree: true}

attributes選項用來觀察目標(biāo)屬性的變化,用法類似與childList,目標(biāo)屬性的刪除添加以及修改都會被觀察到。

3.我們需要注意的是characterData這個選項,它是用來觀察CharacterData類型的節(jié)點的,只有在改變節(jié)點數(shù)據(jù)時才會觀察到,如果你刪除或者增加節(jié)點都不會進行觀察,還有如果對不是CharacterData類型的節(jié)點的改變不會觀察到,比如:

observe.observe(target,{ characterData: true, subtree: true});
target.childNodes[0].textContent="改變Text節(jié)點";              //觀察到
target.childNodes[1].textContent="改變p元素內(nèi)容";              //不會觀察到
target.appendChild(document.createTextNode("新增Text節(jié)點"));  //不會觀察到
target.childNodes[0].remove();                               //刪除TEXT節(jié)點也不會觀察到

我們只需要記住只有對CharacterData類型的節(jié)點的數(shù)據(jù)改變才會被characterData為true的選項所觀察到。

4.最后關(guān)注一個特別有用的選項attributeFilter,這個選項主要是用來篩選要觀察的屬性,比如你只想觀察目標(biāo)style屬性的變化,這時可以如下設(shè)置:

observe.observe(target,{ attributeFilter: ["style"], subtree: true});
target.style="color:red";                      //可以觀察到
target.removeAttribute("name");                //刪除name屬性,無法觀察到 

disconnect方法是用來阻止觀察的,當(dāng)你不再想觀察目標(biāo)節(jié)點的變化時可以調(diào)用observe.disconnect()方法來取消觀察。

takeRecords方法是用來取出記錄隊列中的記錄。它的一個作用是,比如你對一個節(jié)點的操作你不想馬上就做出反應(yīng),過段時間在顯示改變了節(jié)點的內(nèi)容。

var observe=new MutationObserver(function(){});
observe.observe(target,{ childList: true});
target.appendChild(document.createTextNode("新增Text節(jié)點"));
var record = observe.takeRecords();              //此時record保存了改變記錄列表  
//當(dāng)調(diào)用takeRecords方法時,記錄隊列被清空因此不會觸發(fā)MutationObserver中的callback回調(diào)方法。
target.appendChild(document.createElement("span"));
observe.disconnect();                            //停止對target的觀察。
//MutationObserver中的回調(diào)函數(shù)只有一個記錄,只記錄了新增span元素

//之后可以對record進行操作
//...

MutationRecord
變動記錄中的屬性如下:

type:如果是屬性變化,返回"attributes",如果是一個CharacterData節(jié)點(Text節(jié)點、Comment節(jié)點)變化,返回"characterData",節(jié)點樹變化返回"childList"

target:返回影響改變的節(jié)點

addedNodes:返回添加的節(jié)點列表

removedNodes:返回刪除的節(jié)點列表

previousSibling:返回分別添加或刪除的節(jié)點的上一個兄弟節(jié)點,否則返回null

nextSibling:返回分別添加或刪除的節(jié)點的下一個兄弟節(jié)點,否則返回null

attributeName:返回已更改屬性的本地名稱,否則返回null

attributeNamespace:返回已更改屬性的名稱空間,否則返回null

oldValue:返回值取決于type。對于"attributes",它是更改之前的屬性的值。對于"characterData",它是改變之前節(jié)點的數(shù)據(jù)。對于"childList",它是null

其中 type、target這兩個屬性不管是哪種觀察方式都會有返回值,其他屬性返回值與觀察方式有關(guān),比如只有當(dāng)attributeOldValue或者characterDataOldValue為true時oldValue才有返回值,只有改變屬性時,attributeName才有返回值等。

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90787.html

相關(guān)文章

  • Vue源碼詳解之nextTick:MutationObserver只是浮云,microtask才是核

    摘要:后來尤雨溪了解到是將回調(diào)放入的隊列。而且瀏覽器內(nèi)部為了更快的響應(yīng)用戶,內(nèi)部可能是有多個的而的的優(yōu)先級可能更高,因此對于尤雨溪采用的,甚至可能已經(jīng)多次執(zhí)行了的,都沒有執(zhí)行的,也就導(dǎo)致了我們更新操 原發(fā)于我的博客。 前一篇文章已經(jīng)詳細記述了Vue的核心執(zhí)行過程。相當(dāng)于已經(jīng)搞定了主線劇情。后續(xù)的文章都會對其中沒有介紹的細節(jié)進行展開。 現(xiàn)在我們就來講講其他支線任務(wù):nextTick和micro...

    陳偉 評論0 收藏0
  • 什么是 HTML 5?

    摘要:該區(qū)域代表可以被所控制的畫布。那么現(xiàn)在第二個問題,識別該文檔,這或許不是大部分用戶的需求,但小部分用戶并不意味著人數(shù)少。因此一個基于的請求于標(biāo)準(zhǔn)內(nèi)提出。 前言 作為程序員,技術(shù)的落實與鞏固是必要的,因此想到寫個系列,名為 why what or how 每篇文章試圖解釋清楚一個問題。 這次的 why what or how 主題:現(xiàn)在幾乎所有人都知道了 HTML5 ,那么 H5 到底相...

    zhaofeihao 評論0 收藏0
  • VueJS源碼學(xué)習(xí)——MutationObserver實現(xiàn)nextTick

    摘要:倡導(dǎo)開發(fā)者盡量不直接操作,但有的時候由于各種需求讓開發(fā)者不得不這樣做,于是的實現(xiàn)就是讓開發(fā)者在修改數(shù)據(jù)后,能夠在數(shù)據(jù)更新到后才執(zhí)行對應(yīng)的函數(shù),從而獲取最新的數(shù)據(jù)。 Vue 倡導(dǎo)開發(fā)者盡量不直接操作 DOM,但有的時候由于各種需求讓開發(fā)者不得不這樣做,于是 nextTick 的實現(xiàn)就是讓開發(fā)者在修改數(shù)據(jù)后,能夠在數(shù)據(jù)更新到 DOM 后才執(zhí)行對應(yīng)的函數(shù),從而獲取最新的 DON 數(shù)據(jù)。 原文...

    xumenger 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<