路:

  1. 获取想要插入水印的文档节点的顶点坐标值x,y。

  2. 获取文档节点的高度heigt和宽度width。

  3. 用div包裹文字来生成水印。

  4. 定义好div的长宽高间距等各种属性。

  5. 定义虚拟节点createDocumentFragment()包裹水印文档。
  6. 先进行行(hang)循环,一行一行生成水印,以x,y为初始坐标,生成一个top为y,left为x,自带宽高的一列水印。每生成一行,y的值递增(高度加行距),x的值重置为初始值。

  7. 再进行列循环,一列一列生成水印,每生成一列,x的值递增(宽度加间距)。

  8. 通过append方法插入每个水印节点。

  9. 将水印append到最开始想要插入的文档节点中去。

代码:

function watermark(element, config) {
// 获取元素的坐标
function getOffset(el){
if (el.offsetParent) {
return {
x: el.offsetLeft + getOffset(el.offsetParent).x,
y: el.offsetTop + getOffset(el.offsetParent).y,
};
}
return {
x: el.offsetLeft,
y: el.offsetTop,
};
}
if (!element) return;
// 默认配置
const _config = {
text1: 'text', //文本1
text2: 'text', // 文本2
start_x: 0, // x轴起始位置
start_y: 0, // y轴起始位置
space_x: 100, // x轴间距
space_y: 50, // y轴间距
width: 210, // 宽度
height: 80, // 长度
fontSize: 20, // 字体
color: '#aaa', // 字色
alpha: 0.4, // 透明度
rotate: 15, // 倾斜度
};
// 替换默认配置
if(arguments.length === 2 && typeof arguments[1] ==="object" ) {
const src = arguments[1] || {};
for(let key in src) {
if (src[key] && _config[key] && src[key] === _config[key]){
continue;
} else if (src[key]){
_config[key] = src[key];
}
}
}
// 节点的总宽度
const total_width = element.scrollWidth;
// 节点的总高度
const total_height = element.scrollHeight;
// 创建文本碎片,用于包含所有的插入节点
const mark = document.createDocumentFragment();
// 水印节点的起始坐标
const position = getOffset(element);
let x = position.x + _config.start_x, y = position.y + _config.start_y;
// 先循环y轴插入水印
do {
// 再循环x轴插入水印
do {
// 创建单个水印节点
const item = document.createElement('div');
item.className = 'watermark-item';
// 设置节点的样式
item.style.position = "absolute";
item.style.zIndex = 99999;
item.style.left = `${x}px`;
item.style.top = `${y}px`;
item.style.width = `${_config.width}px`;
item.style.height = `${_config.height}px`;
item.style.fontSize = `${_config.fontSize}px`;
item.style.color = _config.color;
item.style.textAlign = 'center';
item.style.opacity = _config.alpha;
item.style.filter = `alpha(opacity=${_config.alpha * 100})`;
// item.style.filter = `opacity(${_config.alpha * 100}%)`;
item.style.webkitTransform = `rotate(-${_config.rotate}deg)`;
item.style.MozTransform = `rotate(-${_config.rotate}deg)`;
item.style.msTransform = `rotate(-${_config.rotate}deg)`;
item.style.OTransform = `rotate(-${_config.rotate}deg)`;
item.style.transform = `rotate(-${_config.rotate}deg)`;
item.style.pointerEvents = 'none'; //让水印不遮挡页面的点击事件
// 创建text1水印节点
const text1 = document.createElement('div');
text1.appendChild(document.createTextNode(_config.text1));
item.append(text1);
// 创建text2水印节点
const text2 = document.createElement('div');
text2.appendChild(document.createTextNode(_config.text2));
item.append(text2);
// 添加水印节点到文本碎片
mark.append(item);
// x坐标递增
x = x + _config.width + _config.space_x;
// 超出文本右侧坐标停止插入
} while (total_width + position.x > x + _config.width);
// 重置x初始坐标
x = position.x + _config.start_x;
// y坐标递增
y = y + _config.height + _config.space_y;
// 超出文本底部坐标停止插入
} while (total_height + position.y > y + _config.height);
// 插入文档碎片
element.append(mark);
}

使用:

const element = document.getElementById('content');
watermark(element);

效果:

js生成页面水印的更多相关文章

  1. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面

    前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码.博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一个什么工具直接生成页面效果,啥代码都不用写了,那该多爽.于是研究了下T4 ...

  2. 利用scrapy-splash爬取JS生成的动态页面

    目前,为了加速页面的加载速度,页面的很多部分都是用JS生成的,而对于用scrapy爬虫来说就是一个很大的问题,因为scrapy没有JS engine,所以爬取的都是静态页面,对于JS生成的动态页面都无 ...

  3. 解决在页面中无法获取qrcode.js生成的base64的图片

    应用场景 生成带二维码的推广海报图片 旧方法: 将用户自己的推广连接先通过qrcode.js生成二维码,然后再用后台返回的一张背景图片和二维码通过canvas绘制成一张海报. 问题 在部分安卓手机上获 ...

  4. js生成有缩进的表格

    项目中用到用了两天时间想到的,记录下来,如有更好的方法,留言给我,谢谢! js做如下表格: json [{"id":302,"serviceId":15,&qu ...

  5. 前端学习-使用JS库Leaflet.js生成世界地图并获取标注地址经纬度。

    介绍:Leaflet是一个开源的JavaScript库,对移动端友好且对地图有很好的交互性. 大小仅仅只有 33 KB, 同时具有大多数地图所需要的特点. Leaflet设计的非常简单易懂, 同时具有 ...

  6. jquery页面水印插件,支持多行水印、行错开

    最近工作需求,需要在页面上加水印,但发现网上示例无法满足我的需求,所以还是自己动手写. 有几个特别需求: 1.可以写多行水印,并且中心对齐. 2.每行水印错开. PS:我找到的例子都是单行水印,所以用 ...

  7. 网站开发进阶(二十六)js刷新页面方法大全

    js刷新页面方法大全 在项目开发过程中,需要实现刷新页面.经过学习,发现下面这条语句就可以轻松实现. location.reload(); // 刷新页面 有关刷新页面的其它方法,具体学习内容如下,有 ...

  8. js生成带logo的二维码

    作为一名java程序员,一直以来都是使用服务端生成二维码,最近接触前端的设计,感觉二维码这块如果放到前端去生成,一方面可以减轻服务端的压力,访问带宽,另一方面,前端页面控制比较顺畅 闲话少叙,说下我的 ...

  9. JS生成URL二维码

    需求:项目中需要在UI界面有一个二维码,扫码后可以跳转到二维码包含的URL. 解决方案:在前端用js生成一个包含URL等信息的二维码. 实现: 方案一. <!DOCTYPE HTML PUBLI ...

随机推荐

  1. Python轮换

    switch_source()用于获取文本信息rewrite_source()用于将信息顺序轮换,其参数times表示要轮换多少次, def switch_source(): tmp = [] wit ...

  2. 并不简单的Integer

    Integer是一个看着挺简单的,其实还是有点不一样,Integer是一个int的包装类,它是可以起到缓存作用的,在java基础里说过它的范围是(-128-127)在这个返回是有缓存的,不会创建新的I ...

  3. 零基础入门学习Python(10)--列表:一个打了激素的数组

    前言 有时候我们需要把一些东西暂时保存起来,因为他们有着一些直接或间接的联系,我们需要把它们放在某个组或者集合中,未来可能用得上. 很多接触过编程的朋友都知道,都接触过数组这个概念,那么数组这个概念事 ...

  4. 树莓派 -- 输入设备驱动 (key)

    输入设备(如按键,键盘,触摸屏等)是典型的字符设备,其一般工作原理是底层在按键或触摸等动作发生时产生一个中断,然后CPU通过SPI,I2C总线读取键值. 在这些工作中之后中断和读键值是与设备相关的,而 ...

  5. restframework框架之认证

    1. 认证之APIView 在聊APIView之前, 我们先重温一下django2.x的CBV流程 a. 对于django而言, 当浏览器请求到达之后,按照规则首先会经过各大中间件(Middlewar ...

  6. Python中的列表(3)

    我们创建的列表元素的顺序是无法预测的,因为我们无法控制用户提供数据的顺序. 为了组织列表中的元素,所以Python帮我们提供一些方法用来排序列表中的元素. 1.方法 sort() 可以对列表永久性排序 ...

  7. LeetCode(38) Count and Say

    题目 The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, 1211, 111 ...

  8. 技能CD 效果 shader

    技能CD特效 这个效果主要是利用反正切函数完成.atan2(x,y)的返回值是[-PI,PI],这个支持4个象限的反正切函数.关于圆角计算,在上篇文章中有介绍. 现在,我们来看看反正切函数的效果: 在 ...

  9. 【04】AJAX接收服务器返回的数据

    AJAX接收服务器返回的数据 readyState 和 status 属性 readyState 属性保存有 XMLHttpRequest 对象的交互状态,从 0 到 4 变化: 0 :未初始化(还没 ...

  10. STM32F407 串口通信实验 第26节 个人笔记

    前言 这篇笔记对应正点原子STM32F407探索者 ,教学视频第26节,网址如下: https://ke.qq.com/webcourse/index.html#cid=279403&term ...