可以使用canvas来实现水印,然后使用mutationObserver来检测元素是否被删改。代码如下:
// 函数buildWatermark()用于创建一个画布,并绘制文本,返回该画布function buildWatermark() { // 创建一个画布 const canvas = document.createElement("canvas"); // 设置画布的宽度 canvas.width = 150; // 设置画布的高度 canvas.height = 120; // 设置画布的显示方式 canvas.style.display = "none"; // 获取画布的2D绘图上下文 var ctx = canvas.getContext("2d"); // 旋转画布 ctx.rotate((-20 * Math.PI) / 180); // 移动画布的位置 ctx.translate(-50, 20); // 设置画布的填充颜色 // ctx.fillStyle = "#f5f5f5"; ctx.fillStyle = "red"; // 设置画布的字体 ctx.font = "100 16px Microsoft YaHei"; // 绘制文本 ctx.fillText("憋鬼叫好不好垃圾!!!", canvas.width / 2, canvas.height / 2); // 返回画布 return canvas;}// 为canvas设置水印function setWatermark(canvas) { // 创建一个div元素 var watermark = document.createElement("div"); // 设置div元素的样式 const styleStr = ` position:fixed; top:0; left:0; width:100vw; height:100vh; z-index:99; pointer-events:none; background-repeat:repeat; mix-blend-mode: multiply; background-image:url('${canvas.toDataURL("image/png")}')`; // 为div元素设置样式 watermark.setAttribute("style", styleStr); // 为div元素设置id watermark.setAttribute("id", "watermark"); // 将div元素添加到body中 document.body.appendChild(watermark); return styleStr;}function setObserverForWatermark() { const canvas = buildWatermark(); let styleStr = setWatermark(canvas); let canvasDOM = document.querySelector("#watermark"); const bodyDOM = document.querySelector("body"); function callback(mutationList, observer) { console.log(observer); mutationList.forEach((mutation) => { if (mutation.type === "attributes") { if (mutation.attributeName === "style") { // 这里需要这样判断,因为每一次修改都会触发这个回调,如果不这样判断 // 就会导致死循环。 if ( !( mutation.target .getAttribute("style") .replaceAll(" ", "") .replaceAll(/\n/g, "") === styleStr.replaceAll(" ", "").replaceAll(/\n/g, "") ) ) { mutation.target.setAttribute("style", styleStr); } // 这里需要这样判断,因为每一次修改都会触发这个回调,如果不这样判断 // 就会导致死循环。 } else if (mutation.attributeName === "id") { if (mutation.target.getAttribute("id") !== "watermark") { mutation.target.setAttribute("id", "watermark"); } } else if (mutation.attributeName === "class") { // 如果用户添加了class,这里主要为防止用户时候浏览器的隐藏元素选项来隐藏元素 // 这个隐藏元素按是添加了一个class,使用overflow:hidden;来隐藏元素 if ( mutation.target.getAttribute("class") !== "" || mutation.target.getAttribute("class") !== undefined ) { // 移除class mutation.target.removeAttribute("class"); } } } }); } // 如果元素被删除,监听元素自身是无法获取到被删除的信息的 // 但是当子元素被删除的时候,监听父元素的mutationObserver是可以监听到的 function parentCallback(mutationList) { console.log(mutationList); mutationList.forEach((mutation) => { if (mutation.type === "childList" && mutation.removedNodes.length > 0) { mutation.removedNodes.forEach((node) => { if (node === canvasDOM) { // 如果被删除的是水印节点,重新添加! setWatermark(canvas); canvasDOM = document.querySelector("#watermark"); } }); } }); } // 监听DOM变化 const observer = new MutationObserver(callback); observer.observe(canvasDOM, { attributes: true, childList: true, subtree: true, }); // 监听父元素,因为当删除元素自身的时候无法被监听到,而复原可以监听子元素被删除 const parentObserver = new MutationObserver(parentCallback); parentObserver.observe(bodyDOM, { attributes: true, childList: true, subtree: true, });}// 开始监听setObserverForWatermark();
我之前公司写过那种用 DOM 上创建 N 个 SPAN 然后用 CSS 斜过来的方案。不过这种有点low,用 Canvas 更优雅一些。可以参考上面的方案,
Canvas生成水印图 + CSS的点击穿透。
社区里面已经有类似的问答了 css怎么给网页添加水印效果?
输入新的指令 之前已经说过,脚本是以行为单位,顺序往下执行的。 也就是说,假如填写了“显示背景”,之后下一行“显示人物”,接着继续“显示对话框”、“显示对话”,按照这样的顺序,就可以做出“人物在场景里出现并说话”的效果。 接下来就来实际试试吧。 首先关掉刚刚的记事本,重新在脚本编辑器里打开“prelogue.ks”这个文件,进入脚本的图形化编辑界面。 然后点击选中第6行,也就是“(到达文件末端)”
V9的验证码在生成后,会把验证码的数字存入Session当中。 V9在默认的情况下,Session是存放在数据库当中的。其在数据库中的表现如下: 您可以在访问后台登陆页后,查看一下数据库中Session这个表,如果表中没有类型的数据code|s:4:"***"; 那说明Session没有成功的写入到数据库中。 这会使你的登陆失败。 可以偿试通过修改"/caches/configs/s
,文字前面跟着已到期或者即将到期,但是这段文字是右对齐,且以最长文本的长度作为整个盒子的宽度,并设置背景色。
在 www.isqqw.com 这个网站中找的,突然被删了
上面是vite.config.ts的别名配置 1.测试过别名注释在运行项目会报路径找不到,加上注释页面正常渲染(@符号) import App from "@/App.vue";