添加水印class封装

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; // 初始化,默认绑定body
      this[_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'); // 修改水印的文本

 

posted @ 2025-11-03 10:49  你风致  阅读(4)  评论(0)    收藏  举报