<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.army8735.org/styles/temp01.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link href="http://feed.army8735.org" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/army8735" type="application/rss+xml"></fs:self_link><lastBuildDate>Thu, 11 Mar 2010 07:39:34 GMT</lastBuildDate><title>army8735</title><description>做一颗可爱的小土豆～ ^ ^</description><link>http://army8735.org</link><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><language>en</language><pubDate>Thu, 11 Mar 2010 07:41:09 GMT</pubDate><item><title>Project Darkstar虽死，RedDwarf Server已活</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340657493/5961215/1/item.html</link><content:encoded>&lt;p&gt;Sun被Oracle收购后，停掉了不少开源项目，其中就有我关心的《Project Darkstar》。今日突发奇想又登录了下老的网站主页，发现关闭之后多出了一个链接：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.reddwarfserver.org/&quot;&gt;http://www.reddwarfserver.org/&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;哦也，开源之火生生不息！目前的0.10.0版本其实就是Project Darkstar停之前最新的发布版本。期待你的表现，&lt;a href=&quot;http://www.david0446.com/&quot; target=&quot;_blank&quot;&gt;某人&lt;/a&gt;赶快给我研究去……嘿嘿……&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340657493/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340657493/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340657493/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340657493/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/03/11/731.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>Sun被Oracle收购后，停掉了不少开源项目，其中就有我关心的《Project Darkstar》。今日突发奇想又登录了下老的网站主页，发现关闭之后多出了一个链接：
http://www.reddwarfserver.org/。
哦也，开源之火生生不息！目前的0.10.0版本其实就是Project Darkstar停之前最新的发布版本。期待你的表现，某人赶快给我研究去……嘿嘿……&lt;img src=&quot;http://www1.feedsky.com/t1/340657493/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340657493/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340657493/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340657493/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>其它</category><pubDate>Thu, 11 Mar 2010 15:39:34 +0800</pubDate><author>army</author><comments>http://army8735.org/2010/03/11/731.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=731</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2010/03/11/731.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340657493/5961215</fs:itemid></item><item><title>TUI: Tudou’s Javascript Library</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340427333/5961215/1/item.html</link><content:encoded>&lt;p&gt;这是由Dexter同学厚积薄发的作品，分为第三方类库、核心、输入输出、视图、界面组件、工具以及插件等几大部分。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://army8735.org/wp-content/uploads/2010/03/tui.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-726&quot; title=&quot;tui&quot; src=&quot;http://army8735.org/wp-content/uploads/2010/03/tui-174x300.png&quot; alt=&quot;&quot; width=&quot;174&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340427333/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427333/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427333/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427333/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/03/09/723.html/feed</wfw:commentRss><slash:comments>2</slash:comments><description>这是由Dexter同学厚积薄发的作品，分为第三方类库、核心、输入输出、视图、界面组件、工具以及插件等几大部分。&lt;img src=&quot;http://www1.feedsky.com/t1/340427333/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427333/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427333/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427333/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>tui</category><category>前端开发</category><pubDate>Tue, 09 Mar 2010 09:59:18 +0800</pubDate><author>army</author><comments>http://army8735.org/2010/03/09/723.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=723</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2010/03/09/723.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340427333/5961215</fs:itemid></item><item><title>JAcld beta1</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340427588/5961215/1/item.html</link><content:encoded>&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/jacld/&quot;&gt;http://code.google.com/p/jacld/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;预览地址：&lt;a href=&quot;http://jacld.googlecode.com/svn/trunk/bin/index.html&quot;&gt;http://jacld.googlecode.com/svn/trunk/bin/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;JAcld(Javascript &amp;amp; Actionscript CapsLock Detection)是一款基于as和js的大写锁定检测工具，大小只有1k多，作用于web上。&lt;/p&gt;
&lt;p&gt;今天终于搞定了针对webkit的特殊修正，所以目前主要浏览器都能使用了。不过还有2点遗憾：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;webkit由于flash的聚焦bug，无法通过flash检测，因此使用了js检测。它跟flash相比起来体验方面要稍微差一点。&lt;/li&gt;
&lt;li&gt;ie下亦存在聚焦问题，当使用tab键切换focus到输入框上时，有一定几率聚焦失败。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;综合而言beta1倒是可以尝试使用的。谁能研究出搞定那2个bug的方法就谢天谢地了……&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340427588/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427588/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427588/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427588/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/03/07/708.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>http://code.google.com/p/jacld/
预览地址：http://jacld.googlecode.com/svn/trunk/bin/index.html
JAcld(Javascript &amp;#38; Actionscript CapsLock Detection)是一款基于as和js的大写锁定检测工具，大小只有1k多，作用于web上。
今天终于搞定了针对webkit的特殊修正，所以目前主要浏览器都能使用了。不过还有2点遗憾：

webkit由于flash的聚焦bug，无法通过flash检测，因此使用了js检测。它跟flash相比起来体验方面要稍微差一点。
ie下亦存在聚焦问题，当使用tab键切换focus到输入框上时，有一定几率聚焦失败。

综合而言beta1倒是可以尝试使用的。谁能研究出搞定那2个bug的方法就谢天谢地了……&lt;img src=&quot;http://www1.feedsky.com/t1/340427588/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427588/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427588/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427588/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>前端开发</category><category>JAcld</category><pubDate>Sun, 07 Mar 2010 17:41:58 +0800</pubDate><author>army</author><comments>http://army8735.org/2010/03/07/708.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=708</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2010/03/07/708.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340427588/5961215</fs:itemid></item><item><title>[译]理解删除</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340427719/5961215/1/item.html</link><content:encoded>&lt;p&gt;&lt;a href=&quot;http://perfectionkills.com/understanding-delete/&quot;&gt;http://perfectionkills.com/understanding-delete/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;原文作者是在读&lt;a href=&quot;http://www.amazon.com/Object-Oriented-JavaScript-high-quality-applications-libraries/dp/1847194141&quot; target=&quot;_blank&quot;&gt;《Object-Oriented Javascript》&lt;/a&gt;的Function章节后有感，写下的一篇博文。&lt;/p&gt;
&lt;p&gt;书中有一句话：function其实就是一个普通变量——它可以被复制到另一个变量中而不会被删除。如果这样解释的话，这里有个例子：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;//army注：这一源代码片段是在Firebug下的Console控制台运行的，放在页面中需改写
var sum = function(a, b) {return a + b;}
var add = sum;
delete sum;
true
typeof sum;
&quot;undefined&quot;&lt;/pre&gt;
&lt;p&gt;忽略代码中省略的两个分号，你注意到这个代码片段的问题了吗？按那句话所说，删除sum不应该成功；delete语句返回的值不可能是true；typeof sum的结果不会是&amp;#8221;undefined&amp;#8221;。可是事实却非如此，所有的这一切都是因为：&lt;strong&gt;Javascript中不可能删除变量。至少不能以这种方式删除。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt;这是为什么呢？&lt;/p&gt;
&lt;p&gt;要回答这个问题，我们需要理解delete操作符是怎么运作的：即什么可以删除、什么不可以删除、为什么？&lt;/p&gt;
&lt;h3&gt;原理&lt;/h3&gt;
&lt;p&gt;我们为什么可以这样删除对象的属性？&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var o = { x: 1 };
delete o.x; // true
o.x; // undefined&lt;/pre&gt;
&lt;p&gt;但是变量就完全不同了：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var x = 1;
delete x; // false
x; // 1&lt;/pre&gt;
&lt;p&gt;方法声明也是：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function x(){}
delete x; // false
typeof x; // &quot;function&quot;&lt;/pre&gt;
&lt;p&gt;注意当一个属性&lt;strong&gt;不能被删除时&lt;/strong&gt;，它会返回false。&lt;/p&gt;
&lt;p&gt;要解释这些，我们首先要理解变量的实例化以及属性的特性——很遗憾，这些很少在Javascript书籍中被提到。下面这节将做个简明的介绍，它很容易理解。如果你不关心&lt;strong&gt;一切为何按照它目前的样子进行工作&lt;/strong&gt;的话，可以跳过此节。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;代码类型&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;在ECMAScript中共有3种执行方式：Global、Function、Eval。这些类型某种程度上正如其名，但还不足：&lt;/p&gt;
&lt;p&gt;当一份源代码作为程序运行时，它在全局作用域内执行，就会被认为是Global代码。在浏览器环境中，script标签通常被解析为一段程序，因此它是全局代码。&lt;/p&gt;
&lt;p&gt;直接运行在function内的代码显然是Function代码。例如浏览器中的&amp;lt;p onclick=&amp;#8221;&amp;#8230;&amp;#8221;&amp;gt;。&lt;/p&gt;
&lt;p&gt;另外，作为参数传入evel函数的源代码字符串会以Eval方式执行。我们很快就会看到其特殊性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; 运行上下文&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;当ECMAScript代码运行时，它是发生在一个运行上下文（execution context）中的。运行上下文是个抽象实体，可以帮助我们理解作用域和变量实例化是如何工作的。这3种代码各自有自己的运行上下文。当一个function执行时，就可以说控制器进入Function运行上下文中；当全局代码执行时，就进入了Global运行上下文。&lt;/p&gt;
&lt;p&gt;如你所知，运行上下文可以逻辑递归。首先一段代码肯定有自己的Global运行上下文；如果调用了function，那么function也有自己的运行上下文；如果function又调用了另外一个function……如此递归。甚至function调用了它本身，每次也会产生一个新的运行上下文。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;激活变量对象/激活对象&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;每一个运行上下文都和一个变量对象（Variable Object）相关联。类似运行上下文，变量对象是一个抽象实体，一种描述变量实例化的机制。现在有趣的事情来了，源代码中的变量和函数声明，实际上&lt;strong&gt;成为这个变量对象上的一组属性。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;当控制器进入Global方式的运行上下文时，一个全局对象被创建用来作为变量对象。这就解释了为何定义的全局方法成为了全局对象的属性。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;/* remember that `this` refers to global object when in global scope */
var GLOBAL_OBJECT = this;

var foo = 1;
GLOBAL_OBJECT.foo; // 1
foo === GLOBAL_OBJECT.foo; // true

function bar(){}
typeof GLOBAL_OBJECT.bar; // &quot;function&quot;
GLOBAL_OBJECT.bar === bar; // true&lt;/pre&gt;
&lt;p&gt;ok，当全局变量成为全局对象的属性时，方法内的局部变量发生了什么事情呢？行为是类似的：它们变成了一个变量对象的一组属性。唯一的不同之处在于，此处的变量对象不是全局对象，但仍然是个激活对象。激活对象在每次进入方法创建运行上下文时都会被创建。&lt;/p&gt;
&lt;p&gt;不仅function内的变量和方法声明会成为激活对象的属性，相同的事情还发生在传入的function参数身上，它在arguments下产生了一个Arguments对象。注意激活对象是内部机制，不能够被程序直接访问。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;(function(foo){

	var bar = 2;
	function baz(){}

	/*
	In abstract terms,

	Special `arguments` object becomes a property of containing function's Activation object:
	ACTIVATION_OBJECT.arguments; // Arguments object

	...as well as argument `foo`:
	ACTIVATION_OBJECT.foo; // 1

	...as well as variable `bar`:
	ACTIVATION_OBJECT.bar; // 2

	...as well as function declared locally:
	typeof ACTIVATION_OBJECT.baz; // &quot;function&quot;
	*/

})(1);&lt;/pre&gt;
&lt;p&gt;最后，eval中的变量声明会作为&lt;strong&gt;它被引用的上下文的变量对象的属性&lt;/strong&gt;。eval代码只是使用它被调用的运行环境的变量对象。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var GLOBAL_OBJECT = this;

/* `foo` is created as a property of calling context Variable object,
which in this case is a Global object */

eval('var foo = 1;');
GLOBAL_OBJECT.foo; // 1

(function(){

	/* `bar` is created as a property of calling context Variable object,
	which in this case is an Activation object of containing function */

	eval('var bar = 1;');

	/*
	In abstract terms,
	ACTIVATION_OBJECT.bar; // 1
	*/

})();&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;属性特性&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;终于说到这里了。现在我们已经清楚变量声明时发生的事情，剩下就是理解属性特性。每个属性可以有任意个以下特性——只读、不可枚举、不可删除、内部的。你可以把它们理解为属性上的选项——有或者没有。因为今天讨论的目的，这里只说不可删除特性。&lt;/p&gt;
&lt;p&gt;当声明变量或者函数时，它们成为变量对象（对于function代码来说是激活对象，对于全局代码来说是全局对象）的属性，这些属性产生的同时具有不可删除特性。然而，任何直接或者内部的属性分配在创建属性时都没有不可删除特性。这就是为什么有的属性可以删除有的不可以。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var GLOBAL_OBJECT = this;

/*  `foo` is a property of a Global object.
It is created via variable declaration and so has DontDelete attribute.
This is why it can not be deleted. */

var foo = 1;
delete foo; // false
typeof foo; // &quot;number&quot;

/*  `bar` is a property of a Global object.
It is created via function declaration and so has DontDelete attribute.
This is why it can not be deleted either. */

function bar(){}
delete bar; // false
typeof bar; // &quot;function&quot;

/*  `baz` is also a property of a Global object.
However, it is created via property assignment and so has no DontDelete attribute.
This is why it can be deleted. */

GLOBAL_OBJECT.baz = 'blah';
delete GLOBAL_OBJECT.baz; // true
typeof GLOBAL_OBJECT.baz; // &quot;undefined&quot;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;内建和不可删除&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;一个属性上的特殊特性控制了它能否被删除。注意一些内建的的属性一开始就有不可删除特性，它们是永远不能被删除的。例如arguments、函数实例的length属性等。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;(function(){

	/* can't delete `arguments`, since it has DontDelete */

	delete arguments; // false
	typeof arguments; // &quot;object&quot;

	/* can't delete function's `length`; it also has DontDelete */

	function f(){}
	delete f.length; // false
	typeof f.length; // &quot;number&quot;

})();&lt;/pre&gt;
&lt;p&gt;函数的形参同样也有不可删除特性：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;(function(foo, bar){

	delete foo; // false
	foo; // 1

	delete bar; // false
	bar; // 'blah'

})(1, 'blah');&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;未声明的分配&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;未声明的变量会在全局对象上生成属性，除非在作用域链中于全局对象之前找到这个变量声明。现在我们知道了属性分配和变量声明之间的区别——后者具有不可删除特性而前者没有——这就解释了为何未经声明的变量可以被删除。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var GLOBAL_OBJECT = this;

