欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > JS 生成防篡改水印

JS 生成防篡改水印

2024/12/22 0:21:39 来源:https://blog.csdn.net/Vue2018/article/details/144529665  浏览:    关键词:JS 生成防篡改水印

网页中有水印的需求,今天我们实现手写一个防篡改水印,先看下效果图:

在这里插入图片描述

一、创建class函数

传递一个dom为水印包裹器,有一些监听防篡改的observer,然后实例化的时候创建水印,执行create()方法

class WaterMarker {private container: HTMLElement | null;private observer_c?: MutationObserver; // 监听水印,防篡改private observer_p?: MutationObserver; // 监听水印,防删除constructor(container: HTMLElement || null) {this.container = containerthis.create() // 初始化}// 获取水印元素getElement(): HTMLElement | null {return document.getElementById(`water_marker`)}// 延时执行async wait(ms: number): Promise<void> {return new Promise(resolve => setTimeout(resolve, ms))}
}let dom = document.querySelector('#body') as HTMLElement || null
dom ? let waterMarker = new WaterMarker(dom) : ''

二、创建水印dom

这里创建水印dom记得将鼠标指针设置为无效,以免水印dom遮挡画面部分点击区域,‘pointerEvents’ 为 null,这里的 mixBlendMode 混合模式则是为了避免水印和画面的颜色重叠,造成水印不可见。

// 创建水印async create(): Promise<void> {await this.wait(500)let content = `<span style="font-size: 18px">游客</span> <br> <span style="font-size: 18px">Guest</span> <br> 中国传媒大学`let el = document.createElement('div') as HTMLElementel.style.display = 'inline-block'el.style.position = 'absolute'el.id = `water_marker`el.style.top = '20px'el.style.left = '20px'el.style.lineHeight = '20px'el.style.color = '#fff'el.style.fontSize = '14px'el.style.textAlign = 'center'el.style.fontWeight = 'bold'el.style.pointerEvents = 'none'el.style.filter = 'opacity(0.75)'el.style.textShadow = '1px 1px 0px rgba(0, 0, 0, 0.2),\n' +'      1px 2px 0px rgba(0, 0, 0, 0.2),\n' +'      1px 3px 0px rgba(0, 0, 0, 0.2)'el.style.mixBlendMode = 'difference'el.style.zIndex = 10el.style.transform = 'rotateZ(-45deg)'el.innerHTML = contentthis.container?.appendChild(el)// 开始动画this.createAnimate(el)// 等待一秒开始监听水印篡改,删除await this.wait(1000)// 监听水印,防篡改this.observeC(el)// 监听水印,防删除this.observeP()}

三、给水印添加animate动画,旋转动画

 // 创建动画createAnimate(el: HTMLElement): void {let delay = 1000 * 6 // 6秒循环一次let width = this.container.offsetWidth || 0let height = this.container.offsetHeight || 0el.animate([{ transform: `translate(0 ,0) rotateZ(-45deg)` }, // 起始位置{ transform: `translate(calc(${width - 40}px - 100%), 0) rotateZ(45deg)`}, // 右侧{ transform: `translate(calc(${width - 40}px - 100%), calc(${height - 40}px - 100%)) rotateZ(45deg)` }, // 底部{ transform: `translate(0, calc(${height - 40}px - 100%)) rotateZ(-45deg)` }, // 左侧{ transform: `translate(0, 0) rotateZ(-45deg)`} // 返回起始位置],{duration: delay,iterations: Infinity, // 无限循环easing: 'cubic-bezier(.31,.01,1,1.27)',delay: 0,})}

四、水印添加防篡改,防删除

防篡改用MutationObserver监听目标元素的节点、属性、子节点变化达到防篡改的作用
防删除用MutationObserver监听包裹器,判断删除的子节点是否包含水印,达到防删除的作用

这里的option配置有几个属性:

属性名作用
attributes元素节点的属性值变化
characterData元素节点的内容数据发生变化
childList元素节点的子节点的新增和移除
subtree元素深层节点的变化
 // 监听目标元素的变化observeC(el: HTMLElement): void {let config: MutationObserverInit = { attributes: true, characterData: true, childList: true, subtree: true }this.observer_c = new MutationObserver((mutationsList: MutationRecord[]) => {for (let mutation of mutationsList) {switch (mutation.type) {case 'attributes':case 'childList':case 'characterData':alert('请勿篡改水印哦,尊重版权!')// 销毁重新创建,这里可以函数防抖下,改变style的时候let cb = () => {this.destroy()this.create()}debounce(cb, 100)break;default:break;}}});this.observer_c.observe(el, config);}// 监听目标元素的父元素的子节点删除,从而达到监听水印被删除observeP() {let config: MutationObserverInit = { attributes: true, characterData: true, childList: true, subtree: true }this.observer_p = new MutationObserver((mutationsList: MutationRecord[]) => {for (let mutation of mutationsList) {switch (mutation.type) {case 'childList':// 判断删除的子节点中是否包含水印节点let removedNodes = Array.from(mutation.removedNodes)if (removedNodes.find(node => node.id.includes('water_marker'))) {alert('请勿篡改水印哦,尊重版权!')// 销毁重新创建this.destroy()this.create()}break;default:break;}}});this.observer_p.observe(this.container, config);}

五、添加销毁事件

这里要先销毁监听器,再销毁水印dom

  destroy() {this.observer_c?.disconnect()this.observer_p?.disconnect()let el: HTMLElement = this.getElement()el? el.remove() : ''}

六、拓展

如果涉及到重复,创建dom可修改为canvas创建,这里就不多说了

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com