路:

  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. jquery腾讯换肤的一些技术实现

    //检查cookie if($.cookie("skinID")){ $("#cssSkin").attr("href","/st ...

  2. vue+VeeValidate 校验范围(部分校验,全部校验)

    搜索很久,没有发现有关于vue+VeeValidate部分校验的.自己写一个. 主要是两个场景: 1. 校验范围内,所有的字段. 2. 校验全局所有字段.主要方法: 1.validate(fields ...

  3. react-native 框架升级 安卓第三方插件报错 Android resource linking failed

    亲自经历react-native从0.55升级到0.58的过程,有点坎坷,ios出现的问题还算不多,但是android这里,随着gradle和buildTool的使用升级,导致第三方插件出现各种问题, ...

  4. 使用Hashids来保护你的数据库主键

    为什么要保护数据库主键? 数据库主键一般是有序自增主键,极易被爬虫抓取数据,作为应用开发者,这是不应该的,你辛辛苦苦收集的数据转眼之间被其他人给抓取了,是不是很大的损失? Hashids的介绍 gen ...

  5. Python之面向对象多态

    Python之面向对象多态 多态与多态性: 多态: 多态是指一类事物有多种形态,一个抽象类有多个子类,因而多态的概念依赖于继承. 1.序列类型有多种形态:字符串.列表.元组. 2.动物有多种形态:Pe ...

  6. 【tips】RESTful架构

    认识RESTful在前后端分离的应用模式里,后端API接口如何定义?例如对于后端数据库中保存了商品的信息,前端可能需要对商品数据进行增删改查,那相应的每个操作后端都需要提供一个API接口:    PO ...

  7. 全文检索(AB-1)-相关领域

    信息检索 认知科学 管理科学

  8. 运算符、流程控制、while循环

    运算符: 1. 算术运算符: “ + ”.“ - ” .“ * ” .“ / ” 分别为加.减.乘.除. # % 是“取模运算符”,就是返回除法的余数.eg. a = 3, b=5, b % a 就是 ...

  9. Oracle锁表数据查询及解决方法

    首先:查询数据那些表被锁定1. SELECT l.session_id sid, s.serial#, l.locked_mode,l.oracle_username, l.os_user_name, ...

  10. [USACO08NOV]时间管理Time Management

    题目描述 Ever the maturing businessman, Farmer John realizes that he must manage his time effectively. H ...