/* create global property via variable declaration; property has DontDelete */
var foo = 1;

/* create global property via undeclared assignment; property has no DontDelete */
bar = 2;

delete foo; // false
typeof foo; // &quot;number&quot;

delete bar; // true
typeof bar; // &quot;undefined&quot;&lt;/pre&gt;
&lt;p&gt;注意在属性创建时特性已经被定义了（除了ie），再次分配的话并不会修改已经存在的特性。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;/* `foo` is created as a property with DontDelete */
function foo(){}

/* Later assignments do not modify attributes. DontDelete is still there! */
foo = 1;
delete foo; // false
typeof foo; // &quot;number&quot;

/* But assigning to a property that doesn't exist,
creates that property with empty attributes (and so without DontDelete) */

this.bar = 1;
delete bar; // true
typeof bar; // &quot;undefined&quot;&lt;/pre&gt;
&lt;h3&gt;Firebug的困惑&lt;/h3&gt;
&lt;p&gt;那么在Firebug中发生了什么？为何在控制台console中的声明变量可以被删除？还记得前面说的吗，当eval代码进行变量声明时有个特殊的行为，这些声明的变量没有不可删除特性，所以它们可以被删除。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;通过eval删除变量&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;由于eval行为的特殊性，再加上ECMAScript允许我们删除没有不可删除特性的属性，在同一运行上下文中函数声明可以覆盖已经声明的变量。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function x(){ }
var x;
typeof x; // &quot;function&quot;&lt;/pre&gt;
&lt;p&gt;注意函数声明是如何获得优先权并覆盖掉原有变量声明的，这是因为函数声明的实例化晚于变量声明的实例化，并且允许覆盖。不仅如此，它还会覆盖属性特性。假如我们通过eval方式来声明函数，也会这样。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var x = 1;

/* Can't delete, `x` has DontDelete */

delete x; // false
typeof x; // &quot;number&quot;

eval('function x(){}');

/* `x` property now references function, and should have no DontDelete */

typeof x; // &quot;function&quot;
delete x; // should be `true`
typeof x; // should be &quot;undefined&quot;&lt;/pre&gt;
&lt;p&gt;不幸的是，我在尝试这段代码的时候失败了，可能哪里出了点错误。&lt;/p&gt;
&lt;h3&gt;浏览器的让步&lt;/h3&gt;
&lt;p&gt;原理已然弄清，实践更为重要。浏览器们都按照标准做了吗？答案是：大部分是。&lt;/p&gt;
&lt;p&gt;我对以下现代浏览器做了一个测试：Opera 7.54+、Firefox 1.0+、Safari 3.1.2+、Chrome 4+。&lt;br /&gt;
Safari 2.x和3.0.4在删除函数参数时有问题，这些属性看上去没有不可删除特性，因此它们竟被删除了。Safari 2.x的问题还不止这些——删除没有引用的变量（如delete 1，army注：我感觉这应该是常量才对）会抛出异常；函数声明具有可删除特性（变量声明没有）；eval中的变量声明有不可删除特性（函数声明没有）。&lt;/p&gt;
&lt;p&gt;类似的，Konqueror（3.5而非4.3）在删除没有引用的变量的时候会抛出异常，并且允许删除函数参数。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gecko的不可删除特性bug&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;基于Gecko 1.8.x的浏览器——Firefox 2.x、Camino 1.x、Seamonkey 1.x等等——有个很有趣的bug：可以删除一个属性的不可删除特性，尽管这个属性是通过变量声明或者函数声明而产生的。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function foo(){}
delete foo; // false (as expected)
typeof foo; // &quot;function&quot; (as expected)

