麟游做网站,腾讯企业邮箱登录入口,沧州市做网站价格,免费包装设计在线生成目录
一、应用场景
二、实现原理
三、详细开发
1.水印的实现方式
2.防止用户通过控制台修改样式去除水印效果#xff08;可跳过#xff0c;有弊端#xff09;
3.水印的使用
#xff08;1#xff09;单页面/全局使用
#xff08;2#xff09;全局使用个别页面去掉…目录
一、应用场景
二、实现原理
三、详细开发
1.水印的实现方式
2.防止用户通过控制台修改样式去除水印效果可跳过有弊端
3.水印的使用
1单页面/全局使用
2全局使用个别页面去掉
四、总结 一、应用场景
在网页中添加水印的作用可以有多个方面一个重要的作用就是版权保护防止未经授权就复制截图或使用在文档中可以帮助标识文档的来源审查追踪等也可以展示企业信息或者作为提示信息告诉用户当前页面谨慎处理也能在敏感信息的页面提示用户保护信息安全等。注意制作页面中的水印要平衡用户体验和需求确保水印不要太大太密太突兀干扰页面浏览和操作。 二、实现原理 在页面里添加水印一种是特定页面加水印那么本页面加水印功能即可用CSS/JavaScript都可以实现另一种是全局都加水印这种可以考虑某些页面不需要加水印在路由守卫或者其他地方去掉即可。 写在前面水印的实现原理创建一个canvas画一个客户端高x客户端宽的画布里面画满水印并将其的层级z-index设置最高使其一直显示在界面的最上方。
水印的内容可以根据应用的场景而变换比如版权保护这些最好显示版权的归属方之类的有些出于标识来源加的水印则需要考虑当前用户的信息比如用户名等等。
实现效果如下 三、详细开发
首先谈一下水印的实现方式再说怎么加水印。
1.水印的实现方式
我们可以在utils下新建一个文件watermark.js代码如下
let watermark {}
let idd 1.23452384164.123412416
let setWatermark (str, srt1, srt2, srt3) {let id iddif (document.getElementById(id) ! null) {document.body.removeChild(document.getElementById(id))}//创建一个画布let can document.createElement(canvas)//设置画布的长宽can.width 600can.height 450 let cans can.getContext(2d)//旋转角度cans.rotate((-15 * Math.PI) / 180)cans.font 18px Vedana//设置填充绘画的颜色、渐变或者模式cans.fillStyle rgba(200, 200, 200, 0.40)//设置文本内容的当前对齐方式cans.textAlign left//设置在绘制文本时使用的当前文本基线cans.textBaseline Middle//在画布上绘制填色的文本输出的文本开始绘制文本的X坐标位置开始绘制文本的Y坐标位置cans.fillText(str srt1, can.width / 8, can.height / 2)cans.fillText(srt2, can.width / 8, can.height / 2.3)cans.fillText(srt3, can.width / 8, can.height / 2.7)let div document.createElement(div)div.id idconst styleStr position:fixed;visibility:visible !important;top:30px;width:${document.documentElement.clientWidth}px;height:${document.documentElement.clientHeight}px;left:0;z-index:100000;pointer-events:none;background:url(${can.toDataURL(image/png)}) left top repeatdiv.setAttribute(style, styleStr)// div.style.width document.documentElement.clientWidth px;// div.style.height document.documentElement.clientHeight px;document.body.appendChild(div)//此方法是防止用户通过控制台修改样式去除水印效果/* MutationObserver 是一个可以监听DOM结构变化的接口。 */// const observer new MutationObserver(() {// const wmInstance document.getElementById(id)// if (// (wmInstance wmInstance.getAttribute(style) ! styleStr) ||// !wmInstance// ) {// //如果标签在只修改了属性重新赋值属性// // console.log(水印属性修改了)// if (wmInstance) {// // 避免一直触发// observer.disconnect();// console.log(水印属性修改了)// wmInstance.setAttribute(style, styleStr)// } else {// /* 此处根据用户登录状态判断是否终止监听避免用户退出后登录页面仍然有水印 */// if (store.state.user.token) {// //标签被移除重新添加标签// // console.log(水印标签被移除了);// document.body.appendChild(div)// } else {// observer.disconnect()// }// }// }// })// observer.observe(document.body, {// attributes: true,// subtree: true,// childList: true,// })return id;
}// 该方法只允许调用一次
watermark.set (str, srt1, srt2, srt3) {let id setWatermark(str, srt1, srt2, srt3)setInterval(() {if (document.getElementById(id) null) {id setWatermark(str, srt1, srt2, srt3)}}, 500)window.onresize () {setWatermark(str, srt1, srt2, srt3)}
}
// 移除
const outWatermark id {if (document.getElementById(id) ! null) {const div document.getElementById(id)div.style.display none}
}watermark.remove () {const str iddoutWatermark(str)
}// 将 watermark 的控制方法挂载到 window 对象上
window.watermark watermarkexport default watermark上面的代码很多人都写过这里实现的也是大致效果原理简单来讲就是创建一个canvas画一个客户端高x客户端宽的画布里面画满水印并将其的层级z-index设置最高使其一直显示在界面的最上方水印的效果就根据业务需求来调整。
这里将水印的控制方法set和remove)都挂载在了window上那么不论在哪个页面使用都可以直接调window来操作水印水印的传参设置了四个str其实可以根据实际情况添加更多定制各样的效果。
2.防止用户通过控制台修改样式去除水印效果可跳过有弊端
这里就是指上面代码里注释的的功能可根据需求添加。 这个功能的原理 创建了一个 MutationObserver 实例MutationObserver 允许开发人员监视 DOM 树的变化并在发生变化时执行相应的操作通过传一个制定ID的元素将其存储在 wmInstance 变量中。然后检查wmInstance 是否存在及其style属性是否与指定的styleStr 变量相匹配来判断水印是否需要更新。如果 wmInstance 存在且其 style 属性不匹配或者 wmInstance 不存在则进行相应的处理 1如果 wmInstance 存在则更新其 style 属性为 styleStr。 2如果 wmInstance 不存在则检查用户登录状态。如果用户已登录假设通过 store.state.user.token 判断则向页面添加新的水印元素假设该元素已在其他地方定义。否则断开 observer 的监听。最后调用 observer.observe() 方法开始观察文档主体的变化。选项对象指定了要观察的变化类型包括 attributes、subtree 和 childList。 而MutationObserver是什么 MutationObserver 是 Web API 中的一部分用于监视 DOM文档对象模型树的变化。它允许开发人员异步地观察文档中的节点并对其进行相应的处理。 在 Web 开发中DOM 是指用于表示文档结构的树形数据结构它由节点node组成每个节点代表文档中的不同部分如元素、属性、文本等。DOM 的结构和内容可能在页面加载后发生变化比如用户的交互行为、脚本操作等都可能导致 DOM 发生变化。 MutationObserver 提供了一种机制让开发人员可以监视 DOM 树的这些变化并在变化发生时执行回调函数。这使得开发人员可以更灵活地响应 DOM 变化而不必通过定时器或事件监听器等方式来轮询检查 DOM。 使用 MutationObserver开发人员可以监视以下类型的 DOM 变化 属性的改变例如元素的属性值发生变化。节点的添加或删除例如元素被插入或从 DOM 中移除。子节点的改变例如元素的子节点被添加或移除。 通过 MutationObserver开发人员可以更有效地监视 DOM 变化从而实现更灵活、高效的 DOM 操作和交互。这在诸如单页面应用SPA等需要动态更新页面内容的场景中特别有用。 上述查自网络 这个功能的弊端是 如下图所示如果浏览器修改窗口大小也会触发水印的修改并且水印的覆盖会带来一定视觉上的“卡顿”实际使用中可能卡顿不是那么明显但是这种情况也是值得考虑的。 3.水印的使用
使用的方式有两种局部使用和全局使用就类似于我们引入UI组件库的组件一样封装的水印js也需要局部或者全局注册。
1单页面/全局使用
这里就比较简单我们在需要加水印的页面引入水印然后可以在mounted生命周期里调用它就行了。
import Watermark from /utils/watermarkmounted() {if (!Watermark) {Watermark null// console.log(无水印,Watermark)return} else {Watermark.set(第一行,第二行,第三行,第二行)}},
如果是 全局使用就在app.vue的页面里根据当前页面的路径或其他标识来判断是否需要添加水印。
2全局使用个别页面去掉
这个有多种实现方式需要考虑业务场景我这里推荐借助路由守卫在router的路由守卫拦截的时候进行水印的set或者remove操作如下
router.afterEach((to) {let Watermark window.watermarkif(!Watermark ){Watermarknull// console.log(store.state.app.watermark,store.state.app.watermark);return}if (to.fullPath /login || to.fullPath /test) {Watermark.remove()} else {Watermark.set(第一行,第二行,第三行,第二行)}
})
使用路由守卫进行拦截的优点是 路由守卫可以针对每个路由进行拦截并判断是否需要添加水印如果在特定路由不需要添加水印可以在路由拦截时不调用水印脚本或者remove对水印添加的控制更加精细。 四、总结
在水印的实现里第二种情况我推荐结合两者的方法可以更好地满足不同场景下的需求即在 app.vue中判断大部分页面是否需要添加水印然后在路由守卫中针对个别页面进行额外的控制这样页面就能满足大部分场景的要求。