博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用MutationObserver监控dom树实现水印的不可删除属性。
阅读量:6418 次
发布时间:2019-06-23

本文共 3306 字,大约阅读时间需要 11 分钟。

MutationObserver 是一个观察对象,提供用来当DOM树发生变化时开发者可以根据发生的变化,进行逻辑的变化。

就像三体中的水滴一样,当地球上出现大型强子对撞研究时,会触发一定的逻辑来锁死地球的科学研究。

MutationObserver 有三个方法,分别是

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

主要说observe()方法,在实现水印不可删除的过程中,主要需要应对的逻辑有两个,第一种是对水印节点的修改,第二种是对水印节点的删除。

先说第一种,observe( Node target, optional MutationObserverInit options ),接受两个参数,第一个是目标节点,第二个是目标节点需要被监控的属性,包括属性,子节点,甚至所有后代节点都可以监控。

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的背景图片。

也就是说id为divContainer的div就是我需要监控的dom节点。这时我只需要

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的重绘。

第二种,因为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对象。
图片描述

可以看到MutationObserver()有一个takeRecords函数来纪录监控中所有节点增查删改的操作,并且返回到MutationRecord对象中。

图片描述

可以看到我执行了removeNode的操作并且被记录在了MutationRecord这个对象中。

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是一致的就可以进行下一步的重绘操作了。

这是github地址。

转载地址:http://gqpra.baihongyu.com/

你可能感兴趣的文章
git入门与实践【转】
查看>>
WPF 虚拟键盘
查看>>
储存卡无法打开专家教您怎么数据恢复
查看>>
彼得原理
查看>>
如何利用【百度地图API】,制作房产酒店地图?(下)——结合自己的数据库...
查看>>
[20171113]修改表结构删除列相关问题3.txt
查看>>
特征选择
查看>>
在Winform程序中设置管理员权限及为用户组添加写入权限
查看>>
RTMP直播到FMS中的AAC音频直播
查看>>
多能互补提速 加快我国能源转型和现代能源体系建设
查看>>
《JavaScript设计模式》——2.5 多种调用方式——多态
查看>>
Redis开发运维实践高可用和集群架构与实践(二)
查看>>
程序员的常见“谎话”:对,这是一个已知 Bug
查看>>
如何侦查SQL执行状态
查看>>
CentOS 7 命令行如何连接无线网络
查看>>
Ubuntu 12.04上享用新版本Linux的功能
查看>>
logstash + grok 正则语法
查看>>
Zimbra开源版(v8.6)安装说明
查看>>
Android性能优化之TraceView和Lint使用详解
查看>>
基于pgrouting的路径规划之一
查看>>