const _x = Symbol('x')
const _body = Symbol('body')
const _base64Url = Symbol('base64Url')
class Watermark {props: any;// targetNode: HTMLElement | null;// base64Url: string;// bodyWapper: any;// observerData: Array<any>;
constructor(props) {this.props = props;this[_base64Url] = '';this[_body] = document.body; // 初始化,默认绑定bodythis[_x ] = []}/*** @description: 增加水印* @param {HTMLElement} wapper 包裹水印的父元素,传null时,默认body* @param {string} userName 水印显示的文本* @return {*}*/ add = (wapper, userName) => {if (wapper) {this[_body] = wapper;}this.creatImg(userName);this.addDom();this._mutationObserve();};addDom = () => {const targetNode = document.createElement('div');targetNode.setAttribute('class','info');targetNode.id = '__water-mark';targetNode.style.position = 'fixed';targetNode.style.left = '0';targetNode.style.top = '0';targetNode.style.width = '100vw';targetNode.style.height = '100vh';targetNode.style.background = `url(${this[_base64Url]}) repeat`;targetNode.style.opacity = '.5';targetNode.style.zIndex = '3000';targetNode.style.pointerEvents = 'none';this[_body] && this[_body].append(targetNode);}creatImg = (userName) => {const cavansDom: any = document.createElement('CANVAS');const ctx = cavansDom.getContext('2d');cavansDom.width = 110;cavansDom.height = 80;ctx.rotate((-20 * Math.PI) / 180);ctx.font = '13px Georgia';if (this.props.color) {ctx.fillStyle = this.props.color;} else {ctx.fillStyle = '#e6e3e3';}if (userName) {ctx.fillText(`${userName}`, 20, 50);} else {ctx.fillText('测试文字', 20, 50);}this[_base64Url] = cavansDom.toDataURL('image/png');}/*** @description: 更换水印文本* @param {string} userName* @return {*}*/ change = (userName) => {this.remove()this.add(null, userName)}/*** @description: 去除水印* @param {** @return {*}*/ remove = () => {const targetNode = document.getElementById('__water-mark')if (!targetNode) {return}this[_x ][0].disconnect()this[_x ][1].disconnect()this[_x ] = []this[_body].remove(targetNode);}_mutationObserve = () => {// 禁止修改水印节点const config = {childList: true,attributes: true,characterData: true,subtree: true,attributeOldValue: true,characterDataOldValue: true,};const mutationCallback = (mutationList) => {console.log(mutationList);for (const mutation of mutationList) {const type = mutation.type;console.log(type);switch (type) {case 'attributes':const targetNode = document.getElementById('__water-mark')if (mutation.attributeName === 'style' && targetNode) {targetNode.style.position = 'fixed';targetNode.style.left = '0';targetNode.style.top = '0';targetNode.style.width = '100vw';targetNode.style.height = '100vh';targetNode.style.background = `url(${this[_base64Url]}) repeat`;targetNode.style.opacity = '.5';targetNode.style.zIndex = '3000';targetNode.style.pointerEvents = 'none';}console.log(`${mutation.attributeName}属性修改了`);break;default:break;}}};const mutationCallback1 = (mutationList) => {console.log(mutationList);for (const mutation of mutationList) {const type = mutation.type;console.log(mutation);switch (type) {case 'childList':if (mutation.removedNodes.length > 0) {mutation.target.append(mutation.removedNodes[0])}console.log('节点被删除或添加');break;case 'subtree':console.log('子树被修改');break;default:break;}}};// 创建 MutationObserver 实例this[_x ][0] = new MutationObserver(mutationCallback);// 开始监控目标节点const targetNode = document.getElementById('__water-mark')this[_x ][0].observe(targetNode, config);// 创建 MutationObserver 实例this[_x ][1] = new MutationObserver(mutationCallback1);// 开始监控目标节点this[_x ][1].observe(this[_body], config);// 停止监控// observer.disconnect()
};}export default Watermark;
使用方式:
const wapper = document.getElementById('xxx') // 包裹水印的父元素,如果传递的不是dom对象,默认body
const userName = 'xxx' // 要显示的水印文本,必须传字符串
Watermark.add(wapper, userName);//Watermark.remove(); // 谨慎调用
Watermark.change('xxx'); // 修改水印的文本