使用MutationObserver監控dom樹實現水印的不可刪除屬性。

https://developer.mozilla.org...

MutationObserver 是一個觀察對象,提供用來當DOM樹發生變化時開發者能夠根據發生的變化,進行邏輯的變化。
就像三體中的水滴同樣,當地球上出現大型強子對撞研究時,會觸發必定的邏輯來鎖死地球的科學研究。git

MutationObserver 有三個方法,分別是

  • observe( Node target, optional MutationObserverInit options );
  • disconnect();
  • takeRecords();

主要說observe()方法,在實現水印不可刪除的過程當中,主要須要應對的邏輯有兩個,第一種是對水印節點的修改,第二種是對水印節點的刪除。
先說第一種,observe( Node target, optional MutationObserverInit options ),接受兩個參數,第一個是目標節點,第二個是目標節點須要被監控的屬性,包括屬性,子節點,甚至全部後代節點均可以監控。github

drawCanvas() {

        let divContainer = document.body.appendChild(document.createElement('div'));
        let waterMarkercanvas = document.createElement('canvas');
        let context = waterMarkercanvas.getContext('2d');

        divContainer.appendChild(waterMarkercanvas);
        divContainer.id = 'divContainer'
        let backgroundUrl = null;

        divContainer.style.height = window.innerHeight + 'px';
        divContainer.style.width = window.innerWidth + 'px';


        waterMarkercanvas.width = this.option.canvasWidth;
        waterMarkercanvas.height = this.option.canvasHeight;



        context.font =this.option.font;
        context.textAlign = this.option.textAlign;
        context.fillStyle = this.option.textStyle;
        context.translate(waterMarkercanvas.width / 2,waterMarkercanvas.height / 2);
        context.rotate(this.option.degree * Math.PI / 180);
        context.fillText(this.option.text, 0, 0);

        backgroundUrl = waterMarkercanvas.toDataURL('image/png');
        divContainer.style.backgroundImage = `url(${backgroundUrl})`;


    }

在上面的代碼裏,我首先canvas畫出來以後,轉爲png格式的圖片,最後設置成了div的背景圖片。canvas

也就是說id爲divContainer的div就是我須要監控的dom節點。這時我只須要app

canvasObserver() {
        this.drawCanvas();
        let canvasObserver = new MutationObserver((mo) => {
            this.drawCnvas();
        });
        let config = { attributes: true, childList: true, characterData: true };
        console.log

        canvasObserver.observe(document.querySelector('#divContainer'), config);
    }

就能夠實如今用戶修改divContainer這個節點是實現canvas的重繪。dom

第二種,由於MutationObserver本山來說,是不支持監控本自己節點的刪除操做的,也就是說,我若是刪除了divContainer這個節點,是沒法實現canvas的重繪的。
那麼,這時就須要到一個新的辦法了,那就是監控body節點函數

canvasObserver() {
        this.drawCanvas();
        let canvasObserver = new MutationObserver((mo) => {
            console.log(mo.removeNodes)
            // this.drawCanvas();
            // console.log('detect canvas change and redraw')
        });
        let config = { attributes: true, childList: true, characterData: true };
        console.log

        canvasObserver.observe(document.querySelector('#divContainer').parentNode, config);
    }

由於在第一段代碼中,咱們把該節點做爲了body節點的子節點,若是該節點變化,body節點的水滴確定能夠檢測到,而且完成重繪。由於在咱們的開發中,body節點承載着全部的頁面內容,若刪除body節點那麼也就沒有水印的意義了。
這時須要一個就須要一個MutationObserver()中的一個MutationRecord對象。
圖片描述this

能夠看到MutationObserver()有一個takeRecords函數來紀錄監控中全部節點增查刪改的操做,而且返回到MutationRecord對象中。
圖片描述url

能夠看到我執行了removeNode的操做而且被記錄在了MutationRecord這個對象中。spa

canvasObserver() {
        this.drawCanvas();
        let canvasObserver = new MutationObserver((mo) => {
            console.log(mo[0].removedNodes)
            // this.drawCanvas();
            // console.log('detect canvas change and redraw')
        });
        let config = { attributes: true, childList: true, characterData: true };
        console.log

        canvasObserver.observe(document.querySelector('#divContainer').parentNode, config);
    }

這是修改後的代碼,咱們只要匹配一個被刪除的div和canvas的div是一致的就能夠進行下一步的重繪操做了。code

https://github.com/AplloBattl...

這是github地址。

相關文章
相關標籤/搜索