不安全的js写法

一种很常见的写法:

document.write('<scr'+'ipt src="http://a.com/b.js" type="text/javascript"></scr'+'ipt>');

直到被杀毒软件提示有恶意代码才发现这也是不安全的,汗……

那就只好改成这样了:

(function() {
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.src = 'http://a.com.cn/b.js';
    document.getElementsByTagName('head')[0].appendChild(s);
})();

搜了一下,原来还有“邪恶”的eval,具体可以看这里:网马解密大讲堂——网马解密中级篇(Document.write篇)。…

全新极速CSS选择器引擎whiz

好不容易有些空余时间,便拿来写自己的CSS选择器引擎了,这个CSS选择器引擎的目标只有三个:

  • 速度要快
  • 代码要精简
  • 要支持CSS3的选择器。

希望通过这个,能够真正理解那些牛逼的框架中的一部分,比如jQuery,Mootools,YUI等等。花了接近三个星期的时间,大重构了三遍,从最开始的速度极低到现在的极速,每一次都是大换血。在这个过程中,我看到了那些大师写代码的境界,即使我完成了这样一个东西,代码依然很难看。要做一个CSS选择器并没有你想像的那么难,也并不复杂。

大家可能看完性能测试才会有兴趣,下图是一个较全的性能测试结果,大家可以在这里测试,大家可以自己跑一跑看(由于加载的东西较多,请耐心等待一会儿再点start按钮)。

代码量目前还没达到我满意的程度,不过已经足够小了,Gzip之后仅仅只有2KB(YUICompressor压缩之后为8.61K(win NTFS)),另外,针对Firefox 3, Opera…

用书签压缩你当前访问的页面地址

正式开始twitter了,我的twitter地址是:http://twitter.com/xushengs,欢迎加入!

由于twitter的字数有限制,因此把长URL压缩成短URL是非常非常必要的。不过,你是不是因为压缩的工作而烦恼,要复制地址,然后粘贴,然后再复制,再粘贴?用书签来替你完成前面的工作吧!

把下面的这个地址拖到你的书签栏就OK了:

Compress URL

如果不能拖到书签栏,请新建一个书签或者把当前页面加入收藏,然后更改这个书签的属性,把URL地址更改为:

javascript:void(function(){var r='http://is.gd/api.php?longurl='+encodeURIComponent(location.href),x=function(){if(!window.open(r,'ShortURL','toolbar=0,resizable=1,scrollbars=yes,status=1,width=320,height=240'))location.href=r};if(/Firefox/.test(navigator.userAgent)){setTimeout(x,0)}else{x()}})()

关于Math.PI、前自增和后自增

有这么一个题目,说bt其实也不bt,为了重点突出其中的意图,特意加上了括号:

var a = (++Math.PI);
var b = (Math.PI++);
var c = Math.PI = (++Math.PI);
var d = Math.PI = (Math.PI++);
var e = Math.PI = (Math.PI + 1);

执行完后,a、b、c、d、e的值分别是什么呢?如果学校里学的C语言基础好的话,应该可以知道答案。你不妨先写下答案,我们再来看看ECMA的规范。

在ECMA-262中,对于Math.PI的说明是这样的:

15.8.1.6

The number value for π, the ratio of the circumference of a circle to its diameter, which is approximately 3.1415926535897932.

This property has the attributes { DontEnum, DontDelete,

在IE下获取object(ActiveX)的Param

在IE下,获取Param的时候有个诡异现象(不知道算不算bug)。为了清晰起见,下面用最简单的HTML和JavaScript来说明。有这么一段HTML(head部分是标准的head,doctype使用xhtml-transitional的DTD):

<body>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" width="100%" height="100%">
  <param name="movie" value="Test.swf"

在Chrome下使用User Scripts和豆瓣插件

首先要解决Chrome下使用User Scripts的问题。这个功能在Chrome 2中已经支持了,不过没有开启,要自己手动开启。这个教程很多,整理一段在这里:

1.安装最新的Chrome 2

以下是下载地址,随便挑一个吧:
http://download.tech.qq.com/soft/1/2/45974/index.shtml
http://www.google.com/intl/en/landing/chrome/beta/

2.切换Chrome到dev分支

下载chrome channel switcher即可,下载地址:
http://download.pchome.net/internet/browser/companions/detail-142198-0.html

提示:如果切换到dev版本后不稳定(目前为止,我这里还没出现过异常情况),还可以通过这个方式切换回来。

3.建立User Scripts文件夹

一些让你目瞪口呆的JavaScript应用

Google Chrome凭借其强大的V8引擎,让我们有机会领略异常惊人的JavaScript应用,领略JavaScript的超级魅力!点击这里进入Chrome实验网站,体验JavaScript的炫酷

注:尽管Firefox也能看,但是效果远远没有Chrome流畅,因此,如果你想看,最好装上一个Google Chrome,很好用的。Chrome的下载页面:http://www.google.com/chrome

另外,Google Chrome开始支持扩展,尽管其第一个插件仅仅只能更改Google主页的Logo,但是其意义绝远不止于此。

如果你有兴趣开发Google Chrome的插件,可以参考这里的文档。…

实验品:所见即所得在线编辑器

不忙的时候,抽空写的这个,目标很远大,不过可能就要到此为止了,如果哪天我的blog想换编辑器了,可能会再弄弄,呵呵~当然,如果你有兴趣,可以继续完善。UI来源于新浪博客的编辑器,在原有的基础上增加了部分按钮。目前兼容的浏览器列表(只做了一些非常简单的测试,如有错误,请及时告诉我,谢谢^_^):

  • IE 6, IE 7, IE 8
  • Firefox 3
  • Opera 9.6
  • Safari 3
  • Chrome 0.3

编辑器测试地址:点击这里查看

先说好听的,除了支持简单的HTML标签外,目前比较特别的功能:

  • 支持插入各种形式的多媒体内容:图片、flash、各种音视频
  • 支持多种表格操作:插入删除表格、插入删除行和列
  • 支持插入多种特殊字符和表情
  • 自动排版:清除段落开头和结尾的多于空白字符,并缩进两字符(来自新浪的创意)

现在还剩下的比较严重的问题:

  • 粘贴、剪切和复制只能在IE下使用,Safari和Chrome下只支持剪切和复制,其他浏览器下这三个功能完全失效,有待寻求解决方案

为什么JavaScript中正则表达式的test方法会出错?

一段这样的JavaScript代码,猜猜结果如何?

var i = 0, m = 20, a = [], r = /^\d+$/g;
for(i = 0; i < m; i++){
    a.push('' + i);
}

m = a.length;
for(i = 0; i < m; i++){
    if(r.test(a[i])){
        document.write(a[i] + 'true<br />');
    }
    else{
        document.write(a[i] + 'false<br />');
    }
}

也许你期待的结果应该全是true,可是实际结果呢?true和false交替出现,0是true,1是false,2是true,3是false……是不是很怀疑?其实仔细看一下,那个正则表达式多了个全局选项“g”,去掉就好了。

可是为什么有“g”就会出错呢?

原因其实很简单,当一个模式具有全局选项时,和exec一样,每次test都会保留上次匹配的位置——即lastIndex。很显然,当第一次匹配之后,第二次匹配时的lastIndex已经到了字符串末尾,尽管这个时候字符串已经是一个新的字符串了,但是这个lastIndex的位置并没有重新初始化,所以会从末尾开始匹配——当然会匹配失败了。…

其实AS和JS互相调用有个很酷的特性

JavaScript和ActionScript互相调用时,其实有个非常好的特性,不过貌似很少有人提到这个特性:它们之间的数据类型对方均可以识别。因此,你可以通过swf提供的接口来传递对象、数组、字符串等等。不过它们之间传递的参数的值的长度有限制(具体长度还没仔细测试),因此你不能把JavaScript中的一个超大的对象直接传递进去。不过即使是这样,已经非常好用了,看看示例代码:

AS(ActionScript)代码:

// 创建一个行的TextField来显示调用结果
var t:TextField = new TextField();
t.x = 10;
t.y = 10;
t.width = 300;
t.height = 200; 
this.addChild(t);

// 这个是要给JavaScript调用的函数
function test(obj){
    var s = [];
    for(var p in obj){
        s.push(p + ': ' + obj[p]);