使用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地址。

相关文章
相关标签/搜索