我是靠谱客的博主 阔达可乐,最近开发中收集的这篇文章主要介绍前端使用水印的代码实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

第一点

很好实现。我们create一个dom元素,插入到body中就可以了。

 const divObj = document.createElement('div');
const styleStr = `
position:fixed;
top:0;
left:0;
bottom:0;
right:0;
z-index:999999;
background-repeat:repeat;
`;
divObj.setAttribute('style', styleStr);
document.body.appendChild(divObj);

第二点

水印的内容我们从cookie中获取一下。

 const user = /user_name=([^;]+)/.exec(document.cookie);
const name = Array.isArray(user) && user.length === 2 && user[1] ? user[1] : '配置的水印';

第三点

这两个综合考虑的话,将name作为一个背景图 然后repeat就可以了。我们要将文字转为图片,那么canvas是一个不错的选择。同时我们要考虑到这个图片不易过大(为了符合第三点),所以我们就按照100*100的尺寸吧。


const canvasObj = document.createElement('canvas');
const canvas2d = canvasObj.getContext('2d');
canvasObj.width = 100;
canvasObj.height = 100;
canvas2d.font = fontSize + 'px Arial';
canvas2d.fillStyle = 'rgba(128,128,128,.6)'; // 这里文字的颜色淡一点,不要影响整体的美观
canvas2d.translate(canvasObj.width / 4, canvasObj.height / 2);
canvas2d.rotate((-30 / 180) * Math.PI);
canvas2d.fillText(name, 0, canvasObj.height / 2);
// 将canvas 转为 dataURL
const base64Url = canvasObj.toDataURL('image/png');

第四点

要有防窜改的功能,具体要体现在我们创建的水印不能轻易的让别人给删了,其次,水印内容也不能轻易的被改了,无论是水印内容或者是水印的颜色样式等。

水印内容这一块因为我们使用的是cookie中的登录信息,如果有人更改了cookie中的值,会导致登录信息失效,在sso这一侧就会被强制跳转到登录页面,所以这个可以交由登录系统来做。

我们的dom不能轻易的被删除和更改样式,那么我们就需要用到 MutationObserver 这个api了,他的作用就是监听DOM的变化,并触发一个回调,我们只需在回调中重新执行水印的方法就可以避免这个问题。


if (MutationObserver) {
let waterMarkOb = new MutationObserver(function () {
const _globalWatermark = document.querySelector(`domId`);
// 当样式或者水印元素dom节点有改动时会重新绘制
if (
(_globalWatermark && _globalWatermark.getAttribute('style') !== styleStr) ||
!_globalWatermark
) {
waterMarkOb.disconnect();
waterMarkOb = null;
setWaterMark();
}
});
// 指定观察对象
waterMarkOb.observe(document.body, {
attributes: true,
subtree: true,
childList: true,
});
}

最后一点

注意事项中有一点,就是我们的水印功能尽可能的不要影响到业务的使用。 所以这里我们要考虑两点:

1. 我们的水印dom在全屏幕的最上层,虽然层级在99999,但是也不要要影响到下面的元素操作。所以我们需要增加pointer-events:none 的属性,不影响鼠标的操作。

2. 我们要在前端代码不变动的情况下上线水印的功能,那我们就要从服务器上入手了,比如在nginx中,我们可以使用 sub_filter 模块来替换返回的文本。例如

 subs_filter "(</body>)" "$1<script src="https://cdn.xxx.com/watermark.js"></script>" irg;

整体代码

!(function () {
// 一个配置
const options = {
id: 'globalWaterMark',
fontSize: 10,
color: 'rgba(128,128,128,.6)',
rotate: '-30',
userName: "其他的身份"
};
/**
* 创建水印图片url
*/
function createWaterMark() {
const { fontSize, color, id } = options;
const user = /user_name=([^;]+)/.exec(document.cookie);
const name = Array.isArray(user) && user.length === 2 && user[1] ? user[1] : options.userName;
const canvasObj = document.createElement('canvas');
const canvas2d = canvasObj.getContext('2d');
canvasObj.width = 200;
canvasObj.height = 100;
canvas2d.font = fontSize + 'px Arial';
canvas2d.fillStyle = color;
canvas2d.translate(canvasObj.width / 4, canvasObj.height / 2);
canvas2d.rotate((-30 / 180) * Math.PI);
canvas2d.fillText(name, 0, canvasObj.height / 2);
// 将canvas 转为 dataURL
const base64Url = canvasObj.toDataURL('image/png');
return base64Url;
}
function setWaterMark() {
const { fontSize, color, id } = options;
const url = createWaterMark();
const target = document.getElementById(id);
if(target){
document.body.removeChild(target)
}
const divObj = document.createElement('div');
divObj.id = options.id;
const styleStr = `
position:fixed;
top:0;
left:0;
bottom:0;
right:0;
z-index:999999;
background-repeat:repeat;
pointer-events:none;
background-image:url('${url}')`;
divObj.setAttribute('style', styleStr);
document.body.appendChild(divObj);
// 监听DOM变动
const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
if (MutationObserver) {
let waterMarkOb = new MutationObserver(function () {
const _globalWatermark = document.querySelector(`#${id}`);
// 当样式或者水印元素dom节点有改动时会重新绘制
if (
(_globalWatermark && _globalWatermark.getAttribute('style') !== styleStr) ||
!_globalWatermark
) {
waterMarkOb.disconnect();
waterMarkOb = null;
setWaterMark();
}
});
// 指定观察对象
waterMarkOb.observe(document.body, {
attributes: true,
subtree: true,
childList: true,
});
}
}
document.addEventListener('DOMContentLoaded', function () {
setWaterMark();
});
})();

最后

以上就是阔达可乐为你收集整理的前端使用水印的代码实现的全部内容,希望文章能够帮你解决前端使用水印的代码实现所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部