需求
PC端和小程序页面需要水印,水印内容是用户名+电话后四位。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 水印通过变量进行赋值,登录成功后,将用户名及手机号后四位拼接。
  2. 均匀平铺在页面上,通过文章发现有三种方案,分别是:div/css、canvas、svg。
  3. 还有明水印、暗水印的区分及破解。
  1. 除了登录页,其余页面都要展示水印。
  2. 点击系统右上角的退出按钮,退出到登录页后,登录页存在水印。
  3. token失效后,跳转登录页,登录页存在水印。
  4. 登录成功到首页后,点击菜单切换后,点击退出按钮,登录页存在水印。
  5. 如果想实现某个页面不显示水印、某个抽屉显示水印,这种效果。

解决方案:

  1. 登录成功后才会走layout,所有的页面都是在layout的基础上渲染的,把水印相关的方法写在这里就不会一刷新水印就消失了。
  2. 点击退出按钮,退出到登录页的时候,移除dom节点。由于退出按钮在navBar组件里,每一个页面也都有navBar,直接将生成水印的方法写在navBar组件里。在登录成功渲染navBar的时候,创建dom节点承载水印内容 this.waterWrapper = document.createElement('div') ,在点击退出的时候给退出按钮绑定事件,移除创建的dom节点 document.body.removeChild(this.waterWrapper)
  3. 一种方法是把创建的div保存在vuex中,token失效的时候remove;另一种方法是给创建的div一个唯一id,通过 document.getElementById('watermark') 获取,并 removeChild 移除该div。
  4. 该项目有一个全屏展示,登录成功的home页没有左侧的二级菜单,是个全屏展示的图表页面。通过打开设置发现,当点击退出到登录页的时候该div节点依然存在,退出及token失效都已做了清除操作,为什么还会出现节点未清除的情况?
    通过尝试发现:如果一登录到首页就点击退出,此时登录页没有水印;如果点击菜单跳转了别的路由页面,此时去点退出,登录页是有水印的。
    判断:登录成功进入到navBar页面生成水印,首页是单独的一个全屏页面,在首页和头部一级菜单切换的时候,每次都会重新创建navBar,所以切换了路由再退出,就相当于又创建了一次水印节点,那么其实是因为创建了多次,只移除了一次,导致登录页存在水印。
    所以每次创建之前先看看之前是否有创建过,有的话就删掉。
  5. 比较麻烦,就不能写在全局的载体上了,需要把生成水印的相关方法封装成公用的方法,把移除方法也封装起来;需要显示水印的载体不同的话,还要把body改了,比如在一个抽屉显示水印的话就得加在抽屉的最外层的div上。

Navbar

<script>
	export default {
		mounted () {
		    var watermark1 = document.getElementById('watermark')
		    // 在创建新的水印节点之前,先判断有没有,有的话删掉
		    if (watermark1) document.body.removeChild(watermark1)
		    const waterWrapper = document.createElement('div')
		    waterWrapper.id = 'watermark'
		    this.cssHelper(waterWrapper, {
		      position: 'fixed',
		      top: '0px',
		      right: '0px ',
		      bottom: '0px',
		      left: '0px',
		      overflow: 'hidden',
		      display: 'flex',
		      'flex-wrap': 'wrap',
		      'pointer-events': 'none'
		    // 宽高值越小,水印越密集
    		// 宽高值越大,水印越稀疏
		    const waterHeight = 200
		    const waterWidth = 200
		    const { clientWidth, clientHeight } = document.documentElement || document.body
		    const column = Math.ceil(clientWidth / waterWidth)
		    const rows = Math.ceil(clientHeight / waterHeight)
		    for (let i = 0; i < column * rows; i++) {
		      const wrap = document.createElement('div')
		      this.cssHelper(wrap, Object.create({
		        position: 'relative',
		        width: `${waterWidth}px`,
		        height: `${waterHeight}px`,
		        flex: `0 0 ${waterWidth}px`,
		        overflow: 'hidden'
		      }))
		      wrap.appendChild(this.createItem())
		      waterWrapper.appendChild(wrap)
		    document.body.appendChild(waterWrapper)
	methods: {
    cssHelper (el, prototype) {
      for (let i in prototype) {
        el.style[i] = prototype[i]
    createItem () {
      const item = document.createElement('div')
      // item.innerHTML = '张三' + '7788'
      item.innerHTML = this.$store.state.user.userInfo.loginName + this.$store.state.user.userInfo.phone.substr(-4)
      // 水印样式
      // opacity 透明度
      // color  字体颜色
      // transform  旋转角度
      // top  距离顶部的距离
      // left 距离左侧的距离
      this.cssHelper(item, {
        position: 'absolute',
        top: `100px`,
        left: `50px`,
        fontSize: `16px`,
        color: '#080808',
        lineHeight: 1.5,
        opacity: 0.1,
        transform: `rotate(-15deg)`,
        transformOrigin: '0 0',
        userSelect: 'none',
        whiteSpace: 'nowrap',
        overflow: 'hidden'
      return item
    // 退出登录
    exit () {
      this.$confirm('确定退出吗?', '退出登录', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 退出的时候移除水印节点
        var watermark = document.getElementById('watermark')
        document.body.removeChild(watermark)
        // 让左侧菜单在退出的时候重置为首页
        this.$store.commit('user/SET_HOMEIMG', 2)
        this.$store.commit('user/CHANGE_MENU', 0)
        this.$store.commit('user/SET_CURRENT_SYS', 0)
        this.$store.commit('user/SET_TOKEN', '')
        this.$router.push('/login')
</script>

request.js

	 // token失效!
      case 710:
      // 当token失效的时候先判断是否有水印节点,有的话移除
        var watermark = document.getElementById('watermark')
        if (watermark) document.body.removeChild(watermark)
        store.commit('user/SET_HOMEIMG', 2)
        store.commit('user/CHANGE_MENU', 0)
        store.commit('user/SET_CURRENT_SYS', 0)
        store.dispatch('user/resetToken')
        router.push('/login')
        break

参考文章:

主要是依据这篇文章及其提供的代码
从破解某设计网站谈前端水印(详细教程)
水印详解-git代码
水印详解-div明水印实现

前端水印生成
前端页面水印生成方式
前端水印生成方案
前端水印生成方案

为了防止信息泄露或知识产权被侵犯,在web的世界里,对于图片文档等增加水印处理是十分有必要的。水印的添加根据环境可以分为两大类,前端浏览器环境添加和后端服务环境添加。今天介绍的就是通过canvas创建一张含有水印信息的背景图片,通过vue指令插入到页面中。 $(document).ready(function() { var watermark_txt = "测试效果" + getDate(); watermark({"watermarl... 前端给网页添加明水印的解决办法 为了防止信息泄露,保护版权,在前端我们时常会用到水印。 当然,水印也有明水印和暗水印之分,今天我们将的是前端实现水印实现全屏覆盖。 创建一个水印图层,我们需要两步,一步是生成对应的图片,第二步是把图片放到最上层并全屏显示,最好还是按照格子状页面上显示多个水印内容。 一、生成图片 因为不同页面大小不同,不同身份的人也应该设置不同的水印信息。这就需要我们动态生成图片,这里就需要使用canvas function createBackgroundImage(content, p 水印(Watermark)是一种能让人识别纸上图案的技术,当光线照射纸张时,纸张上会显现出各种不同阴影,这些阴影组成的图案就是水印水印常常起到验证货币、护照、邮票、政府文件或者其他纸制文件的真实性的作用。随着互联网的发展,我们经常在网页或者 App 上看到一些具有独特设计的文字或者图片,并且下载后依旧会存在于其中,这种常见的标识叫做水印。随着人们版权意识的觉醒,越来越多的人为了防止信息泄露或知识产权被侵犯,人们会在发布的文章、文件、图片、音频、视频中添加水印页面加载后,通过javascript创建页面元素div,并在div元素中创建文本节点,展示水印内容 设置div元素样式,将其zIndex设置一个较高的值,并设置透明度,实现浮在页面水印效果 其核心逻辑如下所示 var mask_div = document.createElement('div'); mas...