前端水印的实现方法总结

前端水印实现方法,这里有两种方式,希望对大家有帮助。

一、canvas添加水印

通过canvas生成base64图片,生成一个绝对定位的大小与body一样的div–waterDiv,将waterDiv的背景设置为canvas的base64图片,将waterDiv挂在到body下面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div style='height: 100vh; width: 100%; background-color: red;'></div>
  <div style='height: 100vh; width: 100%; background-color: yellow;'></div>
  <div style='height: 100vh; width: 100%; background-color: blue;'></div>
  <div style='height: 100vh; width: 100%; background-color: black;'></div>
</body>
<script>
  function createWaterMark({
    container = document.body,
    width = 200,
    height = 200,
    fillStyle = 'rgba(220,220,220)',
    rotate = '30',
    zIndex = 100,
    font = '20px',
    content = '水印',
  }) {
     // 生成canvas
    const canvas = document.createElement('canvas')
    // 设置宽高
    canvas.setAttribute('width', `${width}px`)
    canvas.setAttribute('height', `${height}px`)
    const ctx = canvas.getContext('2d')
    // 修改样式
    ctx.font = font
    ctx.fillStyle = fillStyle
    ctx.rotate((Math.PI / 180) * rotate)
    ctx.fillText(content, parseFloat(width) / 2, parseFloat(height / 2))
    // 转成base64
    const base64url = canvas.toDataURL()
    // 生成水印div容器
    const waterDiv = document.createElement('div')
    // 添加样式
    waterDiv.setAttribute('style', `
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: ${zIndex};
      background-repeat: repeat;
      background-image: url('${base64url}');
	  pointer-events: none;
    `)
    container.style.position = 'relative'
    container.insertBefore(waterDiv, container.firstChild)
  }
  createWaterMark({
    content: '这是水印'
  })
</script>
</html>

效果如下:

前端开发实现水印的方法

二、通过MutationObserver监听水印

需要注意的是,通过这种方法虽然可以动态生成水印,但是通过浏览器控制台可以轻易将waterDiv删除,所以还需要监听认为删除水印节点时间以及修改水印样式事件,通过MutationObderver可以实现该功能。

MutationObserver 是在DOM4中定义的,用于替代 mutation events 的新API,它的不同于events的是,所有监听操作以及相应处理都是在其他脚本执行完成之后异步执行的,并且是所以变动触发之后,将变得记录在数组中,统一进行回调的,也就是说,当你使用observer监听多个DOM变化时,并且这若干个DOM发生了变化,那么observer会将变化记录到变化数组中,等待一起都结束了,然后一次性的从变化数组中执行其对应的回调函数。

MutationObserver 的浏览器兼容范围。

方法

构造函数

用来实例化一个Mutation观察者对象,其中的参数是一个回调函数,它是会在指定的DOM节点发送变化后,执行的函数,并且会被传入两个参数,一个是变化记录数组(MutationRecord),另一个是观察者对象本身。

new MutationObserver(function(records, itself){});

observe

void observe(Node target, optional MutationObserverInit options)

其中的可选参数MutationObserverInit的属性如下:(需要使用的属性添加true即可)

  • childLIst:观察目标节点的子节点的新增和删除。
  • attributes:观察目标节点的属性节点(新增或删除了某个属性,以及某个属性的属性值发生了变化)。
  • characterData:如果目标节点为characterData节点(一种抽象接口,具体可以为文本节点,注释节点,以及处理指令节点)时,也要观察该节点的文本内容是否发生变化。
  • subtree:观察目标节点的所有后代节点(观察目标节点所包含的整棵DOM树上的上述三种节点变化)
  • attributeOldValue:在attributes属性已经设为true的前提下,将发生变化的属性节点之前的属性值记录下来(记录到下面MutationRecord对象的oldValue属性中)。
  • characterDataOldValue:在characterData属性已经设为true的前提下,将发生变化characterData节点之前的文本内容记录下来(记录到下面MutationRecord对象的oldValue属性中)
  • attributeFilter:一个属性名数组(不需要指定命名空间),只有该数组中包含的属性名发生变化时才会被观察到,其他名称的属性发生变化后会被忽略想要设置那些删选参数的话

disconnect

暂定在观察者对象上设置的节点的变化监听,直到重新调用observe方法。

使用Mutation Observer监听水印

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div style='height: 100vh; width: 100%; background-color: red;'></div>
  <div style='height: 100vh; width: 100%; background-color: yellow;'></div>
  <div style='height: 100vh; width: 100%; background-color: blue;'></div>
  <div style='height: 100vh; width: 100%; background-color: black;'></div>
</body>
<script>
  function createWaterMark({
    container = document.body,
    width = 200,
    height = 200,
    fillStyle  = 'rgba(220,220,220)',
    rotate = '30',
    zIndex = 1000,
    font = '20px microsoft yahei',
    content = '水印',
  }) {
    // 生成canvas
    const canvas = document.createElement('canvas')
    // 设置宽高
    canvas.setAttribute('width', `${width}px`)
    canvas.setAttribute('height', `${height}px`)
    const ctx = canvas.getContext('2d')
    // 修改样式
    ctx.font = font
    ctx.fillStyle  = fillStyle 
    ctx.rotate((Math.PI / 180) * rotate)
    ctx.fillText(content, parseFloat(width) / 2, parseFloat(height / 2))
    // 转成base64
    const base64url = canvas.toDataURL()
    const waterDiv = document.getElementById('waterDiv') || document.createElement('div')
    waterDiv.setAttribute('id', 'waterDiv')
    const style = `
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: ${zIndex};
      background-repeat: repeat;
      background-image: url('${base64url}');
      pointer-events: none;
    `
    // 添加样式
    waterDiv.setAttribute('style', style)
    // 修改父亲节点为相对定位
    container.style.position = 'relative'
    container.insertBefore(waterDiv, container.firstChild)
    const MutationObserver = window.MutationObserver || window.WebKitMutationObserver
    if (MutationObserver) {
      let handle = new MutationObserver(function() {
        const waterDiv = document.getElementById('waterDiv')
        // 触发修改时间后添加判断,符合条件时间才重新生成水印
        if ((waterDiv && waterDiv.getAttribute('style') !== style) || !waterDiv) {
          // 断开连接
          handle.disconnect();
          // 将函数置为空
          handle = null;
          // 重新调用函数
          createWaterMark({
            container,
            width,
            height,
            fillStyle,
            rotate,
            zIndex,
            font,
            content,
          })
        }
      })
      // 监听body
      handle.observe(container, {
      attributes: true,
      subtree: true,
      childList: true
    })
    }
  }
  createWaterMark({
    content: '码云笔记'
  })
</script>
</html>

结语

以上就是码云笔记分享的前端水印实现方法,希望对大家有帮助,感谢阅读。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有资源及文章均来源于网络及用户分享或为本站原创,仅限用于学习和研究,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 前端水印的实现方法总结

发表评论

IT互联网行业相关广告投放 更专业 更精准

立即查看 联系我们