<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_EtherDream の 原创空间</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/83633/rss</id><updated>2012-06-02T01:14:36Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/83633/rss"/><entry><id>http://www.cnblogs.com/index-html/archive/2012/06/01/2531286.html</id><title type="text">一行代码告别 document.getElementById</title><summary type="text">很久以前做网页的时候，几乎没有听说过 getElementById 这一玩意儿。在那个ie独占天下的年代里，做的页面也几乎都是ie only的。只要ie没问题，那就OK了。所以绝大多数的脚本里，都是直接通过元素的id来访问DOM的。 后来随着各种浏览器接踵而至，逐渐的替代了ie。为了保证各路门派统一规则，标准化越来越被重视。当初那种直接访问id的方法，逐渐被document.getElementById所替代。如果这年头还在用id访问元素，要么就是做程序里的内嵌网页，要么就是像铁道部那样的超境界仿古网站：） 当然只要保证你的用户都是用ie访问，这样的非标准也但用无妨。 然而，很...</summary><published>2012-06-01T12:48:00Z</published><updated>2012-06-01T12:48:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2012/06/01/2531286.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2012/06/01/2531286.html"/><content type="html">&lt;p&gt;很久以前做网页的时候，几乎没有听说过 getElementById 这一玩意儿。在那个ie独占天下的年代里，做的页面也几乎都是ie only的。只要ie没问题，那就OK了。所以绝大多数的脚本里，都是直接通过元素的id来访问DOM的。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;后来随着各种浏览器接踵而至，逐渐的替代了ie。为了保证各路门派统一规则，标准化越来越被重视。当初那种直接访问id的方法，逐渐被document.getElementById所替代。如果这年头还在用id访问元素，要么就是做程序里的内嵌网页，要么就是像铁道部那样的超境界仿古网站：） 当然只要保证你的用户都是用ie访问，这样的非标准也但用无妨。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;然而，很多第三方浏览器刚出来的时候，为了保证能与当时大量的非标准页面兼容，都保留了用id访问DOM这一非标准做法。事实上如今的主流浏览器，只有FireFox不支持这种做法，而Chrome,Opera,Safari,Mobile Safari都支持。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;既然如此，我们不如让FireFox也支持，这样所有的浏览器都可以直接用id直接访问DOM，不仅快捷方便，减少了累赘的代码，更能提升运行的效率。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;实现很简单，文档载入完成后查询带有id属性的元素，然后在window对象里添加其引用：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; list = document.querySelectorAll('[id]'&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; i = 0; i &amp;lt; list.length; i++&lt;span style="color: #000000;"&gt;)&lt;br/&gt;{&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(list[i].id)&lt;br/&gt;        window[list[i].id] &lt;/span&gt;=&lt;span style="color: #000000;"&gt; list[i];&lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p&gt;当然，只有FF需要这个hack，所以我们先检测下是否有其特征。最后精简下代码，利用数组遍历回调，即可压缩到简单的一行：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;mozHidden&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;'&lt;/span&gt; &lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; document) [].forEach.call(document.querySelectorAll(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;[id]&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;),&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;(k){self&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;[k.id]&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;k});&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;不过有个值得注意的地方，在文档载入尚未完成前 querySelectorAll，只能查询当前&amp;lt;script&amp;gt;之前的元素。所以以上代码&lt;strong&gt;必须放在文档的末尾&lt;/strong&gt;。而使用id访问，也必须在文档载入完成之后，否则就可能找不到这个元素。下面是个测试页面，在所有浏览器下都通过：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #ff00ff;"&gt;DOCTYPE html&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;No document.getElementById&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;div &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="mytag"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;&lt;br/&gt;onload &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=&lt;/span&gt; &lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;()&lt;br/&gt;{&lt;br/&gt;    mytag.innerHTML &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=&lt;/span&gt; &lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;Goodbye, document.getElementById!&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;;&lt;br/&gt;}&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;mozHidden&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;'&lt;/span&gt; &lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; document) [].forEach.call(document.querySelectorAll(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;[id]&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;'&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;),&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;(e){self&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;[e.id]&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=e&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;});&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2531286.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2012/06/01/2531286.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2012/05/29/jsgear.html</id><title type="text">JsGear -- JavaScript版变速齿轮</title><summary type="text">根据传统变速齿轮原理，移植到JavaScript上，方便动画脚本的观察和调试。插件完全使用JS/CSS编写，引入测试页面即可使用。</summary><published>2012-05-29T07:09:00Z</published><updated>2012-05-29T07:09:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2012/05/29/jsgear.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2012/05/29/jsgear.html"/><content type="html">&lt;p&gt;在JS开发中经常会用到定时器，尤其是一些动画特效，小游戏等完全依靠定时器驱动。&lt;/p&gt;&lt;p&gt;要让动画跑得更流畅，我们常常使用较高的刷新率，例如60fps。由于每一帧的间隔非常短，很难看清楚每一帧具体的运行情况。&lt;/p&gt;&lt;p&gt;有时整体上看似乎一切良好，但如果放慢定时器的速度，却会发现其中有部分帧或因代码里的小问题，并没有按我们想象那样显示。由于播放的非常快，这些潜在的小问题都掩盖了。&lt;/p&gt;&lt;p&gt;为了方便动画脚本的观察和调试，我们尝试用js模仿一个类似windows下经典的应用程序：变速齿轮，能即时修改系统时钟的运行频率！这听起来似乎很神奇吧~其实原理并不复杂。&lt;/p&gt;&lt;p&gt;和传统的变速齿轮运行机制一样，我们使用钩子程序勾住默认那几个定时器相关的API &amp;mdash;&amp;mdash; &lt;em&gt;setTimeout&lt;/em&gt;, &lt;em&gt;setInterval&lt;/em&gt;, &lt;em&gt;clearTimeout&lt;/em&gt;, &lt;em&gt;clearInterval&lt;/em&gt;。当然，所谓的钩子程序，无非就是预先保存原来的API引用，接着用自己的程序覆盖他们。这样我们就可以拦截之后的定时器调用，然后根据虚拟时钟的速率，自己维护回调队列，于是就产生了定时器变速的效果。如果同步上再严密点，甚至还可以覆盖Date对象，让时间的流逝速度都随之而变！&lt;/p&gt;&lt;p&gt;当然，有不少问题仍然难以解决的。&lt;/p&gt;&lt;p&gt;时钟频率被加快后，每一帧的时间间隔被大幅缩短，甚至小于1ms。而js定时器频率众所周知，远达不到这样的精度。于是只能用&amp;ldquo;跳帧&amp;rdquo;来解决这个问题。例如，一个2ms的定时器，理论上应该每2ms触发一次，但某个浏览器最短只支持16ms的间隔，那么每次定时器触发内循环调用 16/2 = 8次回调，来弥补频率上的不足。但由于这8次回调是在同个事件里一口气执行的，所以前7次的界面操作都不会立即渲染出来，只有第8次的操作才会有所表现，所以就有了&amp;ldquo;跳&amp;rdquo;的感觉。&lt;/p&gt;&lt;p&gt;但是这个方法只能解决 setInterval 的定时器，因为它的时间间隔以及回调都是固定的。对于 setTimeout 这样每次延时不确定的，甚至还无法确定下一帧是否接着运行，跳帧机制就有些无从为力了。&lt;/p&gt;&lt;p&gt;不过只实现一个基本功能的还是比较容易的：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;JsGear&lt;/em&gt;&lt;/strong&gt;，就是根据这个思路实现的 JavaScript 变速齿轮插件，对时间相关的API都进行了严密的封装。因为它完全是用js/css制作的，所以不依赖任何插件，引入页面就可以使用。&lt;/p&gt;&lt;p&gt;为了让使用更快捷，这两天换了一个新概念的操作界面，并且支持IE6+, FireFox, Chrome, Safari, Opera浏览器，以及Quirks模式。&lt;/p&gt;&lt;p&gt;测试Demo: &amp;nbsp;&lt;a href="http://www.etherdream.com/JSGear/demo.html" target="_blank"&gt;http://www.etherdream.com/JSGear/demo.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/273626/2012052910525429.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;在自己的页面里测试很简单，把jsgear.js插入到所有的脚本之前就可以。这里上传了一份到博客附件里，复制下面代码到自己的页面内即可使用：&lt;/p&gt;&lt;p&gt;&lt;span style="background-color: #0000ff; color: #c0c0c0;"&gt;&amp;lt;scrpt src="http://files.cnblogs.com/jsapp/jsgear.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;span style="background-color: #0000ff; color: #c0c0c0;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;当然，目前还只是演示版本，实现了基本功能，还有不少小问题。大家要是有什么好多思路和建议，欢迎探讨。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2523998.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2012/05/29/jsgear.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2012/05/09/iframe_cheat.html</id><title type="text">【漫画详解】用iframe障眼法，骗取用户点击</title><summary type="text">尝试给一个iframe设置裁剪区域，只留下里面的想让用户点击的部分，然后将裁剪后的iframe伪装成页面里的按钮，让用户点！</summary><published>2012-05-09T11:53:00Z</published><updated>2012-05-09T11:53:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2012/05/09/iframe_cheat.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2012/05/09/iframe_cheat.html"/><content type="html">&lt;p&gt;做过Web开发的朋友曾经都有过这么个念头：在自己的页面里内嵌一个其他网站的网页，然后可以用脚本去获取他们页面里的信息，甚至可以。。。&lt;/p&gt;&lt;p&gt;显然，有这么好的事也肯定轮不到你来尝了：）一个叫&lt;strong&gt;沙箱模型&lt;/strong&gt;的东西被发明出来，就是防止有这种想法的人搞破坏。。。所以现在的我们只能远观，不可亵玩也。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/273626/2012050923062398.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;不过，这些规定只是针对脚本而已。假如让用户自己乖乖的去点，那当然是没问题的。但有多少人会去点呢！！&lt;/p&gt;&lt;p&gt;所以，我们需要施一些特殊的障眼法，让用户在不经意间，就点了我们想让他点的东西：）&lt;/p&gt;&lt;p&gt;就拿上面那个来说吧，如果直接把这个大页面赤果果的硬塞进网页，无论你怎么提示他点，或者说多少好话，大家见了就烦，就是不点：）&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/273626/2012050919180715.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;所以说，我们必须得修饰修饰，不然人家见了就吓跑了。首先也是最关键的就是这身材问题，突然冒出个这么肥硕的一个页面，看的人眼花缭乱，不知道发送什么情况啦。我们要好好修剪一下，把没用的部分统统去掉，只留下我们想要的&amp;ldquo;精华&amp;rdquo;。这个简单，只要把框架先放到一个层里面，然后把层的尺寸固定好，最后调整下框架的偏移位置，朝左上方移，正好让&amp;ldquo;加关注&amp;rdquo;完全显示在层里面。（用css的clip属性就更简单了，不过有些浏览器不支持）&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/273626/2012050922004134.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这样一来，庞大的微博页面，只露出我们希望用户点的那个&amp;ldquo;按钮&amp;rdquo;了。但这几个字还是会让用户知道我们的意图，所以必须去掉。要修改iframe的内容当然是不可能的，但上面放些文字或图片，那框架就被覆盖，收不到事件了。不过别急，我们仅仅是要让用户看不到&amp;ldquo;加关注&amp;rdquo;这几个字而已，并不一定要真正的去掉。所以，我们只需&lt;strong&gt;给iframe设置一个很小很小的透明度&lt;/strong&gt;，让他&amp;ldquo;看不见却摸得着&amp;rdquo;。&lt;/p&gt;&lt;p&gt;最后，就差粉饰粉饰了。我们给div设置一个背景图片，里面画着&amp;ldquo;关闭广告&amp;rdquo;，或者&amp;ldquo;不再提示&amp;rdquo;之类的，让用户觉得点了有意义的按钮。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/273626/2012050919394117.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;若是嫌这个按钮太小，没有吸引用户去点的魅力，那么不难。我们只需用zoom(或transform: scale)属性放大一下iframe就行了，根据放大的比例，调整下裁剪的区域，OK。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/273626/2012050919451770.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;哈哈，够土的办法！要是再装饰装饰，放到某个页面里，有时还真能做些事儿，尤其是页面里一些不需要用户确认的操作，只要对应的按钮位置是固定的话，就很容易中了这圈套。&lt;/p&gt;&lt;p&gt;当然从防范角度来考虑，在一些重要的操作里，最好能判断是否被嵌套在人家的页面里。若不能，则需要个验证码验证，哪怕是个提示对话框，也能防住这类弱智的骗局。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2492465.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2012/05/09/iframe_cheat.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2011/12/31/js_battlecity.html</id><title type="text">【分享】曾经做的一个JS小游戏——《Battle City》</title><summary type="text">曾经写的一个JS版本《坦克大战》游戏，纯粹的JS/CSS制作。作为2012贺岁礼物分享给大家吧~对于初学OOP思想，或者游戏基本概念的，都可以参考下</summary><published>2011-12-30T17:12:00Z</published><updated>2011-12-30T17:12:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2011/12/31/js_battlecity.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2011/12/31/js_battlecity.html"/><content type="html">&lt;p&gt;今天改网盘密码时，找到了个很久前的东西：JavaScript版的坦克大战。07年的夏天制作花了好多个夜晚制作，那段着迷JS游戏的疯狂时光。但因为后来众多浏览器的出现，导致了游戏兼容性大大的下降，最终放弃了更新。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;尽管到了如今HTML5大红大紫，不过要兼容主流浏览器，还是逃不过IE这关。如此说来，还不如纯粹的div+css制作的js应用兼容性最好了：）&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;之前也发过，但是当时因为找不到源码，所以从压缩过的JS反向修改回来，导致代码混乱不堪。之前做的尺寸很小，今天把图片放大了一倍，晚上闲着把关数增加到了原版35关。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;（方向键：ASDW 射击：KL连发：IO确定：Enter【第一次可以进入选关】）&lt;/p&gt;&lt;p&gt;&lt;iframe src="http://www.etherdream.com/FunnyScript/BattleCity/" frameborder="0" width="600" height="500"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;(源链接：&lt;a href="http://goo.gl/uex0x" target="_blank"&gt;http://goo.gl/uex0x&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;之前用jsmin压缩代码的，换成现在的google closure编译会出现问题。因此现在修改下框架结构和部分模块，现在可以用ADVANCED_OPTIMIZATIONS压缩了，如果有什么BUG留言。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;整个工程4000行左右的代码，包括一个叫WebPlay的游戏库。用到的都是很基本方法和概念，总体并不复杂。对于初学OOP思想，或者游戏基本概念的，都可以参考下！ 作为2012贺岁礼物分享给大家吧~&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Source: &lt;a href="http://files.cnblogs.com/index-html/BattleCity.rar" target="_blank"&gt;http://files.cnblogs.com/index-html/BattleCity.rar&amp;nbsp;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/273626/2012010320225929.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011123111483586.png" alt="" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2308300.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2011/12/31/js_battlecity.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2011/11/25/run_js_in_as.html</id><title type="text">【探索】用ActionScript模拟运行JavaScript</title><summary type="text">尝试在ActionScript运行时下执行JavaScript代码。探索借用Flash的IDE调试JS，改进开发模式。</summary><published>2011-11-25T08:31:00Z</published><updated>2011-11-25T08:31:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2011/11/25/run_js_in_as.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2011/11/25/run_js_in_as.html"/><content type="html">&lt;p&gt;先来段简单的代码：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; JSDemo()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; doc = window.document;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; div = doc.createElement("div");&lt;br /&gt;    &lt;br /&gt;    div.innerHTML = "Hello! &amp;lt;i&amp;gt;This box is created by JavaScript!&amp;lt;/i&amp;gt;";&lt;br /&gt;    &lt;br /&gt;    div.style.background = "#CCC";&lt;br /&gt;    div.style.font = "bolder 18px 'Courier New'";&lt;br /&gt;    div.style.border = "1px dashed #693";&lt;br /&gt;    &lt;br /&gt;    doc.body.appendChild(div);&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;这是再简单不过的JS代码，最基本的DOM创建和操作。不过把他复制到ActionScript里，它还能运行吗？显然不可能。虽然他们有着相似语法，但运行环境完全不同，当然是连编译都通不过的。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;仔细思考下，AS3虽然是JavaScript2.0的风格，但也向下兼容当前的JS语法。仅语法上说，JS复制到AS下是没有语法错误的，只是变量没有定义类型的提示的警告。但Flash SDK没有提供Web的接口，所以window，document这些变量就不存在了，因此无法通过编译。显然，如果我们能够提供这些接口，那么代码至少能通过编译。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;纵观Web下的各种接口，都是从window对象延伸开来。所以我们只需模拟出window对象，之后其他对象就可以从这个顶级接口中获取。由于不同浏览器下的接口都各不相同，并且错综复杂，所以手工的去模拟每一个接口的功能是不现实的。因此我们需要一个AS和Web之间的代理程序，实现接口的自动转换。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;ActionScript自带一个功能强大的类: flash.utils.Proxy。继承它之后，我们的类就可以实现一些底层的操作。我们可以覆盖对象默认的属性读写，方法调用等等，类似C++的operator操作符。通过ExternalInterface.call，我们可以向Flash所在Web页面进行交互，并返回数据，于是我们就可以实现AS/JS接口自动化代理了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;例如，当访问window对象的document属性时，我们的getProperty重载函数向Web发送&amp;ldquo; 获取window的document属性&amp;rdquo;指令。Web端的JS收到指令后，将document属性从window对象读取。不过由于document也是个对象，不是基本类型，所以不能直接返回给AS，而是将其储存在数组里，返回给AS一个对象序列号，这个字符串里包含了数组的id位置。当以后访问document的属性时，这个代表document对象的序列号就会传递过去，js就能从数组里还原这个对象。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;不过要实现JS/AS函数变量的传递就要麻烦些。因为其中涉及到闭包等问题，所以仅仅传递函数字符串是肯定行不通的。解决这个办法，需要和存储对象类型一个办法：发送方在传递函数前先储存起来，传递的只是一个序列号；接收方收到序列号后，新建一个代理函数，里面包含了这个序列号。当以后被调用时，代理函数将序列号作为参数通知给对方，对方通过序列号从数组里取出原函数，执行。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;这样一个大致的轮廓就出来了：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011112517263013.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;目前一些常用功能可以正常运行。下面写了几个简单的JSDemo，能在ActionScript正常运行：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.etherdream.com/FunnyScript/RunJS/RunJS.html" target="_blank"&gt;http://www.etherdream.com/FunnyScript/RunJS/RunJS.html&amp;nbsp;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;iframe src="http://www.etherdream.com/FunnyScript/RunJS/RunJS.html" frameborder="0" width="800" height="500"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 14pt;"&gt;&lt;strong&gt;不要忘了，这些JS可是运行在ActionScript环境下的！&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;package&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;import&lt;/span&gt; flash.display.*;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; RunJS &lt;span style="color: #0000ff;"&gt;extends&lt;/span&gt; Sprite&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; window:JSEnv = JSEnv.$;&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; RunJS()&lt;br /&gt;        {&lt;br /&gt;            JSLine("DOM Demo:");&lt;br /&gt;            JSDemo1();&lt;br /&gt;            &lt;br /&gt;            JSLine("Event Demo:");&lt;br /&gt;            JSDemo2();&lt;br /&gt;            &lt;br /&gt;            JSLine("Closure Demo:");&lt;br /&gt;            JSDemo3();&lt;br /&gt;            &lt;br /&gt;            JSLine("AJAX Demo:");&lt;br /&gt;            JSDemo4();&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; JSLine(str)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; doc = window.document;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; div = doc.createElement("div");&lt;br /&gt;            &lt;br /&gt;            div.innerHTML = "&amp;lt;p&amp;gt;" + str + "&amp;lt;hr/&amp;gt;&amp;lt;/p&amp;gt;"&lt;br /&gt;            doc.body.appendChild(div);&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; JSDemo1()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; doc = window.document;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; div = doc.createElement("div");&lt;br /&gt;            &lt;br /&gt;            div.innerHTML = "Hello! &amp;lt;i&amp;gt;This box is created by ActionScript!&amp;lt;/i&amp;gt;";&lt;br /&gt;            &lt;br /&gt;            div.style.background = "#CCC";&lt;br /&gt;            div.style.font = "bolder 18px 'Courier New'";&lt;br /&gt;            div.style.border = "1px dashed #693";&lt;br /&gt;            &lt;br /&gt;            doc.body.appendChild(div);&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; JSDemo2()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; doc = window.document;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; btn = doc.createElement("button");&lt;br /&gt;            &lt;br /&gt;            btn.innerHTML = "Click Me!";&lt;br /&gt;            btn.onclick = &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;()&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; i = 0;&lt;br /&gt;                window.setInterval(&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;()&lt;br /&gt;                {&lt;br /&gt;                    btn.innerHTML = "Run in ActionScript: i=" + i++;&lt;br /&gt;                }, 10)&lt;br /&gt;            };&lt;br /&gt;            &lt;br /&gt;            doc.body.appendChild(btn);&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; JSDemo3()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; doc = window.document;&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; i=0; i&amp;lt;5; i++)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; btn = doc.createElement("button");&lt;br /&gt;                doc.body.appendChild(btn);&lt;br /&gt;                &lt;br /&gt;                btn.innerHTML = "Button" + i;&lt;br /&gt;                btn.onclick = (&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;(i)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;(){window.alert(i)};&lt;br /&gt;                })(i);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; JSDemo4()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; doc = window.document;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; btn = doc.createElement("button");&lt;br /&gt;            &lt;br /&gt;            doc.body.appendChild(btn);&lt;br /&gt;    &lt;br /&gt;            btn.innerHTML = "Load Test.xml";&lt;br /&gt;&lt;br /&gt;            btn.onclick = &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;()&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; xhr = window.ActiveXObject?&lt;br /&gt;                    new window.ActiveXObject("Microsoft.XMLHTTP"):&lt;br /&gt;                    new window.XMLHttpRequest;&lt;br /&gt;                &lt;br /&gt;                xhr.onreadystatechange = &lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;()&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(xhr.readyState != 4)&lt;br /&gt;                        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;                    &lt;br /&gt;                    window.alert(xhr.responseText);&lt;br /&gt;                };&lt;br /&gt;&lt;br /&gt;                xhr.open("GET", "Test.xml", &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;);&lt;br /&gt;                xhr.send();&lt;br /&gt;            };&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt; 当然，目前仍有不少问题有待解决。这里将继续研究，借用ActionScript强大的IDE来调试JavaScript。并且升级之前的JS解释器，将ActionScript解释成更高效的JS。从而彻底抛弃混乱纠结的JS-OOP。有兴趣的继续关注。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2263472.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2011/11/25/run_js_in_as.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2011/11/12/web_lzma.html</id><title type="text">【探索】JS/Alchemy/C++ 实现Web在线7z解压缩</title><summary type="text">尝试在Web里使用7z压缩数据。利用Alchemy编译出高效的LZMA算法，在AVM2虚拟机中运行。配合JS+AS，即可实现数据在线解压。</summary><published>2011-11-12T15:15:00Z</published><updated>2011-11-12T15:15:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2011/11/12/web_lzma.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2011/11/12/web_lzma.html"/><content type="html">&lt;p&gt;几个月前的一个实验项目：Web在线解码7z压缩。不过最新各种新技术不断涌现，过不了多久这个估计又要OUT了，所以拿出来分享下。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;测试：&lt;a href="http://www.etherdream.com/LZMA/HTML/Demo.html" target="_blank"&gt;http://www.etherdream.com/LZMA/HTML/Demo.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;iframe src="http://www.etherdream.com/LZMA/HTML/Demo.html" frameborder="0" width="700" height="600"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;自从划时代的Alchemy出现，让我原本鄙视的Flash到了至高无上。我们可以把C/C++编译成AVM2虚拟机指令，在Flash中运行，而Flash有着如此高的装有率，终于使我们有机会在Web里实现高密集的运算，从而摆脱as和js低效。作为元老级的C和C++，几乎每种经典的算法都以它为原版发布，然后移植到其他各种语言。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;7z压缩的核心算法叫做LZMA。比传统的zip及rar，压缩率都要高。他是一个开源项目，通过Alchemy，我们轻而易举的编译出自己的解码器。然后即可在Web中实现LZMA解码了。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;lzma插件需要2个文件：lzma.js和lzma.swf。后者即为解码器。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;在引入LZMA.js后，需等到解码器就绪才可以使用，就是lzma.swf载入成功。通过setListener指定ready事件，才可以载入压缩文件。相关调用参考Demo。 &lt;br /&gt;&lt;br /&gt; 调用$LZMA.load(url, charset)方法，下载指定的压缩包并解码。其中charset可以指定文本文件的字符编码，例如utf-8，gb2312等等。如果是二进制文件的话，指定charset为base64，返回的就是经过base64编码的文本。&lt;br /&gt;&lt;br /&gt; 当然，本例中使用的.z格式文件，并非传统的7z格式文档，而是自己实现的一种很简易的格式，用来保存压缩包基本的几个参数。你想尝试下将自己的文件压缩成.z格式，下载&lt;a href="http://www.etherdream.com/LZMA/Encode.rar" target="_blank"&gt;LZMA压缩程序&lt;/a&gt;。里面附带了C源码。在cmd下调用：&lt;strong&gt;lzma.exe file&lt;/strong&gt; 即可压缩。默认为最高压缩比，需要600M的空闲内存。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; 不久前&lt;strong&gt;Flash11&lt;/strong&gt;发布了，其中&lt;strong&gt;支持用LZMA压缩SWF文件&lt;/strong&gt;。在未来Flash11流行后，我们可以利用内置的功能实现一个更高效的LZMA解码方案。尽请期待。&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2246874.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2011/11/12/web_lzma.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2011/11/08/ecma262_eval.html</id><title type="text">标准的JS里，eval和window.eval属于不同的语法！</title><summary type="text">ECMA-262中eval是一个类似关键字的标记符。和this一样，既是关键字也是变量（函数变量）。window.eval仅仅是window对象里的一个叫eval的属性，指向eval函数的属性，和eval字面意义完全不同。</summary><published>2011-11-08T10:51:00Z</published><updated>2011-11-08T10:51:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2011/11/08/ecma262_eval.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2011/11/08/ecma262_eval.html"/><content type="html">&lt;p&gt;最近写的一个脚本里需要在全局下执行代码。这个例子以前见到过，在IE6，7，8下用&lt;span style="text-decoration: underline;"&gt;window.exeScript&lt;/span&gt;方法，其他则调用&lt;span style="text-decoration: underline;"&gt;window.eval&lt;/span&gt;方法即可。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;看似很简单，运行也正确。eval声明的a只有内部可见；window.eval声明的b全局可见。&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; A()&lt;br /&gt;{&lt;br /&gt;    eval(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var a=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);&lt;br /&gt;    window.eval(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var b=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;A();&lt;br /&gt;&lt;br /&gt;alert(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; a);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;undefined&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;alert(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; b);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;number&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;不过事后回想起来感觉有些诡异。eval和window.eval不就同个函数吗，为什么加上window.意义就不同了呢？如果说eval内部判断了当前this，那么eval和window.eval执行时，this都是指向window。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;如果用变量p=window.eval，那么p()和window.eval()还一样吗？&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; A()&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; p &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; window.eval;&lt;br /&gt;&lt;br /&gt;    alert(p &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;===&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; window.eval);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;true&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;    alert(p &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;===&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; eval);           &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;true&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;&lt;br /&gt;    eval(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var a=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);&lt;br /&gt;    p(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var b=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;A();&lt;br /&gt;&lt;br /&gt;alert(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; a);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;undefined&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;alert(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; b);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;number&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;经测试，p()和window.eval()的效果完全一样，都是在全局执行。并且p === window.eval 和 p === eval 同时成立！这显然很奇怪，不过还有更奇怪的事在后面！如果我们用q=eval，结果完全出人意料：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; A()&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; p &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; window.eval;&lt;br /&gt;    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; q &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; eval;&lt;br /&gt;&lt;br /&gt;    p(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var a=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);&lt;br /&gt;    q(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var b=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;A();&lt;br /&gt;&lt;br /&gt;alert(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; a);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;number&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;alert(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; b);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;number&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;居然显示的都是number！也就是说指向eval的p，实际效果却是window.eval。他们都是在全局执行代码！&lt;/p&gt;&lt;p&gt;为了验证是否是引用上的区别，我们再做一次测试：&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; A()&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; q &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; eval;&lt;br /&gt;&lt;br /&gt;    q(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var b=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);&lt;br /&gt;    eval(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var a=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;A();&lt;br /&gt;&lt;br /&gt;alert(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; a);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;undefined&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;alert(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; b);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;number&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;明显，eval执行的a被留在了内部，而q=eval的b却是全局的！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;于是我推测，&lt;strong&gt;标准JavaScript下的eval，也许和this一样，既是关键字，也是一个变量（函数变量）&lt;/strong&gt;。如果是当关键字调用的话，即字面上的eval()，那么在当前的上下文里执行；否则，即通过变量引用调用的话，就在全局上执行。这样就可以解释 window.eval　和 eval 的区别了：&lt;strong&gt;window.eval仅仅是window对象里的一个叫eval的属性，一个指向eval函数的属性&lt;/strong&gt;。和window.eval2，window.eval3一样，仅仅一个属性，并非字面上的eval。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;为了验证这个猜测，我查看了 FireFox 的脚本引擎源码。其中eval真正的执行部分定义在 jsobj.cpp 中的 EvalKernel 里：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&lt;br /&gt;EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame *caller,&lt;br /&gt;           JSObject *scopeobj)&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;     * Per ES5, indirect eval runs in the global scope. (eval is specified this&lt;br /&gt;     * way so that the compiler can make assumptions about what bindings may or&lt;br /&gt;     * may not exist in the current frame if it doesn't see 'eval'.)&lt;br /&gt;     &lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;br /&gt;    uintN staticLevel;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #ff0000;"&gt;evalType == DIRECT_EVAL&lt;/span&gt;) {&lt;br /&gt;        staticLevel = caller-&amp;gt;script()-&amp;gt;staticLevel + &lt;span style="color: #800080;"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    } &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt; {&lt;br /&gt;        &lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt; Pretend that we're top level. &lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;br /&gt;        staticLevel = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        JS_ASSERT(scopeobj == scopeobj-&amp;gt;getGlobal());&lt;br /&gt;        JS_ASSERT(scopeobj-&amp;gt;isGlobal());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;显然，你发现这个函数里有个叫 evalType 的参数，正是这个参数，决定了eval的是否在全局运行。如果是 DIRECT_EVAL，staticLevel 就是当前的上下文；否则 staticLevel=0，就是全局。&lt;/p&gt;&lt;p&gt;顺藤摸瓜，我们又在jsinterp.cpp里发现以 DIRECT_EVAL 模式调用 EvalKernel：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ff0000;"&gt;DirectEval&lt;/span&gt;(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp)&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    JSObject *scopeChain =&lt;br /&gt;        GetScopeChainFast(cx, caller, JSOP_EVAL, JSOP_EVAL_LENGTH + JSOP_LINENO_LENGTH);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!scopeChain || !&lt;span style="color: #ff0000;"&gt;EvalKernel&lt;/span&gt;(cx, argc, vp, &lt;span style="color: #ff0000;"&gt;DIRECT_EVAL&lt;/span&gt;, caller, scopeChain))&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    cx-&amp;gt;regs-&amp;gt;sp = vp + &lt;span style="color: #800080;"&gt;1&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;而调用DirectEval的地方，正是定义关键字的区域：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;}&lt;br /&gt;END_CASE(&lt;span style="color: #ff0000;"&gt;JSOP_NEW&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;BEGIN_CASE(&lt;span style="color: #ff0000;"&gt;JSOP_EVAL&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;    argc = GET_ARGC(regs.pc);&lt;br /&gt;    vp = regs.sp - (argc + &lt;span style="color: #800080;"&gt;2&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!IsFunctionObject(*vp, &amp;amp;callee))&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;goto&lt;/span&gt; call_using_invoke;&lt;br /&gt;&lt;br /&gt;    newfun = callee-&amp;gt;getFunctionPrivate();&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!IsBuiltinEvalFunction(newfun))&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;goto&lt;/span&gt; call_using_invoke;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #ff0000;"&gt;DirectEval&lt;/span&gt;(cx, newfun, argc, vp))&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;goto&lt;/span&gt; error;&lt;br /&gt;}&lt;br /&gt;END_CASE(JSOP_EVAL)&lt;br /&gt;&lt;br /&gt;BEGIN_CASE(&lt;span style="color: #ff0000;"&gt;JSOP_CALL&lt;/span&gt;)&lt;br /&gt;BEGIN_CASE(JSOP_FUNAPPLY)&lt;br /&gt;BEGIN_CASE(JSOP_FUNCALL)&lt;br /&gt;{&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;很明显，eval 和 new 他们一样，都当关键字处理了。也就是说，只有在代码里出现&amp;ldquo;eval(...)&amp;rdquo;这几个字的时候，才会传入DIRECT_EVAL，即在当前上下文内执行。&lt;/p&gt;&lt;p&gt;可见，&lt;strong&gt;ECMA-262的eval有着关键字的特性&lt;/strong&gt;！但并非是真正的关键字，因为关键字是不可以作为对象属性名出现的，例如window.this，window.var是错误的语法。但eval可以。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;那假如在上下文里声明了一个叫eval的变量，并且指向window.eval。那么又会如何呢？&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&amp;lt;script&amp;gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; A()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; eval = window.eval;&lt;br /&gt;&lt;br /&gt;    eval("var a=1");&lt;br /&gt;    eval("var b=1");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;A();&lt;br /&gt;&lt;br /&gt;alert(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt; a);    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;undefined&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;alert(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt; b);    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;undefined&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&amp;lt;/script&amp;gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;为什么是undefined呢？因为此 eval 就是原 eval 嘛~ 都是在内部执行了。(Chrome例外，当作eval的引用对待了，结果是number)&lt;/p&gt;&lt;p&gt;但也不代表eval不能被覆盖：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;&lt;br /&gt;eval &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;=&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; alert;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt; A()&lt;br /&gt;{&lt;br /&gt;    eval(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var a=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;var a=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;    window.eval(&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;var b=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;"&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;);    &lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;//&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;var b=1&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="background-color: #f5f5f5; color: #000000;"&gt;}&lt;br /&gt;&lt;br /&gt;A();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;正常弹出两个对话框。&lt;br /&gt;可见，&lt;strong&gt;在上下文环境中，eval只要保持指向原始的那个函数，没被覆盖，就有着关键字的特征&lt;/strong&gt;；否则就是一个叫eval的变量了。jsinterp.cpp中BEGIN_CASE(JSOP_EVAL)｛｝里的代码也说明了这点。&lt;/p&gt;&lt;p&gt;p&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2241538.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2011/11/08/ecma262_eval.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2011/11/08/bubbles.html</id><title type="text">【分享】翻出过去的一个多彩泡泡屏保特效(JS+CSS版)</title><summary type="text">整理文件时翻出一个好久前做的泡泡屏保的特效，纯JS+CSS做的。回想了下，是去年年初时看见XP下那个流行的泡泡屏保，突然想移植到JS版本来。但有做着才发现有不少麻烦的问题解决不好，于是没继续。和XP系统自带的那个屏保一样，从屏幕一个角落里冒出很多泡泡，然后在屏幕里碰撞反弹。泡泡有着半透明的渐变色，并且颜色也是在不停的变换。</summary><published>2011-11-08T04:11:00Z</published><updated>2011-11-08T04:11:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2011/11/08/bubbles.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2011/11/08/bubbles.html"/><content type="html">&lt;p&gt;整理文件时翻出一个好久前做的泡泡屏保的特效，纯JS+CSS做的。回想了下，是去年年初时看见XP下那个流行的泡泡屏保，突然想移植到JS版本来。但有做着才发现有不少麻烦的问题解决不好，于是没继续。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;DEMO： &lt;a href="http://www.etherdream.com/funnyscript/bubbles/" target="_blank"&gt;http://www.etherdream.com/funnyscript/bubbles/&amp;nbsp;&lt;/a&gt; &amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011110813562995.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;和XP系统自带的那个屏保一样，从屏幕一个角落里冒出很多泡泡，然后在屏幕里碰撞反弹。泡泡有着半透明的渐变色，并且颜色也是在不停的变换。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;当时这个效果分析了不少时间。如果是用flash那就再简单不过了，把泡泡蒙板的灰色通道复制到一个纯色的背景层的Alpha通道就可以了。但是网页里除非用HTML5的canvas，单凭纯粹的CSS还没那么强大的位图处理能力。在CSS里，和透明度有关的道具也只有这几个：png图片，css alpha值，rgba()，chroma滤镜，mask滤镜，AlphaImageLoader滤镜，以及CSS3的渐变。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011110814063480.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;你也许会说，这不是很简单，给png图片层设置各种background-color，不就可以实现颜色的变换了吗。事实上，背景色不但混合到了半透明像素中，连泡泡外的四个边角也给填充了，这样就成了方块，而不是泡泡了，并且颜色也不正确。显然没有这么简单。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011110814153046.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;因为泡泡是半透明渐变的材质，chroma和mask这些过滤单色的滤镜都派不上用场。而rgba的背景色同样也会出现多余的背景。 AlphaImageLoader滤镜经测试，实际显示出来的图片在background之上， 与&amp;lt;img&amp;gt;载入png效果一样。而CSS3的渐变和本例的蒙板配合起来比较困难，而且兼容性也有问题。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;本例的困难之处在于：&lt;strong&gt;图片本身不仅是半透明渐变的，并且这些渐变点的颜色还能通过脚本改变&lt;/strong&gt;。考虑了很久，既然没有一个简便的方法，那不如就用复杂的吧~&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;大家都知道，颜色都是RGB组成的，调整3种原色的比例，就可以变出各种颜色。我们不妨把灰色蒙板事先填入R,G,B三种纯色，保存为3张图片。这样就有了100%的红色泡泡，绿色泡泡，蓝色泡泡。&lt;strong&gt;把他们叠在同个位置，然后给3张图片设置不同的css alpha值，于是就有了各种颜色的泡泡，并且半透明的像素仍然保留！&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011110813452479.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt; 于是这个彩色的问题就解决了。不过值得注意的是，蓝色位于最顶层，而红色则是最底层。即使是红色层100%的不透明，也会被蓝色和绿色层的PNG层层剥削，很明显的减淡。所以实际显示时，还需给蓝和绿层分别加个权值，以保证红色通道不会那么的微弱，而蓝的那么的明显。&lt;strong&gt;不过在IE里的显示效果仍是蓝色很明显&lt;/strong&gt;，不知道IE的透明度计算方式和标准浏览器有什么不同。。。 (2010/2/1)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;后续：当时对ie的mask滤镜理解不对，mask滤镜并非是单色的过滤，而是：&lt;span style="color: #ff0000;"&gt;&lt;strong&gt;用指定的RGB颜色替换容器内所有点的RGB，并且Alpha'=255 - Alpha&lt;/strong&gt;&lt;/span&gt;。所以ie下只要把蒙板图片的Alpha通道取反，然后同时用AlphaImageLoader和Mask滤镜，即可达到效果，Mask滤镜的color参数就是泡泡的颜色。另在Webkit内核的浏览器下，可以使用-webkit-mask-image直接应用一个图片蒙板！（2011/11/10）&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2240946.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2011/11/08/bubbles.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2011/10/25/doodle_fans.html</id><title type="text">【分享】Doodle精美相册。收集了近几年的Google Logo</title><summary type="text">前些时候做的一个卡片式相册，收集了近几年的Doodle。 本人最忠诚的Google Fans :) 页面支持所有的桌面浏览器外，还兼容了iOS系统的mobile safari。你可以体验下用手指拖曳精美的Doodle卡片~在桌面电脑上，你的显示器分辨率越高，视觉效果就越好，别忘了可以按F11全屏浏览。 页面除了用来观赏外，另一个用途就是测试你的浏览器性能。目前排名是Firefox最流畅，而据称渲染最快的Opera反倒最慢... 有iPad2或者iPhone4S的朋友不妨可以试试，双核的强大威力：）</summary><published>2011-10-25T14:00:00Z</published><updated>2011-10-25T14:00:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2011/10/25/doodle_fans.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2011/10/25/doodle_fans.html"/><content type="html">&lt;p&gt;前些时候做的一个卡片式相册，收集了近几年的Doodle。&lt;/p&gt;&lt;p&gt;&lt;img src="http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=100x100&amp;amp;choe=UTF-8&amp;amp;chld=H%7C0&amp;amp;chl=http://goo.gl/26NYQ" alt="" /&gt;&lt;span style="font-size: 20px;"&gt;&lt;a href="http://www.etherdream.com/Doodle/" target="_blank"&gt;http://www.etherdream.com/Doodle/&amp;nbsp;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;页面支持所有的桌面浏览器外，还兼容了iOS系统的mobile safari。你可以体验下用手指拖曳精美的Doodle卡片~&lt;/p&gt;&lt;p&gt;在桌面电脑上，你的显示器分辨率越高，视觉效果就越好，别忘了可以按F11全屏浏览。&amp;nbsp;&lt;/p&gt;&lt;p&gt;页面除了用来观赏外，另一个用途就是测试你的浏览器性能。目前排名是Firefox最流畅，而据称渲染最快的Opera反倒最慢...&amp;nbsp;&lt;/p&gt;&lt;p&gt;有iPad2或者iPhone4S的朋友不妨可以试试，体验下双核的速度：）&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;【有些卡片可能带有敏感词，被天朝河蟹了。】&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011102521590071.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011102522070720.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/273626/2011102522073614.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2224490.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2011/10/25/doodle_fans.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/index-html/archive/2011/10/09/xmlhttp_code_min.html</id><title type="text">【挑战极限】最短AJAX创建代码</title><summary type="text">无聊时尝试了下最短的XHR创建代码</summary><published>2011-10-08T16:14:00Z</published><updated>2011-10-08T16:14:00Z</updated><author><name>EtherDream</name><uri>http://www.cnblogs.com/index-html/</uri></author><link rel="alternate" href="http://www.cnblogs.com/index-html/archive/2011/10/09/xmlhttp_code_min.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/index-html/archive/2011/10/09/xmlhttp_code_min.html"/><content type="html">&lt;p&gt;下午写了篇最短地址栏载入脚本的文章。不过再怎么短仍然没什么意思，纯属娱乐下罢了。刚才想起能缩短个平时经常用到的代码就好了，于是现在一边写一边来研究，最短的XMLHTTP组建创建。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;假如你的脚本只针对某个浏览器开发，那么创建XMLHTTP是很简单的一件事，用XMLHttpRequest或者ActiveXObject即可。但事实上绝大多数的时候，我们都要考虑兼容，于是我们通常写成：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; x;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;(window.ActiveXObject)&lt;br /&gt;    x = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ActiveXObject("Microsoft.XMLHTTP");&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br /&gt;    x = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; XMLHttpRequest();&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;当然，熟练的朋友更倾向于简练的代码：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; x = window.ActiveXObject?&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ActiveXObject("Microsoft.XMLHTTP"):&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; XMLHttpRequest();&lt;/div&gt;&lt;p&gt;但也到此而已。这段代码还能继续压缩吗？我们不妨来探索下。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;现在我们把一堆单词: ActiveXObject,&amp;nbsp; "Microsoft.XMLHTTP", XMLHttpRequest, window 配上几个符号重新排列起来，组合出一个语法正确并且能正常运行的表达式。&lt;/p&gt;&lt;p&gt;首先我们最容易想到的就是共用一个new。因为JS里面有个很强大的运算符&amp;ldquo;&lt;span style="color: #ff0000;"&gt;||&lt;/span&gt;&amp;rdquo;，相信大家都用过。所以我们先用||得出Class，然后用new实例化出instance。于是:&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;(&lt;/span&gt;window.XMLHttpRequest || ActiveXObject("Microsoft.XMLHTTP")&lt;span style="color: #ff0000;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;p&gt;很不幸，它没能通过IE6，7的考验。（IE8+已经支持XMLHttpRequest了）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;错误很简单，就在ActiveXObject("Microsoft.XMLHTTP")上。&lt;span style="color: #ff0000;"&gt;Automation 服务器不能创建对象。&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;在IE里，ActiveXObject(...)之前必须带上new，否则就会出现上面的错误&lt;/strong&gt;。但请注意了，ActiveXObject后面是带参数调用的。如果我们单独引用ActiveXObject这个函数，然后再实例化，结果会如果呢？我们测试下：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; ref = ActiveXObject;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; x = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ref("Microsoft.XMLHTTP");&lt;br /&gt;&lt;br /&gt;x.open("GET", "1.html", &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;);&lt;br /&gt;x.send();&lt;br /&gt;alert(x.responseText)&lt;/div&gt;&lt;p&gt;&lt;br /&gt;结果不但没有报错，并且成功的显示出了文字。这说明window.ActiveXObject这个方法是可以引用调用，但必须用new才能创建组建。这很好理解：function ActiveXObject(){}的Native Code会判断当前是new call还是direct call，如果不是new call就报错。这意味着你不能预先创建出XMLHTTP的Class，而必须用ActiveXObject的工厂形式。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;既然事实如此，我们只能用&lt;span style="color: #ff0000;"&gt;XMLHttpRequest || ActiveXObject&lt;/span&gt;这样的逻辑。如果带上new，我们就得到这样的代码:&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; (window.XMLHttpRequest || ActiveXObject)&lt;/div&gt;&lt;p&gt;这对XHR的创建已经够了，但是ActiveX还需要提供一个参数指定组件名。这个参数加在哪里好呢？不用多虑，就放在最后！&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;因为XMLHttpRequest的构造函数是不带参数的，而JS是个弱类型语言，所以你即便给他指定一个参数也不会出问题。&lt;/strong&gt;于是最后，我们用一行表达式即可创建:&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; (window.XMLHttpRequest || ActiveXObject)("Microsoft.XMLHTTP")&lt;/div&gt;&lt;p&gt;&lt;br /&gt;因为IE8+即支持 XMLHttpRequest 和 ActiveXObject，因此上面 || 左右顺序决定了IE8+优先使用哪种。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;不过，这还不是最简短的！没错，还有更精简的，但显得不是特别正规，甚至有点晦涩。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;纵观上述代码，其中的window显得有点多余，但又不能去掉。假如有个简单的办法判断是（或者不是）IE浏览器，我们就可以用 ?: 运算符来代替 || 了。&lt;/p&gt;&lt;p&gt;曾经有个老外写过最简短判断IE的办法，只需6个字节 !-[1,] &amp;nbsp;原理就是IE特有的特征，数组处理最后项的bug。利用这个办法，我们还可以进一步压缩代码：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;(&lt;/span&gt;-[1,]&lt;span style="color: #ff0000;"&gt;?&lt;/span&gt;XMLHttpRequest&lt;span style="color: #ff0000;"&gt;:&lt;/span&gt;ActiveXObject&lt;span style="color: #ff0000;"&gt;)&lt;/span&gt;("Microsoft.XMLHTTP")&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="text-decoration: line-through;"&gt;无疑，这是最简短的XMLHTTP创建代码了！正好60个字节。 但相比规范性和可读性，还是推荐之前那种。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;补充：感谢经典论坛上的crimsonet网友提醒，其实用self对象完全可以代替window。self是window的只读属性，并且永远指向window，所以用：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;(self.XMLHttpRequest||ActiveXObject)("Microsoft.XMLHTTP")&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;也正好是60字节，并且更规范：）&lt;/p&gt;&lt;p&gt;（如果不是在内嵌框架里运行的话，top===window，还能-1。在框架内top引用顶层窗体，当然会有问题的了）&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/index-html/aggbug/2203170.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/index-html/archive/2011/10/09/xmlhttp_code_min.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
