前端水印优点
- 速度快
- 减少服务器压力
- 简单
实现方式
这里采用的是svg的写法,大概的一个想法就是用svg写水印然后覆盖整个网站
前端写水印有两个要解决的问题:一个是防止有人控制台删除此水印相关代码;另一个是当水印覆盖整个网站的时候,网站的事件按钮被覆盖失效的问题。
看到这里可以先思考这两个问题,然后看下面额实现代码
项目环境
react
实现效果
这是公司的项目,只能截取一部分给大家看看了
实现代码
组件: waterMark.js
import React, { Component } from 'react'
import MutationObserver from 'react-mutation-observer';
class Watermark extends Component {
constructor(props) {
super(props);
this.state = {
waterMarkStyle: '180px 120px',
isError: false
}
}
callback = (records) => {
// outerHTML
if(records.child){
let child = records.child
document.getElementById('***').parentNode.appendChild(child)
}
}
render() {
const { waterMarkStyle } = this.state
const { text = '测试水印', content } = this.props;
const boxStyle = {
backgroundSize: waterMarkStyle,
backgroundImage: `url("data:image/svg+xml;utf8,<svg width=\'100%\' height=\'100%\' xmlns=\'http://www.w3.org/2000/svg\' version=\'1.1\'><text width=\'100%\' height=\'100%\' x=\'20\' y=\'68\' transform=\'rotate(-20)\' fill=\'rgba(0, 0, 0, 0.2)\' font-size=\'14\' stroke=\'rgba(255, 255, 255, .2)\' stroke-width=\'1\'>${text}</text></svg>")`,
};
return (
<MutationObserver onChildRemoval={this.callback}>
<div className={'water_mark_wrapper'} >
<div className={'water_mark_box'} style={boxStyle} />
{content} // content主要是要应用水印的节点部分
</div>
</MutationObserver>
);
}
}
export default Watermark
水印核心代码,主要是svg文本部分
<svg width=\'100%\' height=\'100%\' xmlns=\'http://www.w3.org/2000/svg\' version=\'1.1\'><text width=\'100%\' height=\'100%\' x=\'20\' y=\'68\' transform=\'rotate(-20)\' fill=\'rgba(0, 0, 0, 0.2)\' font-size=\'14\' stroke=\'rgba(255, 255, 255, .2)\' stroke-width=\'1\'>${text}</text></svg>
大概看一下代码,然后我们这边来解释一下上面提到的两个问题
首先是防止删除:
我这里引用了一个react-mutation-observer,如果你不是写的react,可以看看原生的,用法其实一样的。这个东西的用法就是可以帮你监听某个节点是否发生了变更,我这里的思路是当它被删除的时候,触发callback方法,callback方法会帮我重新把这个被删除的水印,重新添加进去
callback = (records) => {
// records.child就是被删除的水印所在节点
if(records.child){
let child = records.child
// 这里可以根据实际需求来看要如何添加
document.getElementById('***').parentNode.appendChild(child)
}
}
防止删除问题解决了,一顿操作,发现页面的事件按钮点击不了,被层级高的水印覆盖了,这时候只需要一行css解决
style.css
.water_mark_wrapper{
position: relative;
}
.water_mark_box{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
pointer-events: none; // 关键代码
}
使用组件
因为我的水印在网站的每个页面都需要,所以在app.js页面用了
app.js
import React from 'react';
import Watermark from './components/watermark'
import Main from './routes/index'
class App extends React.Component {
render() {
return (
<div className="App">
<Watermark content={
<Route path="/" component={Main} />
}></Watermark>
</div>
);
}
}
export default App;
总结
其实如果粗暴点解决的话,可以直接禁止打开浏览器控制台,就可以避免各种删除等操作。
- 参考文章
水印实现的几种方式