/* now assign to a property explicitly */

this.foo = 1; // erroneously clears DontDelete attribute
delete foo; // true
typeof foo; // &quot;undefined&quot;

/* note that this doesn't happen when assigning property implicitly */

function bar(){}
bar = 1;
delete bar; // false
typeof bar; // &quot;number&quot; (although assignment replaced property)&lt;/pre&gt;
&lt;p&gt;让人震惊的是，IE5.5到IE8居然全部通过了测试！除了那个删除没有引用的变量外。然而即使如此，IE却在另外的方面有着严重的bug！这些bug很隐晦，和全局变量有关。&lt;/p&gt;
&lt;h3&gt;IE的bug&lt;/h3&gt;
&lt;p&gt;在IE中（至少是6到8版本），下面的表达式会抛出异常。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;this.x = 1;
delete x; // TypeError: Object doesn't support this action&lt;/pre&gt;
&lt;p&gt;再来看看另外一个，非常有趣：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var x = 1;
delete this.x; // TypeError: Cannot delete 'this.x'&lt;/pre&gt;
&lt;p&gt;这个情况看上去好像全局代码上的变量声明没有在全局对象上产生属性，甚至删除操作时会抛出异常。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;this.x = 1;

delete this.x; // TypeError: Object doesn't support this action
typeof x; // &quot;number&quot; (still exists, wasn't deleted as it should have been!)

delete x; // TypeError: Object doesn't support this action
typeof x; // &quot;number&quot; (wasn't deleted again)&lt;/pre&gt;
&lt;p&gt;与之相反的是，未声明变量却具有可删除特性。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;x = 1;
delete x; // true
typeof x; // &quot;undefined&quot;&lt;/pre&gt;
&lt;p&gt;但是你若通过this来引用全局的话却又会异常：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;x = 1;
delete this.x; // TypeError: Cannot delete 'this.x'&lt;/pre&gt;
&lt;p&gt;如果概括一下的话，那就是在全局代码中delete this.x从未成功过。&lt;/p&gt;
&lt;p&gt;我在2009年9月发现了的这一问题，Garrett Smith回答我说“IE中全局变量对象被实现为一个JScript对象，全局对象却被实现为一个宿主对象（host object）”。（army注：延伸阅读hax的文章：&lt;a href=&quot;http://hax.javaeye.com/blog/349569&quot; target=&quot;_blank&quot;&gt;http://hax.javaeye.com/blog/349569&lt;/a&gt;）&lt;/p&gt;
&lt;p&gt;我们可以通过一些测试在某种程度上验证这一回答。注意this和window看上去引用了同一对象（如果===全等操作符可以信赖的话），但是变量对象（函数返回的值）却和this不同。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;/* in Global code */
function getBase(){ return this; }

getBase() === this.getBase(); // false
this.getBase() === this.getBase(); // true
window.getBase() === this.getBase(); // true
window.getBase() === getBase(); // false&lt;/pre&gt;
&lt;h3&gt;删除和宿主对象&lt;/h3&gt;
&lt;p&gt;关于delete操作的规则如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果操作数中没有引用值，返回true&lt;/li&gt;
&lt;li&gt;如果对象没有直接属性，返回true&lt;/li&gt;
&lt;li&gt;如果属性存在并且具有不可删除特性，返回false&lt;/li&gt;
&lt;li&gt;其它情况，移除属性并且返回true&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然而，IE环境的delete操作在删除宿主对象时却经常让人捉摸不透。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;/* &quot;alert&quot; is a direct property of `window` (if we were to believe `hasOwnProperty`) */
window.hasOwnProperty('alert'); // true

delete window.alert; // true
typeof window.alert; // &quot;function&quot;&lt;/pre&gt;
&lt;p&gt;最好的习惯是从不信任宿主对象。&lt;/p&gt;
&lt;h3&gt;ES5严格模式&lt;/h3&gt;
&lt;p&gt;ECMAScript 5的严格模式带来了哪些条规？它引进了诸多限制。比如删除引用变量、函数参数和标志符的时候会抛出SyntaxError。另外，如果属性包含[[Configurable]] == false键值对，删除时会抛出TypeError。&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;(function(foo){

&quot;use strict&quot;; // enable strict mode within this function

var bar;
function baz(){}

delete foo; // SyntaxError (when deleting argument)
delete bar; // SyntaxError (when deleting variable)
delete baz; // SyntaxError (when deleting variable created with function declaration)

/* `length` of function instances has { [[Configurable]] : false } */

delete (function(){}).length; // TypeError

})();&lt;/pre&gt;
&lt;p&gt;还有，删除未声明变量时也会抛出SyntaxError：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;&quot;use strict&quot;;
delete i_dont_exist; // SyntaxError&lt;/pre&gt;
&lt;p&gt;这和在严格模式中使用未声明的变量类似：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;&quot;use strict&quot;;
i_dont_exist = 1; // ReferenceError&lt;/pre&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340427719/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427719/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427719/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427719/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/03/05/691.html/feed</wfw:commentRss><slash:comments>1</slash:comments><description>http://perfectionkills.com/understanding-delete/
原文作者是在读《Object-Oriented Javascript》的Function章节后有感，写下的一篇博文。
书中有一句话：function其实就是一个普通变量——它可以被复制到另一个变量中而不会被删除。如果这样解释的话，这里有个例子：
//army注：这一源代码片段是在Firebug下的Console控制台运行的，放在页面中需改写
var sum = function(a, b) {return a + b;}
var add = sum;
delete sum;
true
typeof sum;
&quot;undefined&quot;
忽略代码中省略的两个分号，你注意到这个代码片段的问题了吗？按那句话所说，删除sum不应该成功；delete语句返回的值不可能是true；typeof sum的结果不会是&amp;#8221;undefined&amp;#8221;。可是事实却非如此，所有的这一切都是因为：Javascript中不可能删除变量。至少不能以这种方式删除。
 这是为什么呢？
要回答这个问题，我们需要理解delete操作符是怎么运作的：即什么可以删除、什么不可以删除、为什么？
原理
我们为什么可以这样删除对象的属性？
var o = {...&lt;img src=&quot;http://www1.feedsky.com/t1/340427719/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427719/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427719/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427719/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>前端开发</category><category>删除</category><category>javascript</category><pubDate>Fri, 05 Mar 2010 15:57:28 +0800</pubDate><author>army8735</author><comments>http://army8735.org/2010/03/05/691.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=691</guid><dc:creator>army8735</dc:creator><fs:srclink>http://army8735.org/2010/03/05/691.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340427719/5961215</fs:itemid></item><item><title>[转]Google Nexus One上的Flash Player 10.1演示</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340427947/5961215/1/item.html</link><content:encoded>&lt;p&gt;在7yue的blog上看到fp10.1的表现让人兴奋不已，希望Adobe摆脱“很有压力，才有推力”的形象……&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.7yue.com/post/430.html&quot;&gt;http://www.7yue.com/post/430.html&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340427947/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427947/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427947/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427947/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/02/25/689.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>在7yue的blog上看到fp10.1的表现让人兴奋不已，希望Adobe摆脱“很有压力，才有推力”的形象……
http://www.7yue.com/post/430.html&lt;img src=&quot;http://www1.feedsky.com/t1/340427947/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427947/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427947/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427947/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>as、flex</category><category>flash player 10.1</category><pubDate>Thu, 25 Feb 2010 11:56:24 +0800</pubDate><author>army8735</author><comments>http://army8735.org/2010/02/25/689.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=689</guid><dc:creator>army8735</dc:creator><fs:srclink>http://army8735.org/2010/02/25/689.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340427947/5961215</fs:itemid></item><item><title>web端语法高亮原理：走进jssc的世界（五）</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340427976/5961215/1/item.html</link><content:encoded>&lt;h3&gt;整体流程&lt;/h3&gt;
&lt;p&gt;终于说到整体流程上了。之前的文章一直在解说as中如何来做词法分析，js方面丝毫未提，更没说jssc到底在页面上是怎么工作的。现在，就来详细地解释一下。&lt;/p&gt;
&lt;p&gt;环境需求：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;现代浏览器（废话）&lt;/li&gt;
&lt;li&gt;装有Adobe Flash Player插件，版本号为9或9以上&lt;/li&gt;
&lt;li&gt;javascript启用&lt;/li&gt;
&lt;li&gt;页面中放入jssc.swf文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;大致流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;swf文件载入完毕&lt;/li&gt;
&lt;li&gt;内嵌在swf中的js首先被执行，寻找页面中所有符合规则的pre节点&lt;/li&gt;
&lt;li&gt;顺序遍历这些pre节点，提取每个pre节点的文本内容（即原始代码）&lt;/li&gt;
&lt;li&gt;将原始代码传递给swf&lt;/li&gt;
&lt;li&gt;swf对传递来的原始代码进行词法分析，并生成一段结果html片段（即一串li节点）&lt;/li&gt;
&lt;li&gt;将结果传递回js&lt;/li&gt;
&lt;li&gt;js对结果进行包装（一串li节点放入ol节点中，以及标题头、边距和复制等等）&lt;/li&gt;
&lt;li&gt;将对应的原始pre节点隐藏（display:none）&lt;/li&gt;
&lt;li&gt;将新生成的内容插入原始pre节点的前面&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可以看出，js和as耦合的地方在哪里，以及它们之间是如何相互合作的。下面将对以上9个步骤细细说来，希望更多的开发者能提出改进意见～&lt;/p&gt;
&lt;h3&gt;1.载入swf&lt;/h3&gt;
&lt;p&gt;这里没什么好说的，在页面底部加入flash标签即可。值得注意的是不同浏览器中标签有所区别，理想情况下可以使用swfobject来插入标准的html标签。不过为了兼容以及简单，一般我是这样做的：&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; id=&quot;jssc5&quot; style=&quot;position:absolute;visibility:hidden;&quot;&amp;gt;
	&amp;lt;param name=&quot;movie&quot; value=&quot;jssc5.swf&quot;/&amp;gt;
	&amp;lt;param name=&quot;flashvars&quot; value=&quot;find=brush&quot;/&amp;gt;
	&amp;lt;embed src=&quot;jssc5.swf&quot; flashvars=&quot;find=brush&quot; name=&quot;jssc5&quot; type=&quot;application/x-shockwave-flash&quot; style=&quot;position:absolute;visibility:hidden;&quot;/&amp;gt;
&amp;lt;/object&amp;gt;&lt;/pre&gt;
&lt;p&gt;这里面有许多可配置的地方。&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;object&lt;/span&gt;的&lt;span style=&quot;color: #ff0000;&quot;&gt;id&lt;/span&gt;和&lt;span style=&quot;color: #ff0000;&quot;&gt;embed&lt;/span&gt;的&lt;span style=&quot;color: #ff0000;&quot;&gt;name&lt;/span&gt;必须一致且唯一（应该是唯二才对），为了满足不同浏览器的需要。我设为&lt;span style=&quot;color: #ff0000;&quot;&gt;jssc5&lt;/span&gt;，这也是默认值。如果和页面上某个节点有冲突需要修改，那么就需要传入参数修改配置。比如说变成&lt;span style=&quot;color: #ff0000;&quot;&gt;jssc5_modify&lt;/span&gt;，就得在flashvars中这样做：&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; id=&quot;jssc5_modify&quot; style=&quot;position:absolute;visibility:hidden;&quot;&amp;gt;
	&amp;lt;param name=&quot;movie&quot; value=&quot;jssc5.swf&quot;/&amp;gt;
	&amp;lt;param name=&quot;flashvars&quot; value=&quot;find=brush&amp;amp;swf=jssc5_modify&quot;/&amp;gt;
	&amp;lt;embed src=&quot;jssc5.swf&quot; flashvars=&quot;find=brush&amp;amp;swf=jssc5_modify&quot; name=&quot;jssc5_modify&quot; type=&quot;application/x-shockwave-flash&quot; style=&quot;position:absolute;visibility:hidden;&quot;/&amp;gt;
&amp;lt;/object&amp;gt;&lt;/pre&gt;
&lt;p&gt;注意到param标签和embed标签中都得改，为了满足浏览器兼容需要……&lt;/p&gt;
&lt;p&gt;同样，jssc会占用一个全局js变量名&lt;span style=&quot;color: #ff0000;&quot;&gt;jssc&lt;/span&gt;（注意这个jssc是指变量名字符串，而前者是指软件），这是为了在js和as之间互相调用通信必须的。如果这个变量名和页面上的js变量有冲突，那么就会造成错误。所以它也可以进行修改配置，假如要改成&lt;span style=&quot;color: #ff0000;&quot;&gt;jssc_js&lt;/span&gt;，就得在flashvars中这么做：&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; id=&quot;jssc5_modify&quot; style=&quot;position:absolute;visibility:hidden;&quot;&amp;gt;
	&amp;lt;param name=&quot;movie&quot; value=&quot;jssc5.swf&quot;/&amp;gt;
	&amp;lt;param name=&quot;flashvars&quot; value=&quot;find=brush&amp;amp;swf=jssc5_modify&amp;amp;js=jssc_js&quot;/&amp;gt;
	&amp;lt;embed src=&quot;jssc5.swf&quot; flashvars=&quot;find=brush&amp;amp;swf=jssc5_modify&amp;amp;js=jssc_js&quot; name=&quot;jssc5_modify&quot; type=&quot;application/x-shockwave-flash&quot; style=&quot;position:absolute;visibility:hidden;&quot;/&amp;gt;
&amp;lt;/object&amp;gt;&lt;/pre&gt;
&lt;p&gt;最后，还有两个可以配置的参数：&lt;span style=&quot;color: #ff0000;&quot;&gt;css&lt;/span&gt;和&lt;span style=&quot;color: #ff0000;&quot;&gt;url&lt;/span&gt;。前者是指新生成的结果节点的class名称，你可以用firebug看到默认的亦是&lt;span style=&quot;color: #ff0000;&quot;&gt;jssc&lt;/span&gt;；后者是指定swf的路径，这是为了在非ie浏览器下做copy使用（ie可以直接调用api做复制功能），从这个意义上说，整个swf文件其实是有两种功能——词法分析和复制按钮。这么做是为了减少http请求，同时js融合在as里也是为了减少http请求。&lt;/p&gt;
&lt;h3&gt;2.内嵌的js执行&lt;/h3&gt;
&lt;p&gt;js首先会寻找页面上所有符合规则的pre节点，那么是什么规则的？默认情况下，pre的class名称如果这样开头，js就会认为它是正确的（其实并不一定要求是开头，出现在其它位置也可以，但为了良好的习惯推荐如此）：&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;pre class=&quot;brush:html&quot;&amp;gt;&amp;lt;/pre&amp;gt;&lt;/pre&gt;
&lt;p&gt;这段被高亮的代码其实就是它本身。&lt;span style=&quot;color: #ff0000;&quot;&gt;brush&lt;/span&gt;是&lt;strong&gt;键名&lt;/strong&gt;，&lt;span style=&quot;color: #ff0000;&quot;&gt;html&lt;/span&gt;是&lt;strong&gt;键值&lt;/strong&gt;。假如想要高亮一段js代码，那么就需要更改键值：&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;pre class=&quot;brush:js&quot;&amp;gt;&amp;lt;/pre&amp;gt;&lt;/pre&gt;
&lt;p&gt;其它语言道理相同。另外，可以高亮的代码必须是jssc本身已经支持的语法种类，不支持的话也会被格式化，但没有高亮效果。&lt;/p&gt;
&lt;p&gt;细心的人可能已经发现，&lt;span style=&quot;color: #ff0000;&quot;&gt;brush&lt;/span&gt;键名和最开始那段代码中出现的相一致。没错，假如pre节点的class名称也有冲突，不能使用&lt;span style=&quot;color: #ff0000;&quot;&gt;brush&lt;/span&gt;，要改成&lt;span style=&quot;color: #ff0000;&quot;&gt;brush_modify&lt;/span&gt;，那么就要如此修改配置：&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; id=&quot;jssc5_modify&quot; style=&quot;position:absolute;visibility:hidden;&quot;&amp;gt;
	&amp;lt;param name=&quot;movie&quot; value=&quot;jssc5.swf&quot;/&amp;gt;
	&amp;lt;param name=&quot;flashvars&quot; value=&quot;find=brush_modify&amp;amp;swf=jssc5_modify&amp;amp;js=jssc_js&quot;/&amp;gt;
	&amp;lt;embed src=&quot;jssc5.swf&quot; flashvars=&quot;find=brush_modify&amp;amp;swf=jssc5_modify&amp;amp;js=jssc_js&quot; name=&quot;jssc5_modify&quot; type=&quot;application/x-shockwave-flash&quot; style=&quot;position:absolute;visibility:hidden;&quot;/&amp;gt;
&amp;lt;/object&amp;gt;&lt;/pre&gt;
&lt;p&gt;注意param和embed中要修改2次。&lt;/p&gt;
&lt;p&gt;在找到所有符合规则的pre节点之后，js将这些节点的引用存储下来，然后一一遍历它们。下面的经过就是每次遍历一个pre节点时所发生的。&lt;/p&gt;
&lt;h3&gt;3.遍历提取内容&lt;/h3&gt;
&lt;p&gt;提取pre节点的内容很简单，即我们熟知的&lt;span style=&quot;color: #ff0000;&quot;&gt;innerText&lt;/span&gt;。不过在不同浏览器中也有让人头疼的地方。以前在做jssc4的时候，firefox2版本的&lt;span style=&quot;color: #ff0000;&quot;&gt;innerText&lt;/span&gt;容量有限制，如果代码过多，提取的内容就不完整。另外也有低版本浏览器不支持&lt;span style=&quot;color: #ff0000;&quot;&gt;innerText&lt;/span&gt;的可能性发生。所以综合考虑我写了个如下的js方法：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function getText(node) {
	var code = node.textContent || node.innerText;
	if(!code &amp;amp;&amp;amp; node.firstChild) {
		code = node.firstChild.nodeValue;
	}
	return code || &quot;&quot;;
}&lt;/pre&gt;
&lt;h3&gt;4.传递内容给as&lt;/h3&gt;
&lt;p&gt;这是as定义好的接口，js和as可以通过&lt;span style=&quot;color: #ff0000;&quot;&gt;ExternalInterface&lt;/span&gt;类来实现互调。不再多说。&lt;/p&gt;
&lt;h3&gt;5.as做词法分析&lt;/h3&gt;
&lt;p&gt;这是前几篇一直在说的内容，不再多说。&lt;/p&gt;
&lt;h3&gt;6.传递结果给js&lt;/h3&gt;
&lt;p&gt;同第4点。&lt;/p&gt;
&lt;h3&gt;7.js包装结果&lt;/h3&gt;
&lt;p&gt;生成的结果其实是一串&lt;span style=&quot;color: #ff0000;&quot;&gt;li&lt;/span&gt;节点，js要做的就是创建一个&lt;span style=&quot;color: #ff0000;&quot;&gt;ol&lt;/span&gt;节点，然后设置&lt;span style=&quot;color: #ff0000;&quot;&gt;innerHTML&lt;/span&gt;为传递来的结果字符串。如此最基本的高亮代码就完成了。之后是设置标题、起始行数、边距、复制功能和鼠标移入高亮当前行背景。&lt;/p&gt;
&lt;p&gt;其中边距是指ol节点的&lt;span style=&quot;color: #ff0000;&quot;&gt;paddingLeft&lt;/span&gt;值，因为代码行数不一样，所以左边距一定是根据行数动态进行计算的。在js中我的公式如下：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;oOl.style.paddingLeft = Math.max((line.length + 2) * 9, 30) + &quot;px&quot;;&lt;/pre&gt;
&lt;h3&gt;8.隐藏pre节点&lt;/h3&gt;
&lt;p&gt;最后是将本次循环的这个pre节点隐藏。注意，这里是隐藏不是删除！因为后面还要用到代码复制功能，所以只能隐藏不能删除！&lt;/p&gt;
&lt;h3&gt;9.插入结果&lt;/h3&gt;
&lt;p&gt;将包装好的结果插入本次循环pre节点的前面，这轮循环就算走完了，再继续下一轮循环。&lt;/p&gt;
&lt;h3&gt;结束语&lt;/h3&gt;
&lt;p&gt;好了，整个系列文章算结束了。欢迎大家提出好的建议和想法，或者直接参与到开发当中来，亦或以别的方式来参与（比如说做wordpress的插件）。如果你能做出比jssc更好的高亮插件，那么我也会放弃jssc，投入新的、更好的项目中去的——这话说的好假：）&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340427976/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427976/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427976/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427976/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/02/23/669.html/feed</wfw:commentRss><slash:comments>3</slash:comments><description>整体流程
终于说到整体流程上了。之前的文章一直在解说as中如何来做词法分析，js方面丝毫未提，更没说jssc到底在页面上是怎么工作的。现在，就来详细地解释一下。
环境需求：

