Watermark水印组件在页面滚动时位置错乱怎么办?

舒婕 Dev 阅读 3

我用原生JS写了个简单的全屏水印组件,本来显示没问题,但一旦页面有滚动条,水印就跟着滚动跑偏了,不是固定在视口上的。我试过用 fixed 定位,但水印容器还是随着文档流动,完全没固定住。

是不是我的样式写错了?或者需要监听 scroll 事件重新计算位置?下面是我目前的实现:

const watermark = document.createElement('div');
watermark.style.position = 'fixed';
watermark.style.top = '50%';
watermark.style.left = '50%';
watermark.style.transform = 'translate(-50%, -50%) rotate(-30deg)';
watermark.style.opacity = '0.1';
watermark.innerText = '机密文件';
document.body.appendChild(watermark);

但只要页面内容超出一屏,往下滚一下,水印就看不见了,好像被盖在上面还是怎么的……这到底咋整?

我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
公孙志丹
这个问题其实挺常见的,我之前做水印也踩过这个坑。你的思路是对的用fixed定位,但漏了几个关键点。我来解释下为什么现在会这样以及怎么修复:

原理是这样:fixed定位确实是相对于视口固定的,但有两个问题要注意:
1. 你的水印div被其他元素盖住了,因为z-index没设置
2. 水印容器可能需要更合理的宽高设置

试试这样改:

// 创建水印元素
const watermark = document.createElement('div');
watermark.style.position = 'fixed';
watermark.style.top = '0';
watermark.style.left = '0';
watermark.style.width = '100vw'; // 用视口单位确保覆盖整个屏幕
watermark.style.height = '100vh';
watermark.style.pointerEvents = 'none'; // 关键!让水印不阻挡点击事件
watermark.style.zIndex = '9999'; // 确保在最顶层

// 创建实际显示水印内容的内层元素
const watermarkContent = document.createElement('div');
watermarkContent.innerText = '机密文件';
watermarkContent.style.position = 'absolute';
watermarkContent.style.top = '50%';
watermarkContent.style.left = '50%';
watermarkContent.style.transform = 'translate(-50%, -50%) rotate(-30deg)';
watermarkContent.style.opacity = '0.1';
watermarkContent.style.fontSize = '48px'; // 调大点更明显

watermark.appendChild(watermarkContent);
document.body.appendChild(watermark);


主要改动点:
1. 外层容器用fixed定位并且撑满整个视口
2. 加了z-index确保不会被其他元素覆盖
3. pointerEvents很重要,不然水印会挡住页面交互
4. 把内容和容器分离,这样旋转不会影响定位

如果还是有问题,可能是body的margin/padding影响,可以再加个:
body {
margin: 0;
padding: 0;
}


我之前做这个的时候还遇到过浏览器兼容性问题,特别是移动端。如果遇到奇怪的表现,可以告诉我具体现象,我们再一起看怎么调整。
点赞
2026-03-05 03:44