很久沒寫博客了,業務一直在變化,陸陸續續的作了不少web app,被業務流淹沒就不多有機會去反思,前端技術發展如此之快,經常有種不學則退的恐慌,一種技術還沒吃透就涌出新的技術,而後一波人又打着各類旗幟去宣傳,想偷懶都不行,大腦徹底不夠用。html
Nodejs,AngularJS,vuejs,React,grunt,gulp,webpack...Fuck!前端
HTML5的水很深很深,感受還有不少技術沒有挖掘和使用。無心中發現HTML5 DOM4級MutatioObserver方法,能夠檢查頁面中的DOM是否發生變化,說到這也許你們知道能夠用來幹嗎了。vue
確實,前段時間咱們遇到了web app被運營商劫持的問題,不清楚哪一個環節出了問題,換了https按理說應該不會再出現,後來想到用相似GA統計的方式去統計頁面是否被注入了js腳本或者iframe,而後經過日誌去查看異常問題。webpack
劫持問題無非就是頁面被修改了,DOM結構發生變化了被插入了小廣告。看到MutatioObserver方法有種豁然開朗的感受,雖然不能解決被劫持的問題,可是也能查看被注入了什麼,也算漲了見識。web
概述gulp
MutationObserver從字面上含義就是發現突變。它能夠監聽頁面的DOM元素是否發生了變化,而後給出通知。數組
MutationObserver()
new MutationObserver(callback)
callback,當每次DOM發生變化的時候都會觸發callback,你們也許就會問,那要是頻繁修改dom,那這個callback就會頻繁觸發,性能上怎麼辦?實際上,MutationObserver並非每次dom發生變化的時候當即觸發,仍是等全部的dom操做完成以後一次執行,也就是說它是異步的。app
舉個栗子:dom
<body> <ul id="container"></ul> </body>
var callback=function(){ console.log("Dom changed"); }; var mutationObserver=new MutationObserver(callback); var otpions={ subtree:true, childList:true }; mutationObserver.observe(document.body,otpions); window.onload=function(){ for(var i=0;i<10;i++){ var li=document.createElement("li"); li.innerText="這是"; document.getElementById("container").appendChild(li); } };
http://jsbin.com/nimilelote/edit?html,js,console,output異步
咱們像DOM元素中插入了10次,實際上oberve只執行了一次,是在全部的dom操做完成以後觸發的。
mutationObserver實例有三個方法。
observe(target,options) //給制定的DOM註冊一個事件,若是DOM發生變化就會發送通知。target是目標元素,好比body,options是配置哪寫dom發生變化時才發送通知
disconnect(); //終止監聽DOM變化,直到從新實例化
takeRecords() //清除變更記錄,即再也不監聽還沒發生的DOM變化
observe實例化配置:
childList:設置爲true表示監聽指定元素的子元素的變更;
attributes:設置爲true表示監聽指定元素的屬性的變更;
characterData:設置爲true表示監聽指定元素的data變更;
subtree:設置爲true表示不緊監聽目標元素也同時監聽其子元素變更;
attributeOldValue:在attributes
屬性已經設爲true的前提下,若是須要將發生變化的
屬性節點以前的屬性值記錄下來(記錄到下面MutationRecord對象的oldValue屬性中),則設置爲true;
characterDataOldValue:在characterData
屬性已經設爲true的前提下,若是須要將發生變化的
characterData
節點以前的
文本內容記錄下來(記錄到下面MutationRecord對象的oldValue屬性中),則設置爲true
.
attributeFilter:一個屬性名數組(不須要指定命名空間),只有該數組中包含的屬性名發生變化時纔會被觀察到,其餘名稱的屬性發生變化後會被忽略.
// Firefox和Chrome早期版本中帶有前綴 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver // 選擇目標節點 var target = document.querySelector('#some-id'); // 建立觀察者對象 var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation.type); }); }); // 配置觀察選項: var config = { attributes: true, childList: true, characterData: true } // 傳入目標節點和觀察選項 observer.observe(target, config); // 隨後,你還能夠中止觀察 observer.disconnect();