Skip to content

页面背景水印

简介

一些阅读器会使用页面水印标注版权或用户信息。水印只能增加信息泄露的追踪线索,不能防止截图或复制,因此不应将其视为安全措施。

实现细节

技术选型

使用第三方库 watermark-dom 实现,版本 1.0.0。

水印实现原理:创建覆盖页面的半透明图层显示文字,并通过 pointer-events: none 让鼠标事件穿透,不影响页面交互。

.watermark {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  width: 100%;
  height: 100%;
  pointer-events: none; /* 点击穿透 */
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.watermark .watermark-text {
  opacity: 0.1;
  color: #666;
  width: 200px;
  height: 200px;
  transform: rotate(25deg);
  font-size: 24px;
}

然后将图层挂载到页面节点(通常是 body 或阅读内容容器)。

<body>
  <div class="watermark">
    <div class="watermark-text">未授权</div>
    <div class="watermark-text">未授权</div>
    ...
  </div>
</body>

模块实现

  1. 开启、关闭页面水印:在高级设置中监听输入变化,并对更新操作进行节流,避免频繁调用水印 API。水印文本为空时应清除水印。
onChange = throttle(() => {
  let currentText = this.inputRef.current.value.trim();
  if (currentText.length > 10) {
    alert("水印长度最多 10 个字符");
    return;
  }
  if (currentText !== waterMarkText) {
    eventBus.dispatch("watermark", currentText);
  }
}, 1000);
  1. 显示水印:通过 eventBus 将水印内容传递给文档组件,再将水印挂载到阅读内容容器。示例中的选择器使用 #article,getElementById 则应传入不带 # 的 ID;请按所用库要求选择对应 API。
if (currentText) {
  watermark.load({
    watermark_txt: currentText,
    watermark_alpha: 0.075,
    watermark_parent_node: document.getElementById("article"),
  });
} else {
  watermark.remove();
  // 若所用版本无法可靠清除水印,应显式移除覆盖层,而不是刷新整个页面。
}
  1. 存储水印配置:如需展示“未登录”“测试版”或用户名等信息,应由应用统一管理配置,并根据需要设置默认状态。不要将用户可控文本当作权限或版权校验依据。
saveWatermark = (txt) => {
  this.config = Object.assign({}, this.config, { watermark_txt: txt });
};

版本历史

1.4 版本基本支持页面水印。

参考文献