前端页面填加水印方案及实现

前端页面填加水印方案及实现

一、背景

最近有个项目需要在页面上加上水印。这里尝试了一个实现方案。

二、实现

1.利用canvas绘制水印信息

   var can = document.createElement('canvas');
    can.width = 250;
    can.height = 150;
    var cans = can.getContext('2d');
    cans.rotate(-20 * Math.PI / 180);
    cans.font = '17px Vedana';
    // ziti yanse
    cans.fillStyle = 'rgba(200, 200, 200, 0.30)';
    cans.textAlign = 'left';
    cans.textBaseline = 'Middle';
    cans.fillText("水印数据", xIndex , yIndex); //绘制水印文案
}
复制代码

2.页面展示水印

  • 将图片转为dataURL(base64)
canvas.toDataURL('image/png') 
复制代码
  • 创建一个div用于展示
var div = document.createElement('div');
div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat';
复制代码

left top repeat属性表示背景图像将从left,top开始向垂直和水平方向重复。

3.利用MutationObserver监听DOM树结构的变化

利用MutationObserver监听DOM树结构的变化,防止水印被人为去掉

function createObserver(id,args){
// 创建一个观察器实例并传入回调函数
var observer = new MutationObserver(()=>{
        if (document.getElementById(id) === null) {
            id = setWatermark(args);
        }});

var option = {
  'childList': true,//子元素的变动
  'subtree': true//所有下属节点(包括子节点和子节点的子节点)的变动
};

observer.observe(document.body, option);//观察body下节点的变化
}
复制代码

三、完整代码

var watermark = {}

function setWatermark(args) {
 console.log(...arguments)
	//声明一个怪异一点的变量,确保id的唯一性
    var id = '111.222.333.456';
    var xIndex = 15;//绘制文本的 x 坐标位置
    var yIndex = 65;//绘制文本的 y 坐标位置
    var xInterval = 25//有多个参数时的行间间隔
    if (document.getElementById(id) !== null) {
        document.body.removeChild(document.getElementById(id));
    }
	//利用canvas绘制水印信息
    var can = document.createElement('canvas');
    can.width = 250;
    can.height = 150;
    var cans = can.getContext('2d');
    cans.rotate(-20 * Math.PI / 180);
    cans.font = '17px Vedana';
    // ziti yanse
    cans.fillStyle = 'rgba(200, 200, 200, 0.30)';
    cans.textAlign = 'left';
    cans.textBaseline = 'Middle';
    for(let i = 0;i<args.length;i++){
    	cans.fillText(args[i], xIndex , yIndex); //绘制水印文案
    	yIndex+=xInterval ;//设置每行间隔
}
//创建div用于显示
    var div = document.createElement('div');
    div.id = id;
    div.style.pointerEvents = 'none';
    div.style.top = '70px';
    div.style.left = '90px';
    div.style.position = 'fixed';
    div.style.zIndex = '100000';
    div.style.width = document.documentElement.clientWidth - 50 + 'px';
    div.style.height = document.documentElement.clientHeight - 50 + 'px';
    //div承载水印显示
    div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat';
    document.body.appendChild(div);
    return id;
}

function createObserver(id,args){
// 创建一个观察器实例并传入回调函数
var observer = new MutationObserver(()=>{
        if (document.getElementById(id) === null) {
            id = setWatermark(args);
        }});

var option = {
  'childList': true,//子元素的变动
  'subtree': true//所有下属节点(包括子节点和子节点的子节点)的变动
};

observer.observe(document.body, option);//观察body下节点的变化
}

watermark.set = function(){
	let args =Array.prototype.slice.apply(arguments);
    let id = setWatermark(args);

    // 创建观察器检测如果水印被去掉了,自动给加上
    createObserver(id,args);

    //在窗口大小改变之后,自动触发加水印事件
    window.onresize = function(){
        setWatermark(args);
    }
}
window.watermark = watermark;
复制代码

四、调用

  • 将代码写到watermark.js文件里,
  • 再引入
  • 调用
watermark.set("水印信息1","我是水印信息2",...);
复制代码

支持多个参数,传多个参数时,将分行展示。 在这里插入图片描述

<script src="/watermark.js"></script>

......

<script>
window.onload = function(){
  //添加水印
    watermark.set("水印数据");
}
</script>
</body>
复制代码

当然,该方法也可以直接写在页面js里面。

注意: 执行添加水印的操作尽量往后放,反正</body>标签之前就行, 防止DOM还没加载完的情况出现。

五、验证

打开一个页面,控制台执行代码

  1. 在window上添加绘制水印的方法
  2. 执行添加水印

效果如图: 在这里插入图片描述

分类:
前端
标签: