大家都知道FaceBook发明了BigPipe,把页面分为多个PageLet来加载,让服务端运算与客户端加载并行进行,使得页面可交互时间往前提了不少。我这里不谈如何实现BigPipe,而是分析下FaceBook如何处理不支持JavaScript的场景。
对于不支持BP的浏览器,服务端必须一次生成所有HTML,每个模块用到的JS和CSS也需要合并。那怎么让服务器尽早知道客户端不支持JS呢?FaceBook的办法是在BP模式的HTML里加上了NoScript标签和Meta跳转:
<noscript><meta http-equiv="refresh" content="0; URL=/?_fb_noscript=1" /></noscript>
这样,如果用户的浏览器不支持JS,那访问FaceBook的任何一个页面,都会重定向原URL,并带上_fb_noscript=1这个参数。接着,服务端根据这个标记就可以按照非BP模式输出完整的页面。
如果用户访问每一个页面都需要多一次重定向,是不是很浪费时间和带宽呢?确实如此!FaceBook已经考虑到这个问题了:服务端在收到_fb_noscript=1标记时,会给客户端设置noscript=1的Cookie,这样下次请求哪怕没有URL参数标记,服务端也可以根据Cookie标记适配到非BP模式。
但是,如果客户端突然又支持JS了呢?这种情况多半是在测试,理论上继续用非BP模式也没什么问题,但FaceBook还是很厚道的处理了这种情况:在非BP模式的HTML里有这么一段JS:
很早之前,写过一篇“跨浏览器“复制到剪贴板”的解决方案”,当时给出的解决方案是,IE使用window.clipboardData,firefox等其它浏览器使用flash来调用System.setClipboard方法。但是,随着Flash10安全策略更新,只允许在flash内部调用setClipboard方法,那篇文章给出的demo已经失效。我重新写了一个demo,见这里。
新demo是在flash内部调用的setClipboard方法,原则上安装了flash的浏览器都可以用;另外,IE7及以上版本用js调用clipboardData会弹出选择是否允许的提示,往往初级用户看到这样提示还以为网站有病毒,所以这次一视同仁所有浏览器都用flash写剪切板。原理比较简单,大概说一下:
完整的代码见这里。如果要个性化提示文字,打开clipboard.as,修改后编译即可。
本文链接:http://www.imququ.com/post/38.html
--EOF--
Opera是一个来自挪威的浏览器,有着优秀的缓存机制,浏览网页速度很快,有着自己庞大的粉丝群。但是opera并没有支持上下文菜单事件,也就是说我们通常使用的依靠在页面中重写oncontextmenu事件来实现自定义右键菜单的方法不会工作。那么,有没有别的方法来实现自定义菜单呢?
我们来看看三个著名的产品(Fckeditor、YUI、Google Doc)怎么解决opera没有oncontextmenu事件这个问题:
Fckeditor:Fckeditor这个开源的编辑器我想不用多介绍了吧,它的最新版本已经支持了opera。那么它是怎么处理右键菜单的呢?分析源码可以知道,它注册了onmousedown事件,并且判断鼠标按下的是不是右键,如果是就显示自定义菜单。这样看似很完美,但是有两个致命的弱点:1.默认情况下opera是不检测鼠标右键点击的,也就是右键按下时根本不触发mousedown事件。除非在“工具”-“首选项”-”高级”-”内容”-“Javascript选项”中勾选“允许脚本检测右键单击”;2.opera自身的上下文菜单会跟自定义菜单一起出现,也就是说无法preventDefault。这个问题解决起来有一点点巧妙,经过实验我们可以发现,opera下在type等于button的input上点击右键不会出现系统上下文菜单,于是我们可以在mousedown时在鼠标下放一个几乎透明的type=button的input,再在mouseup的时候隐藏这个button。
YUI的MENU组件:YUI是一个先进的界面库,功能强大,使用简便。那么他是怎么解决这个问题的呢?相比于FCKEditor,YUI换了另外一种思路,既然Opera默认不支持检测右键点击,那就用左键点击来代替总可以吧,但是这样显然会干扰用户正常操作,于是YUI又加了一条规则,按下ctrl键的同时点击左键才等同于右键。“Hold down the control key and click with the left mouse button.”
Google Doc:Google出品的web office套件。Google的技术不用怀疑,那么他是怎么解决这个问题的呢?答案是:既然不能完美解决,干脆就不解决。反正Google Doc的所有操作都不是只有右键菜单才能完成。不愧是Google!
本文链接:http://www.imququ.com/post/62.html
--EOF--
众所周知,firefox的安全性比较高,但是安全带来的弊端就是很多功能不支持。比如说在IE下可以通过脚本来设当前网页为首页,firefox却不行。今天要讨论的是另外一个问题:怎么在firefox等不支持window.clipboardData的浏览器下实现复制呢?
首先,我们来看网易邮箱是怎么解决这个问题的。我们在firefox下进到写邮件页面,点击编辑器上的全部功能,然后点击左边的“复制”按钮,“您的浏览器安全设置不允许编辑器自动执行拷贝操作,请使用键盘快捷键(Ctrl C)来完成”,网易邮箱给了我们这么一个提示。我觉得这个解决方案可以得80分,因为它告诉了我们两个信息:其一,之所以复制操作没有完成是因为我的浏览器很安全,为了安全损失一点用户体验一般用户是可以接受的;其二,它还提示了我们可以通过键盘快捷键ctrl c来完成操作,这对刚上网的新手来说很人性化。但是,有没有更好的解决方案呢?
网上大致有两种解决方案,一种是需要修改firefox配置,其实firefox也是支持复制的,但是需要到about:config里去手动开启,这里不做介绍了;另外一种解决方案是本文要用到的flash。因为flash可以方便的把文字拷贝到系统剪切板中,所以我们利用flash来做跳板,只需要一行代码就能搞定:
System.setClipboard(clipboard);
这句代码的含义后面还会提到。有了这个swf的跳板,剩下的工作就简单了,如果浏览器不支持window.clipboardData,就在复制的时候把内容传给这个flash,就OK了,关键代码如下:
if (window.clipboardData){
window.clipboardData.setData("Text",str);
}else{
var flashId = '_clipboard_';
var flashContent = '<embed src="clipboard.swf" FlashVars="clipboard=' str.replace(/\ /g,"+") '" width="0" height="0" type="application/x-shockwave-flash"></embed>';
if(!document.getElementById(flashId)){
var flash = document.createElement("div");
flash.id = flashId;
flash.innerHTML = flashContent;
document.body.appendChild(flash);
}else{
document.getElementById(flashId).innerHTML = flashContent;
}
} adobe的文档中对setClipboard有如下解释:
setClipboard () 方法
public static function setClipboard(string:String):void
语言版本 : ActionScript 3.0
Player 版本 : Flash Player 9 用指定的文本字符串替换剪贴板的内容。
注意:出于安全方面的考虑,您无法读取系统剪贴板的内容。 换句话说,不存在相应的
System.getClipboard()方法。参数
string:String— 要放置在系统剪贴板上的纯文本字符串,用于替换系统剪贴板上的当前内容(如果有)。
由此可见,我们只能利用flash把文字复制到系统剪贴板中,而不能把系统剪切板中的内容拷贝出来。
本文链接:http://www.imququ.com/post/61.html
--EOF--