MutationObserver使用來監測某個範圍內DOM的變更,如節點的增減、屬性的變更,文本節點的變化等。至關於DOM的改變就會觸發MutationObserver這個事件,可是這個事件是異步觸發的,會把DOM的變更封裝成一個數組進行統一更新的,這點和react中的setState很是相像。css
var observer = new MutationObserver(function (mutations, observer) {
mutations.forEach(function(mutation) {
console.log(mutation);
});
})
複製代碼
在調用時,觀察者對象會傳給該函數兩個參數:html
MutationObserver接受一個callback參數,用來處理節點變化的回調函數,返回兩個參數,mutations和observer。react
mutations:節點變化記錄列表git
observer:MutationObserver的實例對象。github
MutationObserver對象有三個方法,分別以下:web
observe:設置觀察目標,接受兩個參數,target:觀察目標,options:經過對象成員來設置觀察選項canvas
disconnect:阻止觀察者觀察任何改變數組
takeRecords:清空記錄隊列並返回裏面的內容promise
observe方法中經常使用的options參數有已下幾個選項:瀏覽器
childList:設置true,表示觀察目標子節點的變化,好比添加或者刪除目標子節點,不包括修改子節點以及子節點後代的變化
attributes:設置true,表示觀察目標屬性的改變
characterData:設置true,表示觀察目標數據的改變
subtree:設置爲true,目標以及目標的後代改變都會觀察
如今有一個id爲target的節點
<div id='target' class='block'>
</div>
複製代碼
對該dom進行監聽並測試
var target=document.getElementById('target');
var i=0
var observe=new MutationObserver(function (mutations,observe) {
i++
});
observe.observe(target,{ childList: true});
target.appendChild(docuemnt. createElement ('span'));
target.appendChild(docuemnt. createElement ('div'));
console.log(i) //1
複製代碼
初始思路:使用MutationObserver監聽整個頁面,每當有頁面變更,則將頁面的html轉換成圖片進行隊列存儲,回放用戶操做即不停從隊列中取出元素展現
這裏咱們直接使用html2canvas這個第三方庫官方地址,基於html2canvas.js可將一個元素渲染爲canvas,只須要簡單的調用html2canvas(element[, options]),下列html2canvas方法會返回一個包含有canvas元素的promise:
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});
複製代碼
上一步生成的canvas即爲包含目標元素的canvas元素對象。實現保存圖片的目標只須要將canvas轉image便可。經過canvas的toDataURL方法將canvas輸出爲data: URI類型的圖片base64地址,再將該圖片地址賦值給元素的src屬性便可。
<canvas id="canvas" width="5" height="5">
</canvas>
複製代碼
獲取該圖片,直接能夠用toDataURL轉成圖片,默認爲 PNG 格式
var canvas = document.getElementById("canvas");
var dataURL = canvas.toDataURL();
console.log(dataURL);
// "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby...
複製代碼
最後,經過定時器將img不停的插入到img標籤的src中,實現回放的效果。
Canvas在高分屏中繪製圖片會有模糊的效果,其實不僅是繪製圖片時會出現模糊的問題,高清屏的設備中任何繪製在 canvas 中的圖形(包括文字)都會出現模糊的問題。
這是由於HIDPI的屏幕上的像素其實是邏輯像素,咱們若是當成正常的像素(css中設置的像素)使用它,如咱們在css中設置100px時,在例如iphone4S(devicePixelRatio爲2)上,實際渲染的是200px的物理像素。因此當咱們向這種高分辨率的屏幕添加img的時候,咱們的圖像及其餘一些圖形文字都會受到devicePixelRatio的影響會變得模糊。
解決方法很簡單,就是將 canvas 的高和寬分別乘以 devicePixelRatio將其放大,而後又用 CSS 將高和寬限制成初始的大小。
這裏爲了簡化操做,作捉了兩個按鈕作添加和刪除元素,實際狀況中,不只須要對dom節點的操做進行監聽,例如用戶的點擊、停留、軌跡等行爲數據都須要進行採集分析。
在Web中, 圖形圖像的操做以及存儲會消耗大量的性能, 經過使用html快照來替代圖像快照能夠大幅的提升性能以達到生成可用狀態,可是須要作不少的處理,當咱們存儲的是html的快照鏈時,想要在客戶端進行用戶操做回放,咱們須要構建沙盒環境對html從新進行渲染,有一些工具如parse5能夠進行html的序列化和解析操做,「視頻回放」其實就是 HTML DOM 的變化增量及快照。
在html的解析過程當中須要要對dom快照進行一點的處理,如:
禁止表單提交
禁止跳轉、window.open等操做
js腳本的執行(由於咱們只是須要dom結構的變化)等
瀏覽器端存必定量的增量快照後再一塊兒發送到服務端,減小網絡開銷;也包括屢次增量以後再進行一次全量,對齊真實狀態。
數據脫敏
經過 DocumentFragment 提升平臺回放效率。
能夠參考開源方案RRWeb:github.com/rrweb-io/rr…
捕捉長按的操做,而後經過咱們上面的,實現轉canvas轉img的操做
記錄用戶的每次的dom操做放到一個棧中,每次用戶觸發撤銷操的時候從棧中取出一個元素,能夠還原上次的dom結構,從而實現了撤銷的操做
例如根據文本內容是否超出來動態控制是否顯示Tooltip,文本末尾顯示其餘內容等