Div
2024年06月18日
一、认识
二、思路
2.1 元素虚化
pointer-events
CSS
属性指定在什么情况下 (如果有) 某个特定的图形元素可以成为鼠标事件的 target
。当它的被设置为 none
的时候,能让元素实体虚化,虽然存在这个元素,但是该元素不会触发鼠标事件。
2.2 禁止选中
CSS
属性 user-select
控制用户能否选中文本。除了文本框内,它对被载入为 chrome
的内容没有影响。
三、实现
3.1 JS
function cssHelper(el, prototype) {
for (let i in prototype) {
el.style[i] = prototype[i];
}
}
function calculateWatermarkCount(params) {
const { waterWidth, waterHeight } = params || {};
const { clientWidth, clientHeight } =
document.documentElement || document.body;
const column = Math.ceil(clientWidth / waterWidth);
const rows = Math.ceil(clientHeight / waterHeight);
return column * rows;
}
function createWatermarkDiv(params) {
const { text } = params || {};
const div = document.createElement("div");
div.innerHTML = text;
cssHelper(div, {
position: "absolute",
top: `50px`,
left: `50px`,
fontSize: `16px`,
color: "#000",
lineHeight: 1.5,
opacity: 0.1,
transform: `rotate(-15deg)`,
transformOrigin: "0 0",
userSelect: "none",
whiteSpace: "nowrap",
overflow: "hidden",
});
return div;
}
function createWatermark(params) {
const { text = "水印文案", waterWidth, waterHeight } = params || {};
const waterWrapper = document.createElement("div");
cssHelper(waterWrapper, {
position: "fixed",
top: "0px",
right: "0px ",
bottom: "0px",
left: "0px",
overflow: "hidden",
display: "flex",
"flex-wrap": "wrap",
"pointer-events": "none",
});
const watermarkCount = calculateWatermarkCount({
waterWidth,
waterHeight,
});
for (let i = 0; i < watermarkCount; i++) {
const wrap = document.createElement("div");
cssHelper(
wrap,
Object.create({
position: "relative",
width: `${waterWidth}px`,
height: `${waterHeight}px`,
flex: `0 0 ${waterWidth}px`,
overflow: "hidden",
})
);
wrap.appendChild(createWatermarkDiv({ text }));
waterWrapper.appendChild(wrap);
}
document.body.appendChild(waterWrapper);
return waterWrapper;
}
function observeWatermark(params) {
const { waterWrapper } = params || {};
const config = { attributes: true, childList: true, subtree: true };
const callback = function (mutationsList) {
for (let mutation of mutationsList) {
switch(mutation.type){
case "attributes":
if(mutation.target === waterWrapper){
document.body.appendChild(waterWrapper);
return;
}
break;
case "childList":
mutation.removedNodes.forEach(function (item) {
if (item === waterWrapper) {
document.body.appendChild(waterWrapper);
return;
}
});
break;
}
}
};
const targetNode = document.body;
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
}
const waterWrapper = createWatermark({
text: "柏拉文水印",
waterWidth: 180,
waterHeight: 100,
});
observeWatermark({ waterWrapper });
3.2 HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>明水印</title>
<link href="index.css" rel="stylesheet" />
</head>
<body>
<div>
<h3>标题 h3</h3>
<img src="../../images/50060231-77d6-4dfb-8752-4723549626dd-1.png"/>
</div>
<script src="./index.js"></script>
</body>
</html>