無標題文檔

「阻挠」用户下载图片

昨天写的篇文章 中,无意间发现 从 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 在这方面是怎么做的

Javascript 悬停弹出框

由于项目的需要,要做一个鼠标悬停显示信息的效果。坦白说,我这个部件我不想使用框架实现,原因是太臃肿了。

在代码库里面找到了些类似的代码(本人为业余的 Javascript 开发人员),但发现都非常的散乱,于是我就尝试重写它们。

https://friable.rocks/_/2009_11_05/95824556d667.jpg

先看下 DEMO ,打包以后的文件可以在 这里 下载。

用法很简单,就是在函数参数中选择容器的 id(或者是节点集合),然后代码就会将容器中 a 元素的 title 和链接以泡框的形式弹出。

下面,说下碰到的些值得回味的代码(格式是我重写以后的)。

_addCssFile : function (css_file) {
    var l = document.createElement("link");
    l.setAttribute("type",  "text/css");
    l.setAttribute("rel",   "stylesheet");
    l.setAttribute("href",  css_file);
    l.setAttribute("media", "screen");
    document.getElementsByTagName("head")[0].appendChild(l);
},

用 Javascript 载入外部样式文件,建议在 DOM Ready 以后运行。

_setOpacity: function (oNode) {
    oNode.style.filter       = "alpha(opacity:85)";
    oNode.style.KHTMLOpacity = "0.85";
    oNode.style.MozOpacity   = "0.85";
    oNode.style.opacity      = "0.85";
},

强行设置元素的属性,不像 YUI 这样 小心翼翼的先判断后操作 ,再设置。我等草根的写出来代码,虽然「暴力」,但是实用。

类似的,还有

var posx = 0, posy = 0;
if(e == null) {
    e = window.event;
}

if(e.pageX || e.pageY) {
    posx=e.pageX; posy=e.pageY;
} else if(e.clientX || e.clientY) {
    if(document.documentElement.scrollTop){
        posx = e.clientX + document.documentElement.scrollLeft;
        posy = e.clientY + document.documentElement.scrollTop;
    } else {
        posx = e.clientX + document.body.scrollLeft;
        posy = e.clientY + document.body.scrollTop;
    }
}

获取当前元素的坐标 -- 写过类似功能的朋友,应该对此段代码很熟悉。

不要忘记跨域 iframe 的载入情况

在编写某个 跨域的 Ajax 调用 功能时,出现了个匪夷所思的问题,就是无法载入 iframe 中的连接器(YAHOO.util.Connect),代码和操作无任何的问题。

在麻烦了 圆心 同志 N 遍以后,发现原来是 iframe 没有完全载入,框架中的代码没有运行的缘故。(在这里再次感谢下他,Orz)

这的确是个非常普遍的问题,由于网速的缘故,往往父页面载入完成,而 iframe 中的内容还正在读取。这个时候,父页面调用子页面中的对象时,就会发生问题。

我想到了个变通的办法,就是「等待」子页面载入完成以后,再去尝试运行。如果子页面还没有载入相应的对象,那么就「再等待」一段时间再去尝试。

可能表述上有所欠缺,我们还是看具体的代码。

为了理解,首先说明已经在 HTML 中已经包含了此 iframe,并子页面中也包含了 YUI 的框架代码及相应的控件。

<iframe src="http://.../proxy.htm" id="proxy"></iframe>

下面是相应的 Javascript 代码

var proxy = $('proxy').contentWindow;
Controler.disable = true;  // 获取数据此段期间,禁止用户输入
if (typeof proxy.YAHOO == 'undefined') {
    // 等待一段时间再去尝试,Function 为父类的名称
    setTimeout(function() {Function.get(URL)}, 100); 
    return;
}

// 已经得到子页面对象,获取数据
proxy.YAHOO.util.Connect.asyncRequest('GET', URL, {
    success: function(req) {
        alert(req.responseText);
        Controler.disable = false; // 恢复用户输入
    },

    failure: function() {
        return false;
    }
});

不过这个代码还有很多的问题,目前所能预见到的,就是客户端的资源占用问题。可想而知,如果反复的请求数据对于浏览器来说,资源花销将是非常大的。

大家如果有更好的办法,不妨说说。

我的照片

嗨!我叫「明城」,八零后、码农、宁波佬,现居杭州。除了这里,同时也欢迎您关注我的 GitHubTwitterInstagram 等。

这个 Blog 原先的名字叫 Gracecode.com 、现在叫 「無標題文檔」 。 要知道作为码农取名是件很难的事情,所以不想在取名这事情上太费心思。

作为八零后,自认为还仅存点点可能不怎么被理解的幽默感,以及对平淡生活的追求和向往。 为了避免不必要的麻烦,声明本站所输出的内容以及观点仅代表个人,不代表自己所服务公司或组织的任何立场。

如果您想联系我,可以发我邮件 `echo bWluZ2NoZW5nQG91dGxvb2suY29tCg== | base64 -d`

分类

搜索

文章