Shaman.com原創資料,作者:w3sft,如轉載請保留此信息。
為了保護版權、防截圖、防拍照等,有些我們會給網頁中的視頻、圖片或文字加水印。
實現的方式,可能有多種,比如:對圖片、視頻而言,可以在服務端完成水印,但對于文字信息類,一般只能在前端頁面中進行水印添加。
本文分享一種圖層式防刪水印技術。其效果是:在頁面渲染完成后,由JavaScript進行圖層水印添加,并會實時檢測水印狀態,如果水印被刪除、隱藏、或設置為透明,都會重置水印。
<html>
<body>
<div id="content" style="padding:10px;">
<h2>防刪文字水印</h2>
水印內容不可刪除,如檢測到被刪除,會重新添加水印
</div>
<script>
function add_water_canvas(){
//水印canvas
var water_canvas = document.createElement("canvas");
water_canvas.id = "water_canvas";
water_canvas.height = 100;
water_canvas.width = 300;
water_canvas.style.top = 100 + "px";
water_canvas.style.left = 100 + "px";
water_canvas.style.position = "absolute";
water_canvas.style.transform = "rotate(-45deg)";
//水印內容
var water_text = water_canvas.getContext("2d");
water_text.font = "26px 黑體";
water_text.fillText("水印內容", 30, 50);
//canvas容器:水印目標
var canvas_container = document.getElementById("content");
canvas_container.style.height = 280 + "px";
canvas_container.style.width = 500 + "px";
canvas_container.style.backgroundImage = "url(bg.png)";
//添加水印canvas給目標div
canvas_container.appendChild(water_canvas);
}
add_water_canvas();
var observer = new MutationObserver(function(mutations){
mutations.forEach(function(mutation){
if(mutation.removedNodes.length > 0 && mutation.removedNodes[0].id == "water_canvas") {
console.log("檢測到水印被刪除,已重新添加水印");
//重新添加水印
add_water_canvas();
}
if (mutation.type == "attributes" && mutation.target.id == "water_canvas") {
console.log("檢測到水印屬性被修改,已重置屬性");
water_canvas.style.display = "block";
water_canvas.style.opacity = 1;
}
});
});
observer.observe(document.body, {
childList: true,
attributes: true,
subtree: true,
attributesOldValue: true,
characterData: true,
characterDataOldValue: true,
});
</script>
</body>
</html>
添加水印的方式平平無奇,只是新建了一個canvas圖層,在圖層中疊加水印內容。
取巧的是用MutationObserver對水印進行監控和重置。MutationObserver是一個很有創意的接口,它可以監聽頁面元素變化,任何元素的修改,如節點的增減、屬性值更新、文本內容的改動都會觸發MutationObserve事件,在本例中,會監測兩種事件:節點刪除、節點屬性發生變化。
如,刪除水印節點:
刪除時觸發事件,時此會還原節點、重置水印:
如,結點屬性被修改(修改display為none使元素不可見,或修改opacity為0使元素完全透明),都會觸監聽事件,并重置節點屬性:
其實應用于產品或項目時,可將JS代碼用JShaman進行混淆加密,以防止代碼被分析識破從而被針對性的反制。
注:本文演示中是給div添加水印,實際應用此技術時,水印可添加給任意種類的元素內容。
上周五,出差去改上個前端遺留的小問題,用到了watermark.js這個網站添加水印插件,功能很簡單,就是給網頁添加個水印,我看了下網上,有很多種,基本都是Canvas實現,我想要的是行與行之間交錯效果,可是沒有找到對應文檔,看的煩的...
那就自己簡單寫個網頁添加水印插件吧, tp-watermark.js
身為初級前端,寫法比較low,但是功能很完善,請大家多多指導
下載插件:https://qzhan.lanzous.com/iP9effhq7af
DEMO下載:https://qzhan.lanzous.com/i7le1fhq7lg
下載完引入插件
RemoveTpWatermark();
RemoveTpWatermark();
很方便使用,一列顯示幾行,一行顯示幾列都是計算的,大家不用自己定義(具體需要的參數已添加注釋)。
// 添加水印方法
function TpWatermark(CON,H,W,R,C,S,O) {
// 判斷水印是否存在,如果存在,那么不執行
if (document.getElementById('tp-watermark') != null) {
return
}
var TpLine = parseInt(document.body.clientWidth/W) * 2; // 一行顯示幾列
var StrLine = '';
for(var i = 0; i < TpLine; i++){
StrLine += '<span style="display: inline-block; line-height:' + H + 'px; width:' + W + 'px; text-align: center; transform:rotate(' + R + 'deg); color:' + C + '; font-size:'+ S + 'px; opacity:' + O + ';">'+ CON +'</span>'
}
var DivLine = document.createElement("div");
DivLine.innerHTML = StrLine;
var TpColumn = parseInt(document.body.clientHeight/H) * 2; // 一列顯示幾行
var StrColumn = '';
for(var i = 0; i < TpColumn; i++){
StrColumn += '<div style="white-space: nowrap;">' + DivLine.innerHTML + '</div>';
}
var DivLayer = document.createElement("div");
DivLayer.innerHTML = StrColumn;
DivLayer.id = "tp-watermark"; // 給水印盒子添加類名
DivLayer.style.position = "fixed";
DivLayer.style.top = "0px"; // 整體水印距離頂部距離
DivLayer.style.left = "-100px"; // 改變整體水印的left值
DivLayer.style.zIndex = "99999"; // 水印頁面層級
DivLayer.style.pointerEvents = "none";
document.body.appendChild(DivLayer); // 到頁面中
}
// 移除水印方法
function RemoveTpWatermark(){
// 判斷水印是否存在,如果存在,那么執行
if (document.getElementById('tp-watermark') == null) {
return
}
document.body.removeChild(document.getElementById('tp-watermark'));
}
// 執行添加
TpWatermark('水印','170','400','-20','red','70','.15');
// TpWatermark(CON,H,W,R,C,S,O); // 值一一對應
CON => 水印文字內容
H => 水印行高
W => 水印寬度
R => 旋轉度數(可為負值)
C => 水印字體顏色
S => 水印字體的大小
O => 水印透明度(0~1之間取值)
// 執行移除
RemoveTpWatermark();
水印行與行之間需要交錯顯示,需添加css代碼(padding-left的交錯值,設置的水印寬度的一半即可)
/*通過此樣式,控制行與行之間的交錯顯示 為0則不交錯*/
#tp-watermark div:nth-child(2n){
padding-left: 200px;
}
給鵬仔添加關注,后期版本會更新針對板塊來添加水印。
、 代碼開發版實現方法
常規代碼實現思路是:
1)web 頁面加載后,通過 javascript 創建頁面元素 div,并在 div 元素中創建文本節點,展示水印內容
2)設置 div 元素樣式,將其 zIndex 設置一個較高的值,并設置透明度,實現浮在頁面的水印效果
代碼開發時需要考慮頁面自適應時寬高改變的情況,同時還需要保證不能影響頁面的原有事件功能,需要綜合考慮的細節比較多。
2、 懶人版實現方法
使用內置水印功能的報表工具,通過簡單屬性配置完成水印效果。
1)文字水印實現可以通過配置水印屬性:
文字要動態變化的話,只需要改為配置表達式就可以啦:
具體操作可以參考 http://c.raqsoft.com.cn/article/1567379764933
實現效果如下圖所示:
2)logo 水印在報表工具中的實現也很簡單,配置下圖片屬性就可以了:
具體操作可以參考 http://c.raqsoft.com.cn/article/1571639241616
實現效果如下圖所示:
使用報表工具不僅可以快速便捷的實現水印功能,還能給前端工程師帶來很多方便之處,例如一些前端效果(數據隔行異色顯示、點擊表頭排序等)可以直接使用工具實現,不用再寫前端代碼,減少了自己的代碼工作量;另外同時也避免了因為需求變更導致的代碼重新調整。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。