HTML5 MutationObserver檢測頁面劫持

很久沒寫博客了,業務一直在變化,陸陸續續的作了不少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元素是否發生了變化,而後給出通知。數組

Constructor

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();
相關文章
相關標籤/搜索