现代浏览器（废话）
装有Adobe Flash Player插件，版本号为9或9以上
javascript启用
页面中放入jssc.swf文件

大致流程：

swf文件载入完毕
内嵌在swf中的js首先被执行，寻找页面中所有符合规则的pre节点
顺序遍历这些pre节点，提取每个pre节点的文本内容（即原始代码）
将原始代码传递给swf
swf对传递来的原始代码进行词法分析，并生成一段结果html片段（即一串li节点）
将结果传递回js
js对结果进行包装（一串li节点放入ol节点中，以及标题头、边距和复制等等）
将对应的原始pre节点隐藏（display:none）
将新生成的内容插入原始pre节点的前面

可以看出，js和as耦合的地方在哪里，以及它们之间是如何相互合作的。下面将对以上9个步骤细细说来，希望更多的开发者能提出改进意见～
1.载入swf
这里没什么好说的，在页面底部加入flash标签即可。值得注意的是不同浏览器中标签有所区别，理想情况下可以使用swfobject来插入标准的html标签。不过为了兼容以及简单，一般我是这样做的：
&amp;#60;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; id=&quot;jssc5&quot; style=&quot;position:absolute;visibility:hidden;&quot;&amp;#62;
	&amp;#60;param name=&quot;movie&quot; value=&quot;jssc5.swf&quot;/&amp;#62;
	&amp;#60;param name=&quot;flashvars&quot; value=&quot;find=brush&quot;/&amp;#62;
	&amp;#60;embed src=&quot;jssc5.swf&quot; flashvars=&quot;find=brush&quot; name=&quot;jssc5&quot; type=&quot;application/x-shockwave-flash&quot; style=&quot;position:absolute;visibility:hidden;&quot;/&amp;#62;
&amp;#60;/object&amp;#62;
这里面有许多可配置的地方。
object的id和embed的name必须一致且唯一（应该是唯二才对），为了满足不同浏览器的需要。我设为jssc5，这也是默认值。如果和页面上某个节点有冲突需要修改，那么就需要传入参数修改配置。比如说变成jssc5_modify，就得在flashvars中这样做：
&amp;#60;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; id=&quot;jssc5_modify&quot; style=&quot;position:absolute;visibility:hidden;&quot;&amp;#62;
	&amp;#60;param name=&quot;movie&quot; value=&quot;jssc5.swf&quot;/&amp;#62;
	&amp;#60;param...&lt;img src=&quot;http://www1.feedsky.com/t1/340427976/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340427976/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340427976/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340427976/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>jssc</category><category>语法高亮原理</category><category>系列文章</category><pubDate>Tue, 23 Feb 2010 14:45:47 +0800</pubDate><author>army8735</author><comments>http://army8735.org/2010/02/23/669.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=669</guid><dc:creator>army8735</dc:creator><fs:srclink>http://army8735.org/2010/02/23/669.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340427976/5961215</fs:itemid></item><item><title>js和swf交互时不同浏览器中的顺序</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340428150/5961215/1/item.html</link><content:encoded>&lt;p&gt;&lt;a href=&quot;/2010/02/20/646.html&quot; target=&quot;_blank&quot;&gt;接上篇&lt;/a&gt;，继续做的测试，有了点新发现。解说测试之前，先说明下用flash检测大写锁定键是否开启的原理。&lt;/p&gt;
&lt;p&gt;前提要求是：普通的input文本输入框（无论是text还是password），用户输入还是以html的input组件为基础，并非在其上加入透明的flash输入框或者其它技术平台的组件；无干扰性，用户输入没有任何其它干扰的感觉。&lt;/p&gt;
&lt;p&gt;以此，唯一的解决办法就是js结合swf来控制。input的各种事件侦听（获得焦点、失去焦点、按键触发）都只能由js来完成，而对当前键盘状态的检测则交给flash来处理。它们之间有个很大的障碍——flash对当前键盘状态的识别必须首先获得焦点，而我们在input中输入内容的时候焦点却在input上，这成为&lt;strong&gt;最大的矛盾&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;利用js控制页面焦点可以解决这一问题，除了webkit内核的浏览器。我们可以写出如下的伪代码：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;oInput.onfocus = function() {
	oSwf.focus(); //flash获得焦点
	oSwf.detect(); //flash进行检测，并根据检测结果调用某个js函数
	setTimeout(function() {
		oInput.focus(); //input重新获得焦点，无干扰用户输入
	}, 0);
}&lt;/pre&gt;
&lt;p&gt;你可能困扰为何要用&lt;strong&gt;setTimeout&lt;/strong&gt;来使input重新获得焦点，这是为了让用户输入时感觉不到焦点在input和flash之间走了一圈，就好象什么事都没有发生一样。至于为什么一定要用setTimeout，那是为了模拟线程同步，确保重新获得焦点这一操作发生在最后。&lt;/p&gt;
&lt;p&gt;就几行代码看上去很简单，实际上有几个隐蔽的信息藏在其中。在flash获得焦点并进行检测之后，input重新获得焦点，试问：这样会不会再次触发onfocus？答案是肯定的，如果不做任何处理的话，这将是个死循环；另外，input还应该侦听onblur，没道理用户在离开输入框之后还在进行提示（除非你能忍受），那么onblur这个侦听函数也会进行不断重复；更恐怖的在下面，我为每一步标上了序号，以表示它们的执行步骤：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;function result() {
	//1
	//调用的结果函数，用以让提示区域显示或隐藏
}
oInput.onfocus = function() {
	//2
	oSwf.focus(); //flash获得焦点
	oSwf.detect(); //flash进行检测，并根据检测结果调用结果函数
	//3
	setTimeout(function() {
		//4
		oInput.focus(); //input重新获得焦点，无干扰用户输入
	}, 0);
	//5
}
oInput.onblur = function() {
	//6
	//失去焦点后该怎么做，略
}&lt;/pre&gt;
&lt;p&gt;猜一猜这个步骤顺序是多少？你永远也答不对，因为即使在&lt;span style=&quot;color: #ff0000;&quot;&gt;trident&lt;/span&gt;（ie为代表）和&lt;span style=&quot;color: #ff0000;&quot;&gt;gecko&lt;/span&gt;（firefox为代表）两种内核下，它们也不相同（别提webkit了，搞定那个bug先）。&lt;/p&gt;
&lt;p&gt;在trident中，input被用户激活后（比如说用鼠标点击），先触发focus，因此2会先执行；接下来flash获得焦点，再调用结果方法，1会被执行；继续回到onfocus方法，顺序走完3和5；onblur被触发，执行一下6；最后是setTimeout那里的4。&lt;/p&gt;
&lt;p&gt;很奇怪的现象，因为在2时，input失去焦点而swf获得焦点，此时并没有触发onblur去执行6，反而是先执行的1；之后还有没执行完的3和5；在接下来才能轮到6。由此我们可以观察出一些trident内核的优先级顺序设计的端倪。&lt;/p&gt;
&lt;p&gt;再来看看gecko，input被激活后，依然会先触发focus，2第一个执行；接下来也是flash获得焦点，不过在这之前input要先失去焦点，因此先触发了onblur，执行了6；然后flash进行判断，并调用结果方法，执行了1；再往后就类似了，3和5搞定后setTimeout的4最后。&lt;/p&gt;
&lt;p&gt;探索完原理后，才有可能继续开发。我也只“刨根问底”到这个程度上，欢迎有兴趣的同学继续“往祖坟上刨”，彻底翻出来赤裸裸的现实。后续如果有新的进展，我会继续把它写出来。：）&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340428150/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340428150/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340428150/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340428150/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/02/20/649.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>接上篇，继续做的测试，有了点新发现。解说测试之前，先说明下用flash检测大写锁定键是否开启的原理。
前提要求是：普通的input文本输入框（无论是text还是password），用户输入还是以html的input组件为基础，并非在其上加入透明的flash输入框或者其它技术平台的组件；无干扰性，用户输入没有任何其它干扰的感觉。
以此，唯一的解决办法就是js结合swf来控制。input的各种事件侦听（获得焦点、失去焦点、按键触发）都只能由js来完成，而对当前键盘状态的检测则交给flash来处理。它们之间有个很大的障碍——flash对当前键盘状态的识别必须首先获得焦点，而我们在input中输入内容的时候焦点却在input上，这成为最大的矛盾。
利用js控制页面焦点可以解决这一问题，除了webkit内核的浏览器。我们可以写出如下的伪代码：
oInput.onfocus = function() {
	oSwf.focus(); //flash获得焦点
	oSwf.detect(); //flash进行检测，并根据检测结果调用某个js函数
	setTimeout(function() {
		oInput.focus(); //input重新获得焦点，无干扰用户输入
	}, 0);
}
你可能困扰为何要用setTimeout来使input重新获得焦点，这是为了让用户输入时感觉不到焦点在input和flash之间走了一圈，就好象什么事都没有发生一样。至于为什么一定要用setTimeout，那是为了模拟线程同步，确保重新获得焦点这一操作发生在最后。
就几行代码看上去很简单，实际上有几个隐蔽的信息藏在其中。在flash获得焦点并进行检测之后，input重新获得焦点，试问：这样会不会再次触发onfocus？答案是肯定的，如果不做任何处理的话，这将是个死循环；另外，input还应该侦听onblur，没道理用户在离开输入框之后还在进行提示（除非你能忍受），那么onblur这个侦听函数也会进行不断重复；更恐怖的在下面，我为每一步标上了序号，以表示它们的执行步骤：
function result() {
	//1
	//调用的结果函数，用以让提示区域显示或隐藏
}
oInput.onfocus = function() {
	//2
	oSwf.focus(); //flash获得焦点
	oSwf.detect(); //flash进行检测，并根据检测结果调用结果函数
	//3
	setTimeout(function() {
		//4
		oInput.focus(); //input重新获得焦点，无干扰用户输入
	}, 0);
	//5
}
oInput.onblur =...&lt;img src=&quot;http://www1.feedsky.com/t1/340428150/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340428150/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340428150/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340428150/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>前端开发</category><category>JAcld</category><pubDate>Sat, 20 Feb 2010 17:44:51 +0800</pubDate><author>army</author><comments>http://army8735.org/2010/02/20/649.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=649</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2010/02/20/649.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340428150/5961215</fs:itemid></item><item><title>webkit内核浏览器中swf获取焦点的bug</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340428153/5961215/1/item.html</link><content:encoded>&lt;p&gt;&lt;a href=&quot;http://army8735.org/2009/09/15/82.html&quot;&gt;http://army8735.org/2009/09/15/82.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;曾经考虑过用swf来检测密码输入框大写锁定键是否被打开，并且也进行了一个小实验，基本是成功的。时隔多日，最近想要把它完善一下，突然发现在chrome中根本不起作用！&lt;/p&gt;
&lt;p&gt;一步步排查下来，终于发现在webkit内核的浏览器下，以往的使得swf获取焦点的方法根本不起作用。随之google一番，发现老外早已发现这个bug，并且目前webkit仍未解决：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://stackoverflow.com/questions/594821/object-focus-problem-with-safari-and-chrome-browsers&quot;&gt;http://stackoverflow.com/questions/594821/object-focus-problem-with-safari-and-chrome-browsers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这样就影响到了部分功能：比如想使用flash的检测按键功能，但它必须要求flash是在获得焦点的情况下才行。使用js可以在ie和gecko内核下轻松办到，webkit只能继续等待了。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340428153/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340428153/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340428153/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340428153/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/02/20/646.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>http://army8735.org/2009/09/15/82.html
曾经考虑过用swf来检测密码输入框大写锁定键是否被打开，并且也进行了一个小实验，基本是成功的。时隔多日，最近想要把它完善一下，突然发现在chrome中根本不起作用！
一步步排查下来，终于发现在webkit内核的浏览器下，以往的使得swf获取焦点的方法根本不起作用。随之google一番，发现老外早已发现这个bug，并且目前webkit仍未解决：
http://stackoverflow.com/questions/594821/object-focus-problem-with-safari-and-chrome-browsers
这样就影响到了部分功能：比如想使用flash的检测按键功能，但它必须要求flash是在获得焦点的情况下才行。使用js可以在ie和gecko内核下轻松办到，webkit只能继续等待了。&lt;img src=&quot;http://www1.feedsky.com/t1/340428153/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340428153/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340428153/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340428153/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>前端开发</category><category>JAcld</category><pubDate>Sat, 20 Feb 2010 12:17:42 +0800</pubDate><author>army</author><comments>http://army8735.org/2010/02/20/646.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=646</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2010/02/20/646.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340428153/5961215</fs:itemid></item><item><title>web中的区域对齐</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340428155/5961215/1/item.html</link><content:encoded>&lt;p&gt;说到对齐方式，一般联想到的无非四种：左对齐、右对齐、上对齐和下对齐。通过其中的两两组合，可以衍生出：左上角对齐、左下角对齐、右上角对齐和右下角对齐。在css中这些类型很常见，比如绝对定位：&lt;/p&gt;
&lt;pre class=&quot;brush:css&quot;&gt;.left_top {
	position: absolute;
	left: 0;
	top: 0;
}
.left_bottom {
	position: absolute;
	left: 0;
	bottom: 0;
}
.right_top {
	position: absolute;
	right: 0;
	top: 0;
}
.right_bottom {
	position: absolute;
	right: 0;
	bottom: 0;
}&lt;/pre&gt;
&lt;p&gt;我们很容易用css来作出四个角对齐或者四个方向居中对齐的效果。但是在as当中，则有一点点麻烦了。&lt;/p&gt;
&lt;p&gt;说到对齐之前，首先要接触到&lt;strong&gt;StageScaleMode&lt;/strong&gt;这个常量，它被赋给&lt;strong&gt;stage.scaleMode&lt;/strong&gt;，用以指定整个swf程序的缩放模式，默认的是&lt;strong&gt;NO_SCALE&lt;/strong&gt;，即不缩放。详细示例如下图：&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;aligncenter size-full wp-image-629&quot; title=&quot;stagealign1&quot; src=&quot;http://army8735.org/wp-content/uploads/2010/02/stagealign1.png&quot; alt=&quot;stagealign1&quot; width=&quot;400&quot; height=&quot;400&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当然&lt;strong&gt;StageScaleMode&lt;/strong&gt;还有保持高宽比的&lt;strong&gt;SHOW_ALL&lt;/strong&gt;常量以及保持高宽比并可能进行裁剪的&lt;strong&gt;NO_BORDER&lt;/strong&gt;常量。上面只例举了两种对立的情形。当涉及到&lt;strong&gt;StageAlign&lt;/strong&gt;的时候，我们默认为&lt;strong&gt;StageScaleMode&lt;/strong&gt;就是默认的&lt;strong&gt;NO_SCALE&lt;/strong&gt;，这样对齐才有意义。&lt;/p&gt;
&lt;p&gt;在css中，也经常会遇到类似的情况。一个div区域有自己的高宽，超出区域范围之外的用&lt;strong&gt;overflow&lt;/strong&gt;来控制可见度。譬如是右上角对齐的css，例子是这样：&lt;/p&gt;
&lt;pre class=&quot;brush:html;&quot;&gt;&amp;lt;style&amp;gt;
.outer{position:relative;width:100px;height:100px;border:1px solid #f00;overflow:hidden;}
.inner{position:absolute;top:0;right:0;width:200px;height:200px;background:#000;}
&amp;lt;/style&amp;gt;

&amp;lt;div class=&quot;outer&quot;&amp;gt;
	&amp;lt;div class=&quot;inner&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;
&lt;p&gt;在as当中，想要做到同样的效果的话，可以借助&lt;strong&gt;StageAlign&lt;/strong&gt;这个常量，它被赋给&lt;strong&gt;stage.align&lt;/strong&gt;属性，所起的作用就和上面说的css对齐方式一样。同样是右上角对齐，我们只要在文档类中声明一下即可达到效果：&lt;/p&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;package {
	import flash.display.*;

	public class Main extends Sprite {
		public function Main():void {
			stage.align = StageAlign.TOP_RIGHT;
		}
	}
}&lt;/pre&gt;
&lt;p&gt;用图片做示例，页面嵌入一个原始大小为50*50的swf文件，假如外部容器（object标签或者emebed标签）的高宽值被改变，swf仍然是右上角对齐：&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;aligncenter size-full wp-image-642&quot; title=&quot;stagealign2&quot; src=&quot;http://army8735.org/wp-content/uploads/2010/02/stagealign2.png&quot; alt=&quot;stagealign2&quot; width=&quot;400&quot; height=&quot;260&quot; /&gt;&lt;/p&gt;
&lt;p&gt;依此我们便可以作出自由指定显示swf内容范围的功能，比如初始swf原始大小为100*100，但是外部容器只设定宽高为50*50。当为右上角对齐时，swf只显示右上区域的50*50部分。当某件事发生时（比如鼠标点击一个按钮），外部容器款高变成100*100，如此便能看见全部的swf了。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340428155/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340428155/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340428155/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340428155/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/02/10/626.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>说到对齐方式，一般联想到的无非四种：左对齐、右对齐、上对齐和下对齐。通过其中的两两组合，可以衍生出：左上角对齐、左下角对齐、右上角对齐和右下角对齐。在css中这些类型很常见，比如绝对定位：
.left_top {
	position: absolute;
	left: 0;
	top: 0;
}
.left_bottom {
	position: absolute;
	left: 0;
	bottom: 0;
}
.right_top {
	position: absolute;
	right: 0;
	top: 0;
}
.right_bottom {
	position: absolute;
	right: 0;
	bottom: 0;
}
我们很容易用css来作出四个角对齐或者四个方向居中对齐的效果。但是在as当中，则有一点点麻烦了。
说到对齐之前，首先要接触到StageScaleMode这个常量，它被赋给stage.scaleMode，用以指定整个swf程序的缩放模式，默认的是NO_SCALE，即不缩放。详细示例如下图：

当然StageScaleMode还有保持高宽比的SHOW_ALL常量以及保持高宽比并可能进行裁剪的NO_BORDER常量。上面只例举了两种对立的情形。当涉及到StageAlign的时候，我们默认为StageScaleMode就是默认的NO_SCALE，这样对齐才有意义。
在css中，也经常会遇到类似的情况。一个div区域有自己的高宽，超出区域范围之外的用overflow来控制可见度。譬如是右上角对齐的css，例子是这样：
&amp;#60;style&amp;#62;
.outer{position:relative;width:100px;height:100px;border:1px solid #f00;overflow:hidden;}
.inner{position:absolute;top:0;right:0;width:200px;height:200px;background:#000;}
&amp;#60;/style&amp;#62;

&amp;#60;div class=&quot;outer&quot;&amp;#62;
	&amp;#60;div...&lt;img src=&quot;http://www1.feedsky.com/t1/340428155/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340428155/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340428155/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340428155/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>对齐</category><category>前端开发</category><category>StageAlign</category><category>as、flex</category><pubDate>Wed, 10 Feb 2010 11:59:43 +0800</pubDate><author>army8735</author><comments>http://army8735.org/2010/02/10/626.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=626</guid><dc:creator>army8735</dc:creator><fs:srclink>http://army8735.org/2010/02/10/626.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340428155/5961215</fs:itemid></item><item><title>web端语法高亮原理：走进jssc的世界（四）</title><link>http://item.feedsky.com/~feedsky/army8735/~7851743/340428158/5961215/1/item.html</link><content:encoded>&lt;h3&gt;内嵌解析&lt;/h3&gt;
&lt;p&gt;很容易遇到这样的情况：在需要高亮的代码中还混淆着其它语言种类的代码（最常见的例子为Html内嵌css和js，以下也将以此为例）。这是一件让人头疼的事情，因为无论采用何种方法，内嵌的语言和原本语言的规则一定是不同的。这意味着必须将它们区分开来对待。从这一点出发，自然而然就能引出问题的关键所在——如何区分？&lt;/p&gt;
&lt;h3&gt;剥离内容&lt;/h3&gt;
&lt;p&gt;先来考虑最简单的情况：&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;head&amp;gt;
&amp;lt;script&amp;gt;var i = 0;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;&lt;/pre&gt;
&lt;p&gt;假如没有第2行的script标签以及其内部的代码，那么整个就是纯html代码高亮，这个没有什么难度（如果已经完全理解前三篇的此法分析的话）。然而不凑巧的是，关键点就在于script标签中会出现js代码，html的此法分析中并没有js的词法规则，两者不能等同。那么怎么办呢？&lt;/p&gt;
&lt;p&gt;答案是将它们剥离出来。上例是最简单的例子，我们在对html进行此法分析的时候，一旦读到了&amp;lt;script&amp;gt;开始标签，接着便去寻找&amp;lt;/script&amp;gt;结束标签（一般会使用String.indexOf()来查找），然后将标签里面的内容单独提取出来。这是第一步，如果做完的话，此时html的高亮结果应该是：除了js代码没有高亮（即默认颜色）以外，其它的html代码均被正确高亮了。&lt;/p&gt;
&lt;h3&gt;更复杂的情况&lt;/h3&gt;
&lt;p&gt;剥离到此还没有结束，因为剥离要考虑其它一些复杂的元素。看以下代码：&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;head&amp;gt;
&amp;lt;script&amp;gt;var i = 0;
//&amp;lt;/script&amp;gt;
&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;&lt;/pre&gt;
&lt;p&gt;代码的第3行中，出现了单行注释，其中有被注释掉的script结束标签。这点需要格外注意。假若使用String.indexOf()来查询script结束标签的话，那么就会在第3行结束。这样就错了，因为第3行实际上是个注释，真正的结束符在第4行。&lt;/p&gt;
&lt;p&gt;以此延伸，除了上面的情况以外，引号中的字符串、多行注释、正则里面均会出现类似情况。因此，单纯的String.indexOf()是肯定不行的。我们必须对js代码部分进行预处理。&lt;/p&gt;
&lt;h3&gt;预处理&lt;/h3&gt;
&lt;p&gt;在as的解析部分，实际上主要分为两大块：词法分析和存储结果。词法分析即是前面几篇一直在讲解的内容；存储结果即是将分析出来的代码链接起来，说白了就是简单的字符串拼接。&lt;/p&gt;
&lt;p&gt;在html中的js代码可能会出现混淆script结束标签的情况之下，唯一解决的办法就是对js也进行&lt;strong&gt;简单的词法分析预处理&lt;/strong&gt;，但不存储结果。因为分析是“读”，而存储是“写”。写的耗时要比读多多了，而且预处理只是为了防止注释、字符串和正则的混淆，不需要真正地进行解析，实现复杂读也比较低。等完全将js代码从html中剥离后，再交给js解析器来做真正的工作，如此也保证了代码的不重复。&lt;/p&gt;
&lt;pre class=&quot;brush:html&quot;&gt;&amp;lt;head&amp;gt;
&amp;lt;script&amp;gt;
var i = 0;
//&amp;lt;/script&amp;gt;
&quot;&amp;lt;/script&amp;gt;&quot;
/*&amp;lt;/script&amp;gt;*/
/[&amp;lt;/script&amp;gt;]/
&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;&lt;/pre&gt;
&lt;p&gt;html中的预处理，至少要保证能将3到7行的js代码完全剥离出来交给js解析器处理，其它html代码则由本身来完成高亮。&lt;/p&gt;
&lt;h3&gt;状态区分&lt;/h3&gt;
&lt;p&gt;接下来的难点可能还是在如何在html解析的时候完成区分上面。在这里，我设置了一个state变量用以标识状态。仔细考虑下html，无非发现它主要有以下几种状态：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;html节点：即&amp;lt;&amp;gt;内的tag，还有随之的一些属性内容。如：&amp;lt;img width=&amp;#8221;100px&amp;#8221;/&amp;gt;。&lt;/li&gt;
&lt;li&gt;text节点：文本内容，段落p中最常见到。&lt;/li&gt;
&lt;li&gt;css节点：style中的css代码。&lt;/li&gt;
&lt;li&gt;script节点：script中的js代码。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在默认最开始的时候，是文本节点。一旦遇到了左尖括号，并且随后跟的是个正确的节点名（&amp;lt;x&amp;gt;绝对不是个正确的节点，所以不能当成节点来处理），那么就进入节点状态来解析；当节点解析完了之后，返回文本状态。css和script节点是个两个特殊的节点，因为在它们的开始标签结束之后，要进行预处理查找结束标签。实际上会做其中的一个，另外一个也就懂了。&lt;/p&gt;
&lt;p&gt;值得注意的是，html标签中有单个类型的存在，比如&amp;lt;br/&amp;gt;，它不需要成对出现，甚至可以写成&amp;lt;br&amp;gt;。省略/的又是另外一种自闭合类型。它们在处理起来有点麻烦，特别是涉及到深度折叠的时候。解决的办法也是设置状态变量，标识当前节点属于那种类型，以此来区分判断。&lt;/p&gt;
&lt;p&gt;这篇写得可能有点简单，因为的确是比较抽象的东西。我也偷偷懒，相信能做到前章所提的词法分析的情况下，纯理论来读本篇也不是什么难事了。可能直接读我的源代码反而会更容易些。在&lt;a href=&quot;http://army8735.org/2010/02/23/669.html&quot; target=&quot;_blank&quot;&gt;下一篇&lt;/a&gt;当中，我会介绍as和js的交互以及jssc的大概处理流程，它将作为结束篇章。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/340428158/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340428158/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340428158/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340428158/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://army8735.org/2010/02/02/608.html/feed</wfw:commentRss><slash:comments>2</slash:comments><description>内嵌解析
很容易遇到这样的情况：在需要高亮的代码中还混淆着其它语言种类的代码（最常见的例子为Html内嵌css和js，以下也将以此为例）。这是一件让人头疼的事情，因为无论采用何种方法，内嵌的语言和原本语言的规则一定是不同的。这意味着必须将它们区分开来对待。从这一点出发，自然而然就能引出问题的关键所在——如何区分？
剥离内容
先来考虑最简单的情况：
&amp;#60;head&amp;#62;
&amp;#60;script&amp;#62;var i = 0;&amp;#60;/script&amp;#62;
&amp;#60;/head&amp;#62;
假如没有第2行的script标签以及其内部的代码，那么整个就是纯html代码高亮，这个没有什么难度（如果已经完全理解前三篇的此法分析的话）。然而不凑巧的是，关键点就在于script标签中会出现js代码，html的此法分析中并没有js的词法规则，两者不能等同。那么怎么办呢？
答案是将它们剥离出来。上例是最简单的例子，我们在对html进行此法分析的时候，一旦读到了&amp;#60;script&amp;#62;开始标签，接着便去寻找&amp;#60;/script&amp;#62;结束标签（一般会使用String.indexOf()来查找），然后将标签里面的内容单独提取出来。这是第一步，如果做完的话，此时html的高亮结果应该是：除了js代码没有高亮（即默认颜色）以外，其它的html代码均被正确高亮了。
更复杂的情况
剥离到此还没有结束，因为剥离要考虑其它一些复杂的元素。看以下代码：
&amp;#60;head&amp;#62;
&amp;#60;script&amp;#62;var i = 0;
//&amp;#60;/script&amp;#62;
&amp;#60;/script&amp;#62;
&amp;#60;/head&amp;#62;
代码的第3行中，出现了单行注释，其中有被注释掉的script结束标签。这点需要格外注意。假若使用String.indexOf()来查询script结束标签的话，那么就会在第3行结束。这样就错了，因为第3行实际上是个注释，真正的结束符在第4行。
以此延伸，除了上面的情况以外，引号中的字符串、多行注释、正则里面均会出现类似情况。因此，单纯的String.indexOf()是肯定不行的。我们必须对js代码部分进行预处理。
预处理
在as的解析部分，实际上主要分为两大块：词法分析和存储结果。词法分析即是前面几篇一直在讲解的内容；存储结果即是将分析出来的代码链接起来，说白了就是简单的字符串拼接。
在html中的js代码可能会出现混淆script结束标签的情况之下，唯一解决的办法就是对js也进行简单的词法分析预处理，但不存储结果。因为分析是“读”，而存储是“写”。写的耗时要比读多多了，而且预处理只是为了防止注释、字符串和正则的混淆，不需要真正地进行解析，实现复杂读也比较低。等完全将js代码从html中剥离后，再交给js解析器来做真正的工作，如此也保证了代码的不重复。
&amp;#60;head&amp;#62;
&amp;#60;script&amp;#62;
var i = 0;
//&amp;#60;/script&amp;#62;
&quot;&amp;#60;/script&amp;#62;&quot;
/*&amp;#60;/script&amp;#62;*/
/[&amp;#60;/script&amp;#62;]/
&amp;#60;/script&amp;#62;
&amp;#60;/head&amp;#62;
html中的预处理，至少要保证能将3到7行的js代码完全剥离出来交给js解析器处理，其它html代码则由本身来完成高亮。
状态区分
接下来的难点可能还是在如何在html解析的时候完成区分上面。在这里，我设置了一个state变量用以标识状态。仔细考虑下html，无非发现它主要有以下几种状态：

html节点：即&amp;#60;&amp;#62;内的tag，还有随之的一些属性内容。如：&amp;#60;img width=&amp;#8221;100px&amp;#8221;/&amp;#62;。
text节点：文本内容，段落p中最常见到。
css节点：style中的css代码。
script节点：script中的js代码。

在默认最开始的时候，是文本节点。一旦遇到了左尖括号，并且随后跟的是个正确的节点名（&amp;#60;x&amp;#62;绝对不是个正确的节点，所以不能当成节点来处理），那么就进入节点状态来解析；当节点解析完了之后，返回文本状态。css和script节点是个两个特殊的节点，因为在它们的开始标签结束之后，要进行预处理查找结束标签。实际上会做其中的一个，另外一个也就懂了。
值得注意的是，html标签中有单个类型的存在，比如&amp;#60;br/&amp;#62;，它不需要成对出现，甚至可以写成&amp;#60;br&amp;#62;。省略/的又是另外一种自闭合类型。它们在处理起来有点麻烦，特别是涉及到深度折叠的时候。解决的办法也是设置状态变量，标识当前节点属于那种类型，以此来区分判断。
这篇写得可能有点简单，因为的确是比较抽象的东西。我也偷偷懒，相信能做到前章所提的词法分析的情况下，纯理论来读本篇也不是什么难事了。可能直接读我的源代码反而会更容易些。在下一篇当中，我会介绍as和js的交互以及jssc的大概处理流程，它将作为结束篇章。&lt;img src=&quot;http://www1.feedsky.com/t1/340428158/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~7851743/340428158/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/army8735/340428158/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/army8735/340428158/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>jssc</category><category>语法高亮原理</category><category>系列文章</category><pubDate>Tue, 02 Feb 2010 14:11:39 +0800</pubDate><author>army8735</author><comments>http://army8735.org/2010/02/02/608.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=608</guid><dc:creator>army8735</dc:creator><fs:srclink>http://army8735.org/2010/02/02/608.html</fs:srclink><fs:srcfeed>http://www.army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~7851743/340428158/5961215</fs:itemid></item></channel></rss>