IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 前端网页水印实现方法 -> 正文阅读

[JavaScript知识库]前端网页水印实现方法

前言

页面水印是一种数字保护,版权保护,知识产权保护的手段,为防止他人盗用,可以快速定位到个人

目标

  • 提高安全性,不可以通过控制台修改隐藏水印
  • 前端水印不影响页面的正常使用
  • 前端水印的显示方式是页面整体旋转某个角度

技术分析

  • 前端网页要整体显示水印,首先生成一个水印
  • 然后将水印作为背景图(重复显示这一个水印repeat)填充整个页面
  • 然后检测水印变化,如果变化重新生成。不会被隐藏。

实现方案

首先生成一个水印

  • 可以通过canvas生成
	function canvasWM({
		container = document.body,
		width = '200px',
		height = '200px',
		textAlign = 'center',
		textBaseLine = 'middle',
		font = '12px SourceHanSansSCVF-Regular',
		fillStyle = 'rgba(0,0,0,0.1)',
		content = '前端水印',
		zIndex = 10
	} = {}) {
		var args = arguments[0];
		var canvas = document.createElement('canvas');
		
		canvas.setAttribute('width', width);
		canvas.setAttribute('height', height);
		var ctx = canvas.getContext('2d');
		
		ctx.textAlign = textAlign;
        ctx.textBaseline = textBaseline;
        ctx.font = font;
        ctx.fillStyle = fillStyle;
        ctx.fillText(content, parseFloat(width) / 2, parseFloat(height) / 2);
		//
        var base64Url = canvas.toDataURL();
	}
 // 调用canvasWM会生成一个base64Url的水印图片
 

链接: canvas如何生成dataUrl

以上代码生成的图片
这是上面代码所生成的水印图片

  • 可以通过svg生成(跟canvas类似)
	function svgWM({
		container = document.body,
		width = '200px',
		height = '200px',
		fontSize = '12px',
		fontFamily = 'SourceHanSansSCVF-Regular',
		fill= 'rgb(0,0,0,0.06)',
		content = '前端水印',
		zIndex = 10
	} = {}) {
	const args = arguments[0];
	const svgStr = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}">
		  <text x="50%" y="50%"
		    text-anchor="middle"
            font-family=${fontFamily}
            fill=${fill}
            style="font-size: ${fontSize};">
            ${content}
		  </text>
		</svg>`;
        const base64Url = `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(svgStr)))}`;
	// 调用svgWM会生成一个base64Url的水印图片
	}

将水印作为背景图

以上代码实现了一个水印的图片,然后创建一个div元素,把水印作为背景图

    const __wm = document.querySelector('.__wm');
	const watermarkDiv = __wm || document.createElement("div");
    const styleStr = `
        position:fixed;
        top:0px;
        left:0px;
        width:100%;
        height:1400%;
        z-index:${zIndex};
        pointer-events:none; // 元素永远不会成为鼠标事件的target
        background-repeat:repeat; // 重复水印显示
        transform: rotate(-24deg) translateZ(0); // 页面整体旋转角度
        overflow:hidden;
        background-image:url('${base64Url}')`;

    watermarkDiv.setAttribute('style', styleStr);
	watermarkDiv.classList.add('__wm');
	

以上代码中的旋转会导致图片上的水印字体模糊,暂时未解决

检测水印变化,做出调整

MutationObserver接口提供了监视对DOM树所做更改的能力
Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
使用MutationObserver构造函数,新建一个观察器实例,实例的有一个回调函数,该回调函数接受两个参数,第一个是变动数组,第二个是观察器实例。MutationObserver 的实例的observe方法用来启动监听,它接受两个参数
MutationObserver只能监测到诸如属性改变、增删子结点等,对于自己本身被删除,是没有办法的可以通过监测父结点来达到要求

		if (!__wm) {
			container.style.position = 'relative';
		    container.insertBefore(watermarkDiv, container.firstChild);
        }
 		const MutationObserver = window.MutationObserver || 		window.WebKitMutationObserver;
        if (MutationObserver) {
          let mo = new MutationObserver(function () {
            const __wm = document.querySelector('.__wm');
            // 只在__wm元素变动才重新调用 __canvasWM
            if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm) {
              // 避免一直触发
              mo.disconnect();
              mo = null;
            __canvasWM(JSON.parse(JSON.stringify(args)));
            }
          });

          mo.observe(container, {
            attributes: true,
            subtree: true,
            childList: true
          })
        }

调用

	// 引入之后调用
	canvasWM({
      content: '显示水印'
    });

整体代码

(function () {
	function svgWM({
		container = document.body,
		width = '200px',
		height = '200px',
		fontSize = '12px',
		fontFamily = 'SourceHanSansSCVF-Regular',
		fill= 'rgb(0,0,0,0.06)',
		content = '前端水印',
		zIndex = 10
	} = {}) {
	const args = arguments[0];
	const svgStr = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}">
		  <text x="50%" y="50%"
		    text-anchor="middle"
            font-family=${fontFamily}
            fill=${fill}
            style="font-size: ${fontSize};">
            ${content}
		  </text>
		</svg>`;
        const base64Url = `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(svgStr)))}`;


 	const __wm = document.querySelector('.__wm');
	const watermarkDiv = __wm || document.createElement("div");
    const styleStr = `
        position:fixed;
        top:0px;
        left:0px;
        width:100%;
        height:1400%;
        z-index:${zIndex};
        pointer-events:none; // 元素永远不会成为鼠标事件的target
        background-repeat:repeat; // 重复水印显示
        transform: rotate(-24deg) translateZ(0); // 页面整体旋转角度
        overflow:hidden;
        background-image:url('${base64Url}')`;

    watermarkDiv.setAttribute('style', styleStr);
	watermarkDiv.classList.add('__wm');

 if (!__wm) {
          container.style.position = 'relative';
          container.insertBefore(watermarkDiv, container.firstChild);
        }
        
        const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
        if (MutationObserver) {
          let mo = new MutationObserver(function () {
            const __wm = document.querySelector('.__wm');
            // 只在__wm元素变动才重新调用 __canvasWM
            if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm) {
              // 避免一直触发
              mo.disconnect();
              mo = null;
            __canvasWM(JSON.parse(JSON.stringify(args)));
            }
          });

          mo.observe(container, {
            attributes: true,
            subtree: true,
            childList: true
          })
        }

      }

      if (typeof module != 'undefined' && module.exports) {  //CMD
        module.exports = __canvasWM;
      } else if (typeof define == 'function' && define.amd) { // AMD
        define(function () {
          return __canvasWM;
        });
      } else {
        window.__canvasWM = __canvasWM;
      }
    })();
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:22:38  更:2022-03-10 22:26:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:18:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码