昨天写的篇文章 中,无意间发现 从 Flickr 右键下载的图片 竟然不是原图。好奇心起,于是就分析起其机制。

https://friable.rocks/_/2009_11_05/0115255fba53.jpg

原来在它的原图上层,再浮动了与其同宽高的一个像素的透明 GIF 图片。这样,当用户右键点击「图片另存为」时,保存的就是其一像素的 GIF 图片。

这个方法虽然是能防「君子」,但相比 Flash (甚至 ActiveX)等措施,对于客户端的资源占用少了许多。职业病,我考虑的是脚本上的实现。

在不长的时间,这个脚本就实现了, 看下 DEMO 或者 打包下载 (用法参见页面)。

不过还是出现了几个问题,在这里提下

var m = document.createElement('img');
var element = document.getElementById(element).getElementsByTagName("img");
for(var i = element.length - 1; i >= 0; i--) {
    this.insertAfter(element[i], m.cloneNode(true));
}

本来的写法是

var m = document.createElement('img');
var element = document.getElementById(element).getElementsByTagName("img");
for(var i = 0; i < element.length; i++) {
    this.insertAfter(element[i], m.cloneNode(true));
}

出现的问题是 新创建的图片只会插入到第一章图片的后面。

感谢 圆心 同志的排查,原来是插入图片时,新插入的图片节点被加入,导致原先图片节点 length 发生变化

换个迭代方式就能解决这个问题。

if (document.documentElement.getBoundingClientRect)  {
    var box = targetElement.getBoundingClientRect();
    maskImage.style['top']  = box.top + "px";
    maskImage.style['left'] = box.left + "px";
} else {
    maskImage.style['top']  = targetElement. + "px";
    maskImage.style['left'] = targetElement.offsetLeft + "px";
}

依旧 很「暴力」的一段代码,主要功能是获取元素在页面中的位置。PPK 告诉我们,尽量避免因兼容性问题,而去检测浏览器类型。

附,看下 YUI 在这方面是怎么做的