<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>YY in Limbo 混沌海狂想 &#187; Ajax</title>
	<atom:link href="http://www.limboy.com/category/coder/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.limboy.com</link>
	<description>这里既空虚又充实，没有规则，没有约束，创造来自思考，生存依赖想像，现实源自梦想</description>
	<lastBuildDate>Fri, 07 Oct 2011 19:33:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>HTML5, CSS3, ES5&#8230;新的web标准和浏览器支持一览</title>
		<link>http://www.limboy.com/2009/06/29/html5-css3-es5-support/</link>
		<comments>http://www.limboy.com/2009/06/29/html5-css3-es5-support/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 00:40:26 +0000</pubDate>
		<dc:creator>Dexter.Yy</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[web服务/应用]]></category>
		<category><![CDATA[代码]]></category>

		<guid isPermaLink="false">http://www.limboy.com/2009/06/29/html5-css3-es5-support/</guid>
		<description><![CDATA[好罢这篇本来是我私下做的笔记，我特别喜欢在Evernote上做备忘的笔记，虽然上次看到漏屋老师的文章里说我现在的年龄才刚刚进入记忆力的巅峰期……但是我的自信心仍然屡受打击！比如跟别人讨论The Dark Knight里小丑在医院对检察官说了什么让他变成双面人，我一句对白都想不起来，还有big bang theory s2里penny玩age of conan时的人物名字是&#8221;Queen Penelope&#8221;，我看的时候印象很深，一个月后就连奥德赛都想不起来了。留份笔记总觉得心里踏实些……啊又跑题了
本文整理了一些最重要（或者说人气比较高罢）的新标准，虽然它们多数还只是w3c的草案，离Recommendation级别还早，却已经成为新一轮浏览器大战中备受追捧的明星，开发者社区里也涌现出大量相关的demo和API封装，有些已经进入生产环境（比如google在iphone上实现的gmail离线应用），其实我觉得如今的web领域里，从厂商私有技术转换成委员会标准再转换成通用技术产生杀手级应用的周期已经显著的加速了，是因为现在web application的需求太高了么…… UPDATE：刚才在solidot发软文的时候我突然想明白怎么表述这个问题：其实现在很多浏览器厂商同时也是基于浏览器的应用开发者和web标准的制定者，就好像修筑舞台的工程师同时也是舞台上的演员和舞蹈动作的导演一样，所以google, mozilla, apple们都在不遗余力的实现那些有利于开发web应用的技术标准，即时它们还是W3C Working Draft，相比之下IE team就比较缺乏动力，果然计划经济缺乏活力亚XD……
由于是源自笔记，对每个条目我只会列出称呼和语法特征，暂时没时间写详细的解释和可执行的示例，但是会给出相关的文档地址，除了列出已经支持该特性的浏览器，也会为不支持的浏览器提供替代/过渡的实现。
===================废话结束的分割线=======================
CSS3 Media queries
对整个外链css文件和部分css代码使用的媒体类型侦测，人气高的原因显然是因为移动设备……
&#60;link media=“all and (orientation:portrait)” src=&#34;screen.css&#34; type=&#34;text/css&#34;&#62;
@media all and (min-color: 4) { ... }
w3c标准：http://www.w3.org/TR/css3-mediaqueries/
MDC文档：https://developer.mozilla.org/En/CSS/Media_queries
Opera文档：http://www.opera.com/docs/specs/css/
支持：Firefox 3.5+, Safari 3+, Opera 7+

CSS3 2D Transforms
css变形，有人用这个实现伪3d效果以及旋转效果的jquery插件
-moz-transform: rotate(-45deg) skew(15deg, 15deg);
sprite.style['-webkit-transform'] = 'rotate(' + v + 'rad)';
w3c标准：http://www.w3.org/TR/css3-2d-transforms/
MDC文档：https://developer.mozilla.org/En/CSS/CSS_transform_functions
webkit博客的介绍: http://webkit.org/blog/130/css-transforms/
支持：Firefox 3.5+, Safari 3.1+
替代/过渡：IE5.5+ Matrix Filter http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx

CSS3 Transitions and [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.limboy.com/2009/06/29/html5-css3-es5-support/bwjpg/' rel='attachment wp-att-239' title='bw.jpg'><img src='http://www.limboy.com/wp-content/uploads/2009/06/bw.jpg' alt='bw.jpg' style="float:left;border:0;margin:0 10px 0 0;" /></a>好罢这篇本来是我私下做的笔记，我特别喜欢在<a target="_blank"  href="http://evernote.com/">Evernote</a>上做备忘的笔记，虽然上次看到<a target="_blank"  href="http://cache.tianya.cn/publicforum/content/english/1/121795.shtml">漏屋老师的文章</a>里说我现在的年龄才刚刚进入记忆力的巅峰期……但是我的自信心仍然屡受打击！比如跟别人讨论The Dark Knight里小丑在医院对检察官说了什么让他变成双面人，我一句对白都想不起来，还有big bang theory s2里penny玩age of conan时的人物名字是&#8221;Queen Penelope&#8221;，我看的时候印象很深，一个月后就连奥德赛都想不起来了。留份笔记总觉得心里踏实些……啊又跑题了</p>
<p>本文整理了一些最重要（或者说人气比较高罢）的新标准，虽然它们多数还只是w3c的草案，离Recommendation级别还早，却已经成为新一轮浏览器大战中备受追捧的明星，开发者社区里也涌现出大量相关的demo和API封装，有些已经进入生产环境（比如google在iphone上实现的<a target="_blank"  href="http://www.wired.com/epicenter/2009/02/google-turns-to/">gmail离线应用</a>），其实我觉得如今的web领域里，从厂商私有技术转换成委员会标准再转换成通用技术产生杀手级应用的周期已经显著的加速了<span id="more-238"></span>，是因为现在web application的需求太高了么…… <strong>UPDATE：</strong>刚才在solidot发软文的时候我突然想明白怎么表述这个问题：其实现在很多浏览器厂商同时也是基于浏览器的应用开发者和web标准的制定者，就好像修筑舞台的工程师同时也是舞台上的演员和舞蹈动作的导演一样，所以google, mozilla, apple们都在不遗余力的实现那些有利于开发web应用的技术标准，即时它们还是W3C Working Draft，相比之下IE team就比较缺乏动力，果然计划经济缺乏活力亚XD……</p>
<p>由于是源自笔记，对每个条目我只会列出称呼和语法特征，暂时没时间写详细的解释和可执行的示例，但是会给出相关的文档地址，除了列出已经支持该特性的浏览器，也会为不支持的浏览器提供替代/过渡的实现。</p>
<p>===================废话结束的分割线=======================</p>
<h3>CSS3 Media queries</h3>
<p>对整个外链css文件和部分css代码使用的媒体类型侦测，人气高的原因显然是因为移动设备……</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Olive;">&lt;</span><span style="color: Green;">link</span><span style="color: Gray;"> </span><span style="color: #00008b;">media</span><span style="color: Gray;">=“</span><span style="color: #00008b;">all</span><span style="color: Gray;"> </span><span style="color: #00008b;">and</span><span style="color: Gray;"> (</span><span style="color: #00008b;">orientation:portrait</span><span style="color: Gray;">)” </span><span style="color: #00008b;">src</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">screen.css</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: #00008b;">type</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">text/css</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;</span></li></ol></div>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #00008b;">@media</span><span style="color: Gray;"> </span><span style="color: Blue;">all</span><span style="color: Gray;"> </span><span style="color: Blue;">and</span><span style="color: Gray;"> (min-color: 4) </span><span style="color: Olive;">{</span><span style="color: Gray;"> ... </span><span style="color: Olive;">}</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/css3-mediaqueries/">http://www.w3.org/TR/css3-mediaqueries/</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/En/CSS/Media_queries">https://developer.mozilla.org/En/CSS/Media_queries</a><br />
Opera文档：<a target="_blank"  href="http://www.opera.com/docs/specs/css/">http://www.opera.com/docs/specs/css/</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+, Safari 3+, Opera 7+</strong><br />
<br/></p>
<h3>CSS3 2D Transforms</h3>
<p>css变形，有人用这个实现<a target="_blank"  href="http://ajaxian.com/archives/fun-with-3d-css-and-video">伪3d效果</a>以及<a target="_blank"  href="http://www.zachstronaut.com/projects/rotate3di/">旋转效果的jquery插件</a></p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Gray;">-moz-transform: </span><span style="color: Blue;">rotate</span><span style="color: Gray;">(-45</span><span style="color: Blue;">deg</span><span style="color: Gray;">) </span><span style="color: Blue;">skew</span><span style="color: Gray;">(15</span><span style="color: Blue;">deg</span><span style="color: Gray;">, 15</span><span style="color: Blue;">deg</span><span style="color: Gray;">);</span></li></ol></div>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">sprite</span><span style="color: Gray;">.</span><span style="color: Blue;">style</span><span style="color: Olive;">[</span><span style="color: #8b0000;">'</span><span style="color: Red;">-webkit-transform</span><span style="color: #8b0000;">'</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: #8b0000;">'</span><span style="color: Red;">rotate(</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> + </span><span style="color: Blue;">v</span><span style="color: Gray;"> + </span><span style="color: #8b0000;">'</span><span style="color: Red;">rad)</span><span style="color: #8b0000;">'</span><span style="color: Gray;">;</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/css3-2d-transforms/">http://www.w3.org/TR/css3-2d-transforms/</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/En/CSS/CSS_transform_functions">https://developer.mozilla.org/En/CSS/CSS_transform_functions</a><br />
webkit博客的介绍: <a target="_blank"  href="http://webkit.org/blog/130/css-transforms/">http://webkit.org/blog/130/css-transforms/</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+, Safari 3.1+</strong><br />
<strong style="color:#ff6600;">替代/过渡：IE5.5+ Matrix Filter <a target="_blank"  href="http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx</a></strong><br />
<br/></p>
<h3>CSS3 Transitions and CSS Animations</h3>
<p>备受期待的css动画，webkit团队提出的草案，transition实现简单的属性渐变，animation定义更复杂的动画效果</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Gray;">transition-property: </span><span style="color: Blue;">width</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">transition-duration: 1</span><span style="color: Blue;">s</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">animation-name: '</span><span style="color: Blue;">diagonal-slide</span><span style="color: Gray;">';</span></li>
<li><span style="color: Gray;">animation-duration: 5</span><span style="color: Blue;">s</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">animation-iteration-count: 10;</span></li>
<li><span style="color: #00008b;">@keyframes</span><span style="color: Gray;"> '</span><span style="color: Blue;">diagonal-slide</span><span style="color: Gray;">' </span><span style="color: Olive;">{}</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/css3-transitions/">http://www.w3.org/TR/css3-transitions/</a><br />
w3c标准：<a target="_blank"  href="http://www.w3.org/TR/css3-animations/">http://www.w3.org/TR/css3-animations/</a><br />
webkit博客的介绍：<a target="_blank"  href="http://webkit.org/blog/138/css-animation/">http://webkit.org/blog/138/css-animation/</a><br />
约翰同学的介绍：<a target="_blank"  href="http://ejohn.org/blog/css-animations-and-javascript/">http://ejohn.org/blog/css-animations-and-javascript/</a></p>
<p><strong style="color:#ff6600;">支持：Safari 3.1+</strong><br />
<br/></p>
<h3>CSS3 Downloadable fonts</h3>
<p>能在网页里嵌入任意字体是设计师的梦想……不过这里支持的也仅限truetype和opentype</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #00008b;">@font</span><span style="color: Gray;">-</span><span style="color: Blue;">face</span><span style="color: Gray;"> </span><span style="color: Olive;">{}</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/css3-fonts/#font-resources">http://www.w3.org/TR/css3-fonts/#font-resources</a><br />
MSDN文档：<a target="_blank"  href="http://msdn.microsoft.com/en-us/library/ms530303(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms530303(VS.85).aspx</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/en/CSS/@font-face">https://developer.mozilla.org/en/CSS/@font-face</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+, Safari 3.1+, Opera 10.0+, IE4.0+</strong><br />
<br/></p>
<h3>附赠：其他CSS3 property的兼容性</h3>
<p>ppk同学维护的文档: <a target="_blank"  href="http://www.quirksmode.org/css/contents.html">http://www.quirksmode.org/css/contents.html</a><br />
css3.info维护的文档：<a target="_blank"  href="http://www.css3.info/modules/selector-compat/">http://www.css3.info/modules/selector-compat/</a><br />
一个测试页面：<a target="_blank"  href="http://westciv.com/iphonetests/">http://westciv.com/iphonetests/</a><br />
<br/></p>
<h3>HTML5 DOM Storage</h3>
<p>简洁的持久存储，键值对的形式</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">window.localStorage</span></li>
<li><span style="color: Blue;">window.sessionStorage</span><span style="color: Gray;"> //可跨域，标签页关掉就清空</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/webstorage/">http://www.w3.org/TR/webstorage/</a><br />
ppk同学维护的兼容性列表：<a target="_blank"  href="http://www.quirksmode.org/dom/html5.html#localstorage">http://www.quirksmode.org/dom/html5.html#localstorage</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/en/DOM/Storage">https://developer.mozilla.org/en/DOM/Storage</a><br />
MSDN文档：<a target="_blank"  href="http://msdn.microsoft.com/en-us/library/cc197062(VS.85).aspx">http://msdn.microsoft.com/en-us/library/cc197062(VS.85).aspx</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+, Safari 4.0+, IE 8.0+</strong><br />
<br/></p>
<h3>HTML5 Offline Application Cache</h3>
<p>用一个manifest文件缓存静态资源（图片,css, js之类）在离线状态下使用，不是结构化数据</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Olive;">&lt;</span><span style="color: Green;">html</span><span style="color: Gray;"> </span><span style="color: #00008b;">manifest</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">foo.manifest</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;</span></li></ol></div>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline">CACHE MANIFEST</li>
<li>index.html</li>
<li>style/default.css</li>
<li>images/logo.png</li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/offline-webapps/#offline">http://www.w3.org/TR/offline-webapps/#offline</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/en/Offline_resources_in_Firefox">https://developer.mozilla.org/en/Offline_resources_in_Firefox</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+</strong><br />
<br/></p>
<h3>HTML5 Database Storage</h3>
<p>本地数据库，支持sql，最早是google gears实现，现在的w3c草案的编辑也是google的工程师……但奇怪的是，gears的api跟现在的草案不兼容，chrome甚至为了保留捆绑的gears的数据库api而删除了webkit实现的html5 api……而google在iphone上实现gmail离线功能的时候又采用webkit的api……真纠结……</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">db</span><span style="color: Gray;"> = </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">openDatabase</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">notes</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;&quot;</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">The Example Notes App!</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Maroon;">1048576</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">db</span><span style="color: Gray;">.</span><span style="color: Blue;">transaction</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">tx</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span></li>
<li><span style="color: Blue;">tx</span><span style="color: Gray;">.</span><span style="color: Blue;">executeSql</span><span style="color: Olive;">(</span><span style="color: Gray;">‘</span><span style="color: Blue;">SELECT</span><span style="color: Gray;"> * </span><span style="color: Blue;">FROM</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Notes</span><span style="color: Gray;">’, </span><span style="color: Olive;">[]</span><span style="color: Gray;">, </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">tx</span><span style="color: Gray;">, </span><span style="color: Blue;">rs</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{})</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">})</span><span style="color: Gray;">;</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/offline-webapps/#sql">http://www.w3.org/TR/offline-webapps/#sql</a><br />
webkit博客的介绍：<a target="_blank"  href="http://webkit.org/blog/126/webkit-does-html5-client-side-database-storage/">http://webkit.org/blog/126/webkit-does-html5-client-side-database-storage/</a><br />
iphone的文档：<a target="_blank"  href="http://developer.apple.com/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/UsingtheJavascriptDatabase/UsingtheJavascriptDatabase.html#//apple_ref/doc/uid/TP40007256-CH3-SW1">http://developer.apple.com/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/UsingtheJavascriptDatabase/UsingtheJavascriptDatabase.html#//apple_ref/doc/uid/TP40007256-CH3-SW1</a></p>
<p><strong style="color:#ff6600;">支持：Safari 3.1+</strong><br />
<strong style="color:#ff6600;">替代/过渡：Gears <a target="_blank"  href="http://code.google.com/p/gears/wiki/Database2API">http://code.google.com/p/gears/wiki/Database2API</a></strong><br />
<br/></p>
<h3>HTML5 Web Workers</h3>
<p>多线程，在后台执行复杂运算，不能操作dom，线程之间通过消息事件通信</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">myWorker</span><span style="color: Gray;"> = </span><span style="color: Green;">new</span><span style="color: Gray;"> </span><span style="color: Blue;">Worker</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">my_worker.js</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">myWorker</span><span style="color: Gray;">.</span><span style="color: Blue;">onmessage</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">event</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span style="color: Blue;">event</span><span style="color: Gray;">.</span><span style="color: Blue;">data</span><span style="color: Gray;"> </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">myWorker</span><span style="color: Gray;">.</span><span style="color: Blue;">postMessage</span><span style="color: Olive;">(</span><span style="color: Blue;">str</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/workers/">http://www.w3.org/TR/workers/</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/En/Using_web_workers">https://developer.mozilla.org/En/Using_web_workers</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+</strong><br />
<strong style="color:#ff6600;">替代/过渡：Gears <a target="_blank"  href="http://code.google.com/p/gears/wiki/HTML5WorkerProposal">http://code.google.com/p/gears/wiki/HTML5WorkerProposal</a></strong><br />
<br/></p>
<h3>HTML5 Geolocation</h3>
<p>地理api</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Teal;">navigator</span><span style="color: Gray;">.</span><span style="color: Blue;">geolocation</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/geolocation-API/">http://www.w3.org/TR/geolocation-API/</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/En/Using_geolocation">https://developer.mozilla.org/En/Using_geolocation</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+</strong><br />
<strong style="color:#ff6600;">替代/过渡：Gears <a target="_blank"  href="http://code.google.com/p/gears/wiki/GeolocationAPI">http://code.google.com/p/gears/wiki/GeolocationAPI</a></strong><br />
<br/></p>
<h3>HTML5 Drag and Drop</h3>
<p>原生拖拽事件</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">ondragstart</span></li>
<li><span style="color: Blue;">ondrag</span></li>
<li><span style="color: Blue;">ondragend</span></li>
<li><span style="color: #ffa500;">//拖拽过程中</span></li>
<li><span style="color: Blue;">ondragenter</span></li>
<li><span style="color: Blue;">ondragover</span></li>
<li><span style="color: Blue;">ondragleave</span></li>
<li><span style="color: Blue;">ondrop</span></li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/html5/editing.html#dnd">http://www.w3.org/TR/html5/editing.html#dnd</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/En/DragDrop/Drag_and_Drop">https://developer.mozilla.org/En/DragDrop/Drag_and_Drop</a><br />
apple文档：<a target="_blank"  href="http://developer.apple.com/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/DragAndDrop.html#//apple_ref/doc/uid/30001233">http://developer.apple.com/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/DragAndDrop.html#//apple_ref/doc/uid/30001233</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+, Safari 2.0+, Chrome 1.0+, IE 5.0+</strong><br />
<br/></p>
<h3>HTML5 Audio and Video</h3>
<p>用html标签来嵌入视频音频的好处并非是“开源格式”，而是“开放性”，让多媒体可以与其他页面元素交互，或者<a target="_blank"  href="http://blog.mozbox.org/post/2009/04/12/Firefox-35:-a-new-experiment-with-Canvas-Video">用页面技术去跟视频“mashup”</a>，这种随意组合和交互的能力是web技术兴盛的基石，也是像flash这类封闭RIA容器最大的缺点。</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Olive;">&lt;</span><span style="color: Green;">video</span><span style="color: Gray;"> </span><span style="color: #00008b;">controls</span><span style="color: Olive;">&gt;</span></li>
<li><span style="color: Olive;">&lt;</span><span style="color: Green;">source</span><span style="color: Gray;">&nbsp;</span><span style="color: #00008b;">src</span><span style="color: Gray;">=“</span><span style="color: #00008b;">zombie</span><span style="color: Gray;">.</span><span style="color: #00008b;">ogg</span><span style="color: Gray;">” </span><span style="color: #00008b;">type</span><span style="color: Gray;">=“</span><span style="color: #00008b;">video</span><span style="color: Gray;">/</span><span style="color: Green;">ogg</span><span style="color: Gray;">”</span><span style="color: Olive;">/&gt;</span></li>
<li><span style="color: Olive;">&lt;</span><span style="color: Green;">source</span><span style="color: Gray;">&nbsp;</span><span style="color: #00008b;">src</span><span style="color: Gray;">=“</span><span style="color: #00008b;">zombie</span><span style="color: Gray;">.</span><span style="color: #00008b;">mp4</span><span style="color: Gray;">″ </span><span style="color: #00008b;">type</span><span style="color: Gray;">=“</span><span style="color: #00008b;">video</span><span style="color: Gray;">/</span><span style="color: Green;">mp4</span><span style="color: Gray;">″</span><span style="color: Olive;">/&gt;</span></li>
<li><span style="color: Olive;">&lt;/</span><span style="color: Green;">video</span><span style="color: Olive;">&gt;</span></li></ol></div>
<p>MDC文档：<a target="_blank"  href="https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox">https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox</a><br />
webkit博客的介绍：<a target="_blank"  href="http://webkit.org/blog/140/html5-media-support/">http://webkit.org/blog/140/html5-media-support/</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+, Safari 3.0+, Chrome 3.0+</strong><br />
<strong style="color:#ff6600;">替代/过渡：用video标签嵌套embed <a target="_blank"  href="http://hacks.mozilla.org/2009/06/html5-video-fallbacks-markup/">http://hacks.mozilla.org/2009/06/html5-video-fallbacks-markup/</a></strong><br />
<br/></p>
<h3>HTML5 Canvas</h3>
<p>apple发明，最早应用于dashboard，目前主流的js图像技术，mozilla已经在实现OpenGL ES标准的<a target="_blank"  href="http://blog.vlad1.com/2007/11/26/canvas-3d-gl-power-web-style/">Canvas 3D</a>了，另外据说ie team为支持canvas<a target="_blank"  href="http://processingjs.org/blog/?p=77">做了大量工作</a>……实际上canvas api相当底层，特别是交互方面，不如svg直观，所以出现了很多封装它的库</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">ctx</span><span style="color: Gray;"> = $</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">#canvas</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;">.</span><span style="color: Blue;">getContext</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">2d</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">ctx</span><span style="color: Gray;">.</span><span style="color: Blue;">fillStyle</span><span style="color: Gray;"> = </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">#00A308</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">ctx</span><span style="color: Gray;">.</span><span style="color: Blue;">beginPath</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">ctx</span><span style="color: Gray;">.</span><span style="color: Blue;">arc</span><span style="color: Olive;">(</span><span style="color: Maroon;">220</span><span style="color: Gray;">, </span><span style="color: Maroon;">220</span><span style="color: Gray;">, </span><span style="color: Maroon;">50</span><span style="color: Gray;">, </span><span style="color: Maroon;">0</span><span style="color: Gray;">, </span><span style="color: Teal;">Math</span><span style="color: Gray;">.</span><span style="color: Blue;">PI</span><span style="color: Gray;">*</span><span style="color: Maroon;">2</span><span style="color: Gray;">, </span><span style="color: Green;">true</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">ctx</span><span style="color: Gray;">.</span><span style="color: Blue;">closePath</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">ctx</span><span style="color: Gray;">.</span><span style="color: Blue;">fill</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li></ol></div>
<p>MDC文档：<a target="_blank"  href="https://developer.mozilla.org/en/Canvas_tutorial">https://developer.mozilla.org/en/Canvas_tutorial</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 1.5+, Safari 2.0+, Chrome 1.0+, Opera 9.0+</strong><br />
<strong style="color:#ff6600;">替代/过渡：excanvas.js <a target="_blank"  href="http://code.google.com/p/explorercanvas/">http://code.google.com/p/explorercanvas/</a></strong><br />
<br/></p>
<h3>SVG</h3>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/SVG12/">http://www.w3.org/TR/SVG12/</a><br />
IBM DW教程：<a target="_blank"  href="http://www.ibm.com/developerworks/cn/views/xml/tutorials.jsp?cv_doc_id=84896">http://www.ibm.com/developerworks/cn/views/xml/tutorials.jsp?cv_doc_id=84896</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 1.5+, Safari 3.0+, Chrome 1.0+, Opera 9.0+</strong><br />
<strong style="color:#ff6600;">替代/过渡：raphael.js <a target="_blank"  href="http://raphaeljs.com/">http://raphaeljs.com/</a></strong><br />
<br/></p>
<h3>XMLHttpRequest 2</h3>
<p>主要是增加跨域能力以及请求过程中的事件</p>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/XMLHttpRequest2/">http://www.w3.org/TR/XMLHttpRequest2/</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/En/Using_XMLHttpRequest#Monitoring_progress">https://developer.mozilla.org/En/Using_XMLHttpRequest#Monitoring_progress</a><br />
XDomainRequest (XDR)<br />
MSDN文档：<a target="_blank"  href="http://msdn.microsoft.com/en-us/library/cc288060(VS.85).aspx">http://msdn.microsoft.com/en-us/library/cc288060(VS.85).aspx</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+（实现了部分）, IE 8.0+（实现了部分）</strong><br />
<br/></p>
<h3>Access Control</h3>
<p>千呼万唤的跨域访问控制，目前firefox3.5和ie8有一些不同，ie8搞的XDR和XDM我也不知道是不是准备提交给w3c标准化的东西……</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline">Access-Control-Allow-Origin: http://foo.example</li></ol></div>
<p>w3c标准：<a target="_blank"  href="http://www.w3.org/TR/cors/">http://www.w3.org/TR/cors/</a><br />
MDC文档：<a target="_blank"  href="https://developer.mozilla.org/En/HTTP_Access_Control">https://developer.mozilla.org/En/HTTP_Access_Control</a><br />
Cross-document Messaging (XDM)<br />
MSDN文档：<a target="_blank"  href="http://msdn.microsoft.com/en-us/library/cc197057(VS.85).aspx">http://msdn.microsoft.com/en-us/library/cc197057(VS.85).aspx</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+, IE8.0+</strong><br />
<br/></p>
<h3>E4X (ECMA-357)</h3>
<p>Firefox和ActionScript3早就实现了的东西……不过其实现在json这么流行，有没有E4X好像都无所谓了～（瞎说的，其实在js代码里直接写dom对象而不是html字符串，会方便很多）</p>
<p>MDC文档：<a target="_blank"  href="https://developer.mozilla.org/en/E4X">https://developer.mozilla.org/en/E4X</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 1.5+</strong><br />
<br/></p>
<h3>ECMAScript 5  Native JSON</h3>
<p>原生的JSON支持，速度和安全性都比eval强一百倍亚一百倍，另外要注意Douglas Crockford的json2.js是一个用js实现的js解释器，所以安全性更好</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">JSON</span><span style="color: Gray;">.</span><span style="color: Blue;">parse</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">text</span><span style="color: Gray;">, </span><span style="color: Blue;">translate</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Blue;">JSON</span><span style="color: Gray;">.</span><span style="color: Blue;">stringify</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;">, </span><span style="color: Blue;">translate</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Teal;">String</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">toJSON</span></li>
<li><span style="color: Blue;">Boolean</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">toJSON</span></li>
<li><span style="color: Teal;">Number</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">toJSON</span></li>
<li><span style="color: Teal;">Date</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">toJSON</span></li></ol></div>
<p>MDC文档：<a target="_blank"  href="http://blog.mozilla.com/webdev/2009/02/12/native-json-in-firefox-31/">http://blog.mozilla.com/webdev/2009/02/12/native-json-in-firefox-31/</a><br />
MSDN文档：<a target="_blank"  href="http://blogs.msdn.com/ie/archive/2008/09/10/native-json-in-ie8.aspx">http://blogs.msdn.com/ie/archive/2008/09/10/native-json-in-ie8.aspx</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 3.5+, IE8+</strong><br />
<strong style="color:#ff6600;">替代/过渡：json2.js <a target="_blank"  href="http://www.json.org/json2.js">http://www.json.org/json2.js</a></strong><br />
<br/></p>
<h3>ECMAScript 5  Array Extras</h3>
<p>js1.6里实现的数组方法，主要是forEach, map, fliter这几个函数式编程里非常重要的方法，还有反向查询</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">indexOf</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">str</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">lastIndexOf</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">str</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">every</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">fn</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">some</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">fn</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">filter</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">fn</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">forEach</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">fn</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">map</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">fn</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li></ol></div>
<p>MDC文档：<a target="_blank"  href="https://developer.mozilla.org/en/New_in_JavaScript_1.6#Array_extras">https://developer.mozilla.org/en/New_in_JavaScript_1.6#Array_extras</a></p>
<p><strong style="color:#ff6600;">支持：Firefox2.0+, Safari 3.0+, Google Chrome 1.0+, Opera 9.5+</strong><br />
<strong style="color:#ff6600;">替代/过渡：都可以通过扩展Array.prototype来模拟</strong><br />
<br/></p>
<h3>ECMAScript 5  isArray()</h3>
<p>区分数组和对象</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">isArray</span><span style="color: Olive;">([])</span><span style="color: Gray;">; </span><span style="color: #ffa500;">// true</span></li></ol></div>
<p><strong style="color:#ff6600;">支持：无</strong><br />
<strong style="color:#ff6600;">替代/过渡：Array.isArray = function(a){ return Object.prototype.toString.call(a) === &#8220;[object Array]&#8220;;};</strong><br />
<br/></p>
<h3>ECMAScript 5  Object</h3>
<p>用GOOGLE I/O演讲里的话来说：更鲁棒(robust)的对象系统<br />
<br/></p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">getPrototypeOf</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li></ol></div>
<p>约翰同学的讲解：<a target="_blank"  href="http://ejohn.org/blog/objectgetprototypeof/">http://ejohn.org/blog/objectgetprototypeof/</a></p>
<p><strong style="color:#ff6600;">支持：Firefox3.5</strong><br />
<strong style="color:#ff6600;">替代/过渡：object.__proto__ 或 object.constructor.prototype</strong><br />
<br/></p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">create</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">proto</span><span style="color: Gray;">, </span><span style="color: Blue;">props</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: #ffa500;">//克隆或继承对象</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">keys</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: #ffa500;">//数据结构的映射</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">getOwnPropertyNames</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">preventExtensions</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: #ffa500;">//不能添加新属性</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">isExtensible</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">seal</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: #ffa500;">//不能删除和修改属性的配置，不能添加新属性</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">isSealed</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">freeze</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: #ffa500;">//不能删除和修改属性的配置，不能添加新属性，不能写属性</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">isFrozen</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li></ol></div>
<p>约翰同学的讲解：<a target="_blank"  href="http://ejohn.org/blog/ecmascript-5-objects-and-properties/">http://ejohn.org/blog/ecmascript-5-objects-and-properties/</a></p>
<p><strong style="color:#ff6600;">支持：无</strong><br />
<strong style="color:#ff6600;">替代/过渡：Object.create和Object.keys可以自己实现</strong><br />
<br/></p>
<h3>ECMAScript 5 Property Descriptor</h3>
<p>对象属性的访问控制</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">getOwnPropertyDescriptor</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">obj</span><span style="color: Gray;">, </span><span style="color: Blue;">prop</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">defineProperty</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;">, </span><span style="color: Blue;">prop</span><span style="color: Gray;">, </span><span style="color: Blue;">desc</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">defineProperties</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;">, </span><span style="color: Blue;">props</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">desc</span><span style="color: Gray;"> = </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">value</span><span style="color: Gray;">: </span><span style="color: Green;">true</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">writable</span><span style="color: Gray;">: </span><span style="color: Green;">false</span><span style="color: Gray;">, </span><span style="color: #ffa500;">//修改</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">enumerable</span><span style="color: Gray;">: </span><span style="color: Green;">true</span><span style="color: Gray;">, </span><span style="color: #ffa500;">//for in</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">configurable</span><span style="color: Gray;">: </span><span style="color: Green;">true</span><span style="color: Gray;">, </span><span style="color: #ffa500;">//删除和修改属性</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">get</span><span style="color: Gray;">: </span><span style="color: Green;">function</span><span style="color: Olive;">(){</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Blue;">name</span><span style="color: Gray;">; </span><span style="color: Olive;">}</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp;&nbsp; </span><span style="color: Blue;">set</span><span style="color: Gray;">: </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">value</span><span style="color: Olive;">){</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">name</span><span style="color: Gray;"> = </span><span style="color: Blue;">value</span><span style="color: Gray;">; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>约翰同学的讲解：<a target="_blank"  href="http://ejohn.org/blog/ecmascript-5-objects-and-properties/">http://ejohn.org/blog/ecmascript-5-objects-and-properties/</a></p>
<p><strong style="color:#ff6600;">支持：无</strong><br />
<strong style="color:#ff6600;">替代/过渡：Object.defineProperties其实相当于jQuery.extend，用来实现Mixin</strong><br />
<br/></p>
<h3>ECMAScript 5 Getters and Setters</h3>
<p>python和ruby里都有的属性访问方法</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">obj</span><span style="color: Gray;"> = </span><span style="color: Olive;">{</span><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Blue;">get</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">innerHTML</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span style="color: Green;">return</span><span style="color: Gray;"> …; </span><span style="color: Olive;">}</span><span style="color: Gray;">, </span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Blue;">set</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">innerHTML</span><span style="color: Olive;">(</span><span style="color: Blue;">newHTML</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"> … </span><span style="color: Olive;">}</span><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li></ol></div>
<p>MDC文档：<a target="_blank"  href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters">https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters</a></p>
<p><strong style="color:#ff6600;">支持：Firefox 2.0+, Safari 3.0+, Google Chrome 1.0+, Opera 9.5+</strong><br />
<strong style="color:#ff6600;">替代/过渡：</strong></p>
<p>非标准，Firefox1.5里的旧方法</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">HTMLElement</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">__defineGetter__</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">innerHTML</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{})</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">HTMLElement</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">__defineSetter__</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">innerHTML</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Green;">function</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Blue;">val</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{})</span><span style="color: Gray;">;</span></li></ol></div>
<p><strong style="color:#ff6600;">支持：Firefox 2.0+, Safari 3.0+, Google Chrome 1.0+, Opera 9.5+</strong></p>
<p>标准</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">Object</span><span style="color: Gray;">.</span><span style="color: Blue;">defineProperty</span><span style="color: Olive;">(</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">body</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">innerHTML</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span style="color: Blue;">get</span><span style="color: Gray;"> : </span><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{}</span><span style="color: Gray;"> </span><span style="color: Olive;">})</span><span style="color: Gray;">;</span></li></ol></div>
<p>MSDN文档：<a target="_blank"  href="http://msdn.microsoft.com/en-us/library/dd229916(VS.85).aspx">http://msdn.microsoft.com/en-us/library/dd229916(VS.85).aspx</a></p>
<p><strong style="color:#ff6600;">支持：IE8+ (只能对DOM使用)</strong><br />
<br/></p>
<h3>ECMAScript 5 Strict Mode</h3>
<p>ES5的严格模式，删除了旧版本中容易引起问题的元素，并且会显式的报错，方便调试</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #8b0000;">&quot;</span><span style="color: Red;">use strict</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">; </span><span style="color: #ffa500;">//以下情况下抛出异常</span></li>
<li><span style="color: #ffa500;">//对未定义的变量赋值</span></li>
<li><span style="color: #ffa500;">//操作被设置为不可写，不可配置或不可扩充的属性</span></li>
<li><span style="color: #ffa500;">//删除变量，函数，参数</span></li>
<li><span style="color: #ffa500;">//在对象直接量里重复定义属性</span></li>
<li><span style="color: #ffa500;">//eval做关键字，在eval的字符串里定义变量</span></li>
<li><span style="color: #ffa500;">//覆写arguments</span></li>
<li><span style="color: #ffa500;">//使用arguments.caller和arguments.callee（匿名函数必须具名才能引用自己）</span></li>
<li><span style="color: #ffa500;">//(function(){ ... }).call( null ); // Exception </span></li>
<li><span style="color: #ffa500;">//使用with</span></li></ol></div>
<p>约翰同学的讲解：<a target="_blank"  href="http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/">http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/</a></p>
<p><strong style="color:#ff6600;">支持：无</strong><br />
<strong style="color:#ff6600;">替代/过渡：……从现在开始养成严谨的编程习惯</strong><br />
<br/></p>
<h3>ECMAScript 5 其他新特性</h3>
<p>传递函数的引用时，绑定this</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Teal;">Function</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">bind</span><span style="color: Olive;">(</span><span style="color: Blue;">thisArg</span><span style="color: Gray;">, </span><span style="color: Blue;">arg1</span><span style="color: Gray;">, </span><span style="color: Blue;">arg2</span><span style="color: Gray;">....</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: #8b0000;">/</span></li></ol></div>
<p><strong style="color:#ff6600;">支持：无</strong><br />
<strong style="color:#ff6600;">替代/过渡：prototype <a target="_blank"  href="http://www.prototypejs.org/api/function/bind">http://www.prototypejs.org/api/function/bind</a></strong></p>
<p>ISO-formatted dates</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Teal;">Date</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">toISOString</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: #ffa500;">// Prints 2009-05-21T16:06:05.000TZ</span></li></ol></div>
<p><strong style="color:#ff6600;">支持：无</strong><br />
<strong style="color:#ff6600;">替代/过渡：datejs <a target="_blank"  href="http://code.google.com/p/datejs/">http://code.google.com/p/datejs/</a></strong></p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Teal;">String</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">trim</span><span style="color: Olive;">()</span></li></ol></div>
<p><strong style="color:#ff6600;">支持：Firefox3.5</strong><br />
<strong style="color:#ff6600;">替代/过渡：各种正则实现 <a target="_blank"  href="http://blog.stevenlevithan.com/archives/faster-trim-javascript">http://blog.stevenlevithan.com/archives/faster-trim-javascript</a></strong><br />
<br/><br />
===================废话又开始的分割线=======================</p>
<p>其实我把这个东西发出来是希望能促进创新的氛围，让更多人认识到很多新技术已经进入到“实用”阶段。</p>
<p>如果只是想做个实验性的webgame，或是只能用于特定平台的应用（比如iphone，greasemonkey），firefox3.5+webkit的支持就已经足够罢。</p>
<p>如果不能无视主流平台，有很多技术能让你gracefully degrade（优雅的退化）或者选取不同的方法实现兼容的接口。</p>
<p>如果你等不及IE x在若干年后实现xx，希望提前享受福利，有些技术的设计原则就是让你能在没有native支持的情况下可以自己实现一模一样的功能或语法糖（syntactic sugar），比如ES5对象的继承和访问控制，从ES4/ActionScript3时期那些老土的关键词（class extands private static）改成了Object.create(p, attrs).defineProperty(o, n, attrs).defineProperties(o, attrs).freeze().getOwnPropertyNames().map(fn)，不会只是为了酷炫罢……</p>
<p>很多人都喜欢抱怨“我这辈子都没机会用HTML5”，但是只要把视线从自己脚下那巴掌大块地移开看看别处，会发现世界其实一直都在改变喔XD</p>
]]></content:encoded>
			<wfw:commentRss>http://www.limboy.com/2009/06/29/html5-css3-es5-support/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>iframe和异步的跨域请求，结合土豆网的实例</title>
		<link>http://www.limboy.com/2008/12/31/iframe-cross-site-request/</link>
		<comments>http://www.limboy.com/2008/12/31/iframe-cross-site-request/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 19:00:46 +0000</pubDate>
		<dc:creator>Dexter.Yy</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[代码]]></category>
		<category><![CDATA[土豆网]]></category>

		<guid isPermaLink="false">http://www.limboy.com/2008/12/31/iframe-cross-site-request/</guid>
		<description><![CDATA[这篇文章将会探讨一下在网页里做异步的跨域请求，以及借助iframe来获取数据的方法。
呃，本来我觉得这个话题没什么好说的了，因为如今好像没有几个web应用能离开这类request，google和facebook用iframe来做comet的时候也基本上把能hack的都hack遍了，所以我估计开发者社区里应该早就形成所谓的&#8221;最佳实践&#8221;（best practices）了罢。不过最近看到有一些关注前端技术的blog（比如realazy）在讨论相关的话题，发现还是有一些东西值得写下来。

一、借助script的异步跨域请求
先说跨域的问题，首先要指出的是，iframe里的js宿主对象一样也躲不开同源策略（Same Origin Policy），仅仅能解决二级域名的跨域而已，比如www.tudou.com和so.tudou.com，如果要请求某个八杆子打不到一起去的域名下的数据（例如你想搞mashup），建议老老实实的用script标签去请求JSONP罢。关于JSONP要附带说一下的是，jQuery对JSONP请求的封装方式很值得提倡：
$.getJSON(url, params + &#34;&#38;jsoncallback=?&#34;, function(json){
&#160; &#160; /* do something */
});
用jsoncallback作为服务器端支持的标准jsonp参数，而每次执行这个方法都会用时间戳生成一个唯一的全局函数名，替换这个“?”，这个细节被封装到黑盒里，使用者不必了解，可以像普通的ajax请求一样，用匿名的回调函数作为最末尾的参数（这是jquery强调的风格），这种语法糖（syntactic sugar）的作用绝对不仅仅是让前端开发人员可以偷懒而已，对代码的可读性，兼容性和今后的维护都有好处。（我经常要向服务器端的开发人员解释这个道理，否则他们才不给你支持什么jsoncallback参数呢，直接给你返回一个“yy({……})”就算完工……囧）
二、利用前沿技术的跨域方法
当然了，我们还可以走一些目前来看比较野的路子来实现跨域，比如在页面里嵌入一个不到1K的swf，借助flashplayer向部署了crossdomain.xml的服务器请求数据，再用actionscript里的ExternalInterface类把数据还给javascript（我觉得这种方法忒有调用dll的感觉～大心）。
我们还可以指望ie8里支持的XDomainRequestAllowed，和firefox3.1支持的Access Control，甚至传说中的HTML5 socket……噢喔喔，多么甜美的梦……/掐一把脸蛋
三、用iframe直接发送跨域请求
跟script标签一样，iframe也可以用来替代ajax，而且在修改document.domain之后（比如上面提到的两个域名，可以设置document.domain = &#8220;tudou.com&#8221;），还可以解决部分跨域问题。
通过iframe请求数据的方法，最直接的莫过于在页面里动态的嵌入一个iframe标签，用它的src属性直接请求包含数据的网页，然后利用那个网页里的js把数据传给父页面，比如：
&#60;iframe id=&#34;crossdomain&#34; width=&#34;0&#34; height=&#34;0&#34; style=&#34;visibility:hidden;&#34; src=&#34;http://yoursite.com/request_url/&#34; &#62;&#60;/iframe&#62;
这种方法耦合的太紧，非常不推荐。你请求的URI代表一个资源，应该是单纯的数据，它会作为xml，json，js代码还是html来处理，这个并不重要，不应该把你的程序逻辑跟数据混杂到一起，数据也不应该因为跨域或不跨域，用iframe，script还是ajax来请求就变成完全不同的东西。
有人会说：为了让数据能够被JS处理，返回的内容难免有差异。——但是小的差异可以通过合理的封装隐藏起来，比如JQuery的getJSON方法
有人会说：请求的URI是一个动态页面，同样可以在URI里支持类似jsoncallback的参数，生成一个script标签和其中的JS代码，把数据“包裹”在JS里，比如请求“http://yoursite.com/request_url/?callback=cb1304344”，返回：
&#60;script type=&#34;text/javascript&#34;&#62;
document.domain=&#34;tudou.com&#34;;
top.cb1304344({ /* 数据 */ });
&#60;/script&#62;
——首先，很多情况下你请求到的不会是动态页面，在这个到处都强调高负载的web世界里，你拿到的经常是squid之类的代理程序返回的缓存。其次，如果你请求的是HTML格式的文本，为了能作为JS代码来执行，服务器端必须对这段文本做转义和清理工作，而且安全性还不一定能保证（因为HTML里经常包含很多来自UGC的内容），如果你请求的是JSON格式的数据……那何必用iframe咧……直接嵌script罢……
四、用iframe直接请求数据的最佳实践
我推荐在上述方法的基础上做改良，首先在服务器端，直接返回数据本身，并且把数据“包裹”在一个textarea标签里，比如：
&#60;textarea&#62;&#60;div&#62;&#60;p&#62;yyyyy&#60;/p&#62;&#60;/div&#62;&#60;/textarea&#62;
textarea的优点是可以支持任何格式的内容，而且这些内容不会在iframe子页面里解析（比如创建DOM树，执行JS），接下来前端要做的，只是在父页面里获取到子页面的DOM，把textarea的内容取出来（注意不能取innerHTML而要取value）。
这里存在一个判断iframe是否加载完成的问题，解决方法之一是在iframe标签上写onload事件，不过这样就需要显式的调用一个函数。
方法二如下：
(function(){
try{
&#160; &#160; callback(document.getElementById('crossdomain').contentWindow.document.body.getElementsByTagName(&#34;TEXTAREA&#34;)[0].value);
}catch(e){
&#160; &#160; setTimeout(arguments.callee,0);
&#160; &#160; return;
}&#160; &#160; 
})();
最后我们可以封装出这样一个方法：
window.TUI = window.$ = {};
/**
 * @public 通过iframe异步请求数据
 * @param {string}&#160; url是请求的地址
 * @param {function}&#160; cb是处理返回数据的回调函数
 */
TUI.getIframeData = function(url, [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.limboy.com/wp-content/uploads/2008/12/tudou_frame.jpg' title='tudou_frame.jpg'><img style="float:left;width:200px;margin:0 10px 10px 0;" src='http://www.limboy.com/wp-content/uploads/2008/12/tudou_frame.jpg' alt='tudou_frame.jpg' /></a>这篇文章将会探讨一下在网页里做异步的跨域请求，以及借助iframe来获取数据的方法。</p>
<p>呃，本来我觉得这个话题没什么好说的了，因为如今好像没有几个web应用能离开这类request，google和facebook用iframe来做comet的时候也基本上把能hack的都hack遍了，所以我估计开发者社区里应该早就形成所谓的&#8221;最佳实践&#8221;（best practices）了罢。不过最近看到有一些关注前端技术的blog（比如<a target="_blank" href="http://realazy.org/blog/2008/11/30/benifit-of-fecthing-page-via-iframe/">realazy</a>）在讨论相关的话题，发现还是有一些东西值得写下来。<span id="more-208"></span></p>
<p><br/></p>
<h3>一、借助script的异步跨域请求</h3>
<p>先说跨域的问题，首先要指出的是，iframe里的js宿主对象一样也躲不开同源策略（Same Origin Policy），仅仅能解决二级域名的跨域而已，比如www.tudou.com和so.tudou.com，如果要请求某个八杆子打不到一起去的域名下的数据（例如你想搞mashup），建议老老实实的用script标签去请求<a href="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/" target="_blank">JSONP</a>罢。关于JSONP要附带说一下的是，jQuery对JSONP请求的封装方式很值得提倡：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Gray;">$.</span><span style="color: Blue;">getJSON</span><span style="color: Olive;">(</span><span style="color: Blue;">url</span><span style="color: Gray;">, </span><span style="color: Blue;">params</span><span style="color: Gray;"> + </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">&amp;jsoncallback=?</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">json</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">/* do something */</span></li>
<li><span style="color: Olive;">})</span><span style="color: Gray;">;</span></li></ol></div>
<p>用jsoncallback作为服务器端支持的标准jsonp参数，而每次执行这个方法都会用时间戳生成一个唯一的全局函数名，替换这个“?”，这个细节被封装到黑盒里，使用者不必了解，可以像普通的ajax请求一样，用匿名的回调函数作为最末尾的参数（这是jquery强调的风格），这种语法糖（syntactic sugar）的作用绝对不仅仅是让前端开发人员可以偷懒而已，对代码的可读性，兼容性和今后的维护都有好处。（我经常要向服务器端的开发人员解释这个道理，否则他们才不给你支持什么jsoncallback参数呢，直接给你返回一个“yy({……})”就算完工……囧）</p>
<h3>二、利用前沿技术的跨域方法</h3>
<p>当然了，我们还可以走一些目前来看比较野的路子来实现跨域，比如在页面里嵌入一个不到1K的swf，借助flashplayer向部署了crossdomain.xml的服务器请求数据，再用actionscript里的ExternalInterface类把数据还给javascript（我觉得这种方法忒有调用dll的感觉～大心）。</p>
<p>我们还可以指望ie8里支持的<a target="_blank" href="http://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=ie8whitepapers&#038;ReleaseId=581">XDomainRequestAllowed</a>，和firefox3.1支持的<a target="_blank" href="http://dev.w3.org/2006/waf/access-control/">Access Control</a>，甚至传说中的<a target="_blank" href="http://www.reddit.com/r/programming/comments/7a3rc/html_5_websocket_is_neither_web_nor_socket/">HTML5 socket</a>……噢喔喔，多么甜美的梦……/掐一把脸蛋</p>
<h3>三、用iframe直接发送跨域请求</h3>
<p>跟script标签一样，iframe也可以用来替代ajax，而且在修改document.domain之后（比如上面提到的两个域名，可以设置document.domain = &#8220;tudou.com&#8221;），还可以解决部分跨域问题。</p>
<p>通过iframe请求数据的方法，最直接的莫过于在页面里动态的嵌入一个iframe标签，用它的src属性直接请求包含数据的网页，然后利用那个网页里的js把数据传给父页面，比如：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Olive;">&lt;</span><span style="color: Green;">iframe</span><span style="color: Gray;"> </span><span style="color: #00008b;">id</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">crossdomain</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: #00008b;">width</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">0</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: #00008b;">height</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">0</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: #00008b;">style</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">visibility:hidden;</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: #00008b;">src</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">http://yoursite.com/request_url/</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: Olive;">&gt;&lt;/</span><span style="color: Green;">iframe</span><span style="color: Olive;">&gt;</span></li></ol></div>
<p>这种方法耦合的太紧，非常不推荐。你请求的URI代表一个资源，应该是单纯的数据，它会作为xml，json，js代码还是html来处理，这个并不重要，不应该把你的程序逻辑跟数据混杂到一起，数据也不应该因为跨域或不跨域，用iframe，script还是ajax来请求就变成完全不同的东西。</p>
<p>有人会说：为了让数据能够被JS处理，返回的内容难免有差异。——但是小的差异可以通过合理的封装隐藏起来，比如JQuery的getJSON方法</p>
<p>有人会说：请求的URI是一个动态页面，同样可以在URI里支持类似jsoncallback的参数，生成一个script标签和其中的JS代码，把数据“包裹”在JS里，比如请求“http://yoursite.com/request_url/?callback=cb1304344”，返回：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Olive;">&lt;</span><span style="color: Green;">script</span><span style="color: Gray;"> </span><span style="color: #00008b;">type</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">text/javascript</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;</span></li>
<li><span style="color: Gray;">document.domain=&quot;tudou.com&quot;;</span></li>
<li><span style="color: Gray;">top.cb1304344({ /* 数据 */ });</span></li>
<li><span style="color: Olive;">&lt;/</span><span style="color: Green;">script</span><span style="color: Olive;">&gt;</span></li></ol></div>
<p>——首先，很多情况下你请求到的不会是动态页面，在这个到处都强调高负载的web世界里，你拿到的经常是<a target="_blank" href="http://blog.s135.com/book/squid/">squid</a>之类的代理程序返回的缓存。其次，如果你请求的是HTML格式的文本，为了能作为JS代码来执行，服务器端必须对这段文本做转义和清理工作，而且安全性还不一定能保证（因为HTML里经常包含很多来自UGC的内容），如果你请求的是JSON格式的数据……那何必用iframe咧……直接嵌script罢……</p>
<h3>四、用iframe直接请求数据的最佳实践</h3>
<p>我推荐在上述方法的基础上做改良，首先在服务器端，直接返回数据本身，并且把数据“包裹”在一个textarea标签里，比如：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Olive;">&lt;</span><span style="color: Green;">textarea</span><span style="color: Olive;">&gt;&lt;</span><span style="color: Green;">div</span><span style="color: Olive;">&gt;&lt;</span><span style="color: Green;">p</span><span style="color: Olive;">&gt;</span><span style="color: Gray;">yyyyy</span><span style="color: Olive;">&lt;/</span><span style="color: Green;">p</span><span style="color: Olive;">&gt;&lt;/</span><span style="color: Green;">div</span><span style="color: Olive;">&gt;&lt;/</span><span style="color: Green;">textarea</span><span style="color: Olive;">&gt;</span></li></ol></div>
<p>textarea的优点是可以支持任何格式的内容，而且这些内容不会在iframe子页面里解析（比如创建DOM树，执行JS），接下来前端要做的，只是在父页面里获取到子页面的DOM，把textarea的内容取出来（注意不能取innerHTML而要取value）。</p>
<p>这里存在一个判断iframe是否加载完成的问题，解决方法之一是在iframe标签上写onload事件，不过这样就需要显式的调用一个函数。</p>
<p>方法二如下：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Green;">try</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">callback</span><span style="color: Olive;">(</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">getElementById</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">crossdomain</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">contentWindow</span><span style="color: Gray;">.</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">body</span><span style="color: Gray;">.</span><span style="color: Blue;">getElementsByTagName</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">TEXTAREA</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;">.</span><span style="color: Blue;">value</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Green;">catch</span><span style="color: Olive;">(</span><span style="color: Blue;">e</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Blue;">arguments</span><span style="color: Gray;">.</span><span style="color: Blue;">callee</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">&nbsp; &nbsp; </span></li>
<li><span style="color: Olive;">})()</span><span style="color: Gray;">;</span></li></ol></div>
<p>最后我们可以封装出这样一个方法：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">TUI</span><span style="color: Gray;"> = </span><span style="color: Teal;">window</span><span style="color: Gray;">.$ = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">/**</span></li>
<li><span style="color: #ffa500;"> * @public 通过iframe异步请求数据</span></li>
<li><span style="color: #ffa500;"> * @param {string}&nbsp; url是请求的地址</span></li>
<li><span style="color: #ffa500;"> * @param {function}&nbsp; cb是处理返回数据的回调函数</span></li>
<li><span style="color: #ffa500;"> */</span></li>
<li><span style="color: Blue;">TUI</span><span style="color: Gray;">.</span><span style="color: Blue;">getIframeData</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">url</span><span style="color: Gray;">, </span><span style="color: Blue;">cb</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">f</span><span style="color: Gray;"> = </span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">getElementById</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">crossdomain</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">f</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">f</span><span style="color: Gray;">.</span><span style="color: Blue;">src</span><span style="color: Gray;"> = </span><span style="color: Blue;">url</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">else</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">t</span><span style="color: Gray;"> = </span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">createElement</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">DIV</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">t</span><span style="color: Gray;">.</span><span style="color: Blue;">innerHTML</span><span style="color: Gray;"> = </span><span style="color: #8b0000;">'</span><span style="color: Red;">&lt;iframe id=&quot;crossdomain&quot; width=&quot;0&quot; height=&quot;0&quot; style=&quot;visibility:hidden;&quot; src=&quot;</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> + </span><span style="color: Blue;">url</span><span style="color: Gray;"> + </span><span style="color: #8b0000;">'</span><span style="color: Red;">&quot; &gt;&lt;/iframe&gt;</span><span style="color: #8b0000;">'</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">body</span><span style="color: Gray;">.</span><span style="color: Blue;">appendChild</span><span style="color: Olive;">(</span><span style="color: Blue;">t</span><span style="color: Gray;">.</span><span style="color: Blue;">firstChild</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">try</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">cb</span><span style="color: Olive;">(</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">getElementById</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">crossdomain</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">contentWindow</span><span style="color: Gray;">.</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">body</span><span style="color: Gray;">.</span><span style="color: Blue;">getElementsByTagName</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">TEXTAREA</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;">.</span><span style="color: Blue;">value</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Green;">catch</span><span style="color: Olive;">(</span><span style="color: Blue;">e</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Blue;">arguments</span><span style="color: Gray;">.</span><span style="color: Blue;">callee</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">&nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">})()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #ffa500;">//像这样执行</span></li>
<li><span style="color: Gray;">$.</span><span style="color: Blue;">getIframeData</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">http://yoursite.com/request_url/</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">data</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">/* do something */</span></li>
<li><span style="color: Olive;">})</span><span style="color: Gray;">;</span></li></ol></div>
<p>只要再增加一个可选的param参数，这就是一个很标准的jQuery AJAX API，我们还可以在jQuery的$.get上面封装，增加一个是否跨域的判断，当这个request的URI修改成同样的域名后，自动切换到普通的AJAX方法来请求，把返回的文本用类似这样的正则/<(textarea)>(.+)<\/(textarea)>/删掉多余的字符，再传给回调函数，前端和服务器端都不用修改代码。</p>
<h3>五、用iframe直接请求数据的缺陷</h3>
<p>必须指出的是，iframe在ie里获取数据时会引发一些“小问题”，dojo的创始人Alex Russell把它们称作<a target="_blank" href="http://alex.dojotoolkit.org/2006/02/what-else-is-burried-down-in-the-depths-of-googles-amazing-javascript/">“灵异点击（phantom click）”和“噩梦般的指示器（throbber of doom）”</a>，前者是指在iframe请求内容的时候会出现一次点击链接的音效（让用户怀疑闹鬼，多差的体验口牙！），后者是指iframe加载过程中，ie的界面上会出现正在读取的提示（比如左下的进度条，右上的图标）……好罢，其实以我个人的标准，这两个问题都可以无视……</p>
<p>这种方法还有一个明显的缺陷，就是只支持GET类型的请求。</p>
<h3>六、用iframe结合ajax</h3>
<p>不过iframe还有一种使用方法，不但可以避免上面提到的问题，也不需要服务器端做任何调整，简单来说：在iframe的src里调用一个包含ajax方法的页面，然后父页面调用这个方法来发起跟子页面同域名下的ajax请求。在土豆网的播放页面上，我使用这种方法请求用户评论统一接口里的HTML内容，例如这个WH40K:DOWII的视频：</p>
<p><a  target="_blank" href="http://www.tudou.com/programs/view/iPcprDz_LhI/">http://www.tudou.com/programs/view/iPcprDz_LhI/</a></p>
<p>获得评论部分HTML的接口类似这样:</p>
<p><a  target="_blank" href=" http://comments.tudou.com/itemcomment.srv?method=get&#038;iid=21283123&#038;page=1&#038;tm=5&#038;ban=1">http://comments.tudou.com/itemcomment.srv?method=get&#038;iid=21283123&#038;page=1&#038;tm=5&#038;ban=1</a></p>
<p>这个接口在独立的一组服务器上实现，在视频播放页，豆单播放页，豆单封面，相册，个人主页都会被调用。由于包含大量用户提交的内容和复杂的HTML结构，如果用JSON形式，前端后端处理起来都效率低，此外，提交新评论，回复，删除，也会用到comments.tudou.com这个域名下的接口，而这些操作显然需要POST类型的请求。在这种需求下，借助iframe的AJAX方法</p>
<p>首先在comments.tudou.com域名下部署一个供iframe调用的跨域文件，感觉很像flashplayer的crossdomain.xml……</p>
<p><a  target="_blank" href="http://comments.tudou.com/crossdomain/index.html">http://comments.tudou.com/crossdomain/index.html</a></p>
<p>可以看到源文件里仅仅包含一个stand-alone的ajax方法……呃……你觉得很眼熟？不用怀疑，就是在jQuery源代码的基础上修改来的-___-b，支持最基本的需求。这个页面可以设置很长的过期头让浏览器缓存起来，因为不会再有变动。</p>
<p>在父页面里通过<a target="_blank" href="http://js.tudouui.com/js/comments_9.js">TUI.videoComment.request</a>提供统一的接口，不做详述了，只列举其中访问跨域方法的部分：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">try</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; $</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">#crossdomain</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;">.</span><span style="color: Blue;">contentWindow</span><span style="color: Gray;">.</span><span style="color: Blue;">TUI</span><span style="color: Gray;">.</span><span style="color: Blue;">ajax</span><span style="color: Olive;">(</span><span style="color: Blue;">o</span><span style="color: Olive;">)</span><span style="color: Gray;">;&nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Green;">catch</span><span style="color: Olive;">(</span><span style="color: Blue;">e</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Blue;">arguments</span><span style="color: Gray;">.</span><span style="color: Blue;">callee</span><span style="color: Gray;">,</span><span style="color: Maroon;">500</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">&nbsp; &nbsp; </span></li>
<li><span style="color: Olive;">})()</span><span style="color: Gray;">;</span></li></ol></div>
<h3>七、总结一下</h3>
<p>iframe适用于 ( 跨域的 &#038;&#038; ( 返回大量数据 || 返回HTML内容 || 需要发POST请求 ) ) 的场合，除此之外还有<a  target="_blank" href="http://www.ibm.com/developerworks/cn/web/wa-lo-comet/">comet里的串流技术（streaming）</a>——本文不涉及。使用时需要注意保持资源的纯粹性，并尽可能隐藏那些跟其他异步请求差异很大的或包含hack的细节（比如嵌入iframe，触发回调函数，处理数据），设计出一致的，兼容性和扩展性良好的，不碍眼的接口XD</p>
<p>关于跨域还要补充一点：修改document.domain可能会产生一些无法预料的问题，比如在firefox里，document.styleSheets的cssRules属性会被拒绝访问。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.limboy.com/2008/12/31/iframe-cross-site-request/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>JavaScript Memoization：让函数也有记忆功能</title>
		<link>http://www.limboy.com/2008/04/27/javascript_memoization/</link>
		<comments>http://www.limboy.com/2008/04/27/javascript_memoization/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 02:57:54 +0000</pubDate>
		<dc:creator>Dexter.Yy</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[代码]]></category>

		<guid isPermaLink="false">http://www.limboy.com/2008/04/27/javascript_memoization/</guid>
		<description><![CDATA[realazy在blog上给出了一个JavaScript Memoization的实现，Memoization就是函数返回值的缓存，比如一个函数参数与返回结果一一对应的hash列表，wiki上其实也有详细解释，我不细说了，只讨论一下具体实现的问题，realazy文中的代码有一些问题，比如直接用参数拼接成的字符串作为查询缓存结果的key，如果参数里包括对象或数组的话，就很难保证唯一的key，还有1楼评论里提到的：[221,3]和[22,13]这样的参数也无法区分。 
那么来改写一下，首先还是用hash表来存放缓存数据：

function Memoize(fn){
&#160; &#160; var&#160;cache = {};
&#160; &#160; return&#160;function(){
&#160; &#160; &#160; &#160; var&#160;key = [];
&#160; &#160; &#160; &#160; for(&#160;var i=0, l = arguments.length; i &#60; l; i++ )&#160;
&#160; &#160; &#160; &#160; &#160; &#160; key.push(arguments[i]);
&#160; &#160; &#160; &#160; if( !(key&#160;in cache) )
&#160; &#160; &#160; &#160; &#160; &#160; cache[key] = fn.apply(this, arguments);
&#160; &#160; &#160; &#160; return&#160;cache[key];
&#160; [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.limboy.com/wp-content/uploads/2008/04/ltp.jpg' title='ltp.jpg'><img src='http://www.limboy.com/wp-content/uploads/2008/04/ltp.jpg' alt='ltp.jpg' style="float:left;margin:0 10px 5px 0;width:200px;" /></a>realazy在blog上给出了一个<a target="_blank" href="http://realazy.org/blog/2008/04/22/javascript-memoization/">JavaScript Memoization的实现</a>，Memoization就是函数返回值的缓存，比如一个函数参数与返回结果一一对应的hash列表，wiki上其实也有<a target="_blank" href="http://en.wikipedia.org/wiki/Memoization">详细解释</a>，我不细说了，只讨论一下具体实现的问题，realazy文中的代码有一些问题，比如直接用参数拼接成的字符串作为查询缓存结果的key，如果参数里包括对象或数组的话，就很难保证唯一的key，还有1楼评论里提到的：[221,3]和[22,13]这样的参数也无法区分。 </p>
<p>那么来改写一下，首先还是用hash表来存放缓存数据：<span id="more-188"></span><br />
<br/><br/></p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Blue;">Memoize</span><span style="color: Olive;">(</span><span style="color: Blue;">fn</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">cache</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">key</span><span style="color: Gray;"> = </span><span style="color: Olive;">[]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">i</span><span style="color: Gray;">=</span><span style="color: Maroon;">0</span><span style="color: Gray;">, </span><span style="color: Blue;">l</span><span style="color: Gray;"> = </span><span style="color: Blue;">arguments</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;"> &lt; </span><span style="color: Blue;">l</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;">++ </span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">key</span><span style="color: Gray;">.</span><span style="color: Blue;">push</span><span style="color: Olive;">(</span><span style="color: Blue;">arguments</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">])</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;"> !</span><span style="color: Olive;">(</span><span style="color: Blue;">key</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">in</span><span style="color: Gray;"> </span><span style="color: Blue;">cache</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">cache</span><span style="color: Olive;">[</span><span style="color: Blue;">key</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Blue;">fn</span><span style="color: Gray;">.</span><span style="color: Blue;">apply</span><span style="color: Olive;">(</span><span style="color: Green;">this</span><span style="color: Gray;">, </span><span style="color: Blue;">arguments</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">cache</span><span style="color: Olive;">[</span><span style="color: Blue;">key</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>嗯，区别是直接把数组当作键来用，不过要注意函数里的arguments是js解释器实现的一个特殊对象，并不是真正的数组，所以要转换一下……</p>
<blockquote><p>
ps: 原来的参数包括方法名称和上下文引用：fib.fib_memo = Memoize(&#8216;fib_memo&#8217;, fib)，但实际上currying生成的函数里可以用this直接引用上层对象，更复杂的例子可以参考<a target="_blank" href="http://ejohn.org/blog/simple-class-instantiation/">John Resig的makeClass</a>，所以我改成直接传函数引用：fib.fib_memo = Memoize(fib.fib_memo)</p></blockquote>
<p>这样写看上去似乎很靠谱，由参数组成的数组不是唯一的么。但实际上，数组之所以能作为js对象的属性名称来使用，是因为它被当作字符串处理了，也就是说如果你给函数传的参数是这样：(1,2,3), cache对象就会是这个样子：{ &#8220;1,2,3&#8243;: somedata }，如果你的参数里有对象，比如：(1,2,{i:&#8221;yy&#8221;})，实际的键值会是：&#8221;1,2,[object Object]&#8220;，所以这跟把数组拼接成字符串的方法其实没有区别……</p>
<p>示例：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">a</span><span style="color: Gray;"> = </span><span style="color: Olive;">[</span><span style="color: Maroon;">1</span><span style="color: Gray;">,</span><span style="color: Maroon;">2</span><span style="color: Gray;">,</span><span style="color: Olive;">{</span><span style="color: Blue;">yy</span><span style="color: Gray;">:</span><span style="color: #8b0000;">'</span><span style="color: Red;">0</span><span style="color: #8b0000;">'</span><span style="color: Olive;">}]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">b</span><span style="color: Gray;"> = </span><span style="color: Olive;">[</span><span style="color: Maroon;">1</span><span style="color: Gray;">,</span><span style="color: Maroon;">2</span><span style="color: Gray;">,</span><span style="color: Olive;">{</span><span style="color: Blue;">xx</span><span style="color: Gray;">:</span><span style="color: #8b0000;">'</span><span style="color: Red;">1</span><span style="color: #8b0000;">'</span><span style="color: Olive;">}]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">obj</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">obj</span><span style="color: Olive;">[</span><span style="color: Blue;">a</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">111</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">obj</span><span style="color: Olive;">[</span><span style="color: Blue;">b</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">222</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">;</span></li>
<li><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">i</span><span style="color: Gray;"> </span><span style="color: Green;">in</span><span style="color: Gray;"> </span><span style="color: Blue;">obj</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">alert</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">i</span><span style="color: Gray;"> + </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;"> = </span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> + </span><span style="color: Blue;">obj</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;">;&nbsp; &nbsp; </span><span style="color: #ffa500;">//只会弹出&quot;1,2,[object Object] = 222&quot;，obj[a] = &quot;111&quot;被覆盖了</span></li></ol></div>
<p>直接用参数作为键名的方法不靠谱了…………换一种方法试试：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Blue;">Memoize</span><span style="color: Olive;">(</span><span style="color: Blue;">fn</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">cache</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">, </span><span style="color: Blue;">args</span><span style="color: Gray;"> = </span><span style="color: Olive;">[]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">i</span><span style="color: Gray;">=</span><span style="color: Maroon;">0</span><span style="color: Gray;">, </span><span style="color: Blue;">key</span><span style="color: Gray;"> = </span><span style="color: Blue;">args</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;"> &lt; </span><span style="color: Blue;">key</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;">++ </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">equal</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">args</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]</span><span style="color: Gray;">, </span><span style="color: Blue;">arguments</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp; </span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">cache</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">args</span><span style="color: Olive;">[</span><span style="color: Blue;">key</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Blue;">arguments</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">cache</span><span style="color: Olive;">[</span><span style="color: Blue;">key</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Blue;">fn</span><span style="color: Gray;">.</span><span style="color: Blue;">apply</span><span style="color: Olive;">(</span><span style="color: Green;">this</span><span style="color: Gray;">, </span><span style="color: Blue;">arguments</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">cache</span><span style="color: Olive;">[</span><span style="color: Blue;">key</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>可以完全避免上述问题，没有使用hash的键值对索引，而是把函数的参数和结果分别缓存在两个列表里，每次都先遍历整个参数列表作比较，找出对应的键名/ID号之后再从结果列表里取数据。以下是比较数组的equal方法：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Blue;">equal</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">first</span><span style="color: Gray;">, </span><span style="color: Blue;">second</span><span style="color: Gray;"> </span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;"> !</span><span style="color: Blue;">first</span><span style="color: Gray;"> || !</span><span style="color: Blue;">second</span><span style="color: Gray;"> || </span><span style="color: Blue;">first</span><span style="color: Gray;">.</span><span style="color: Blue;">constructor</span><span style="color: Gray;"> != </span><span style="color: Blue;">second</span><span style="color: Gray;">.</span><span style="color: Blue;">constructor</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">false</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">first</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;"> &amp;&amp; </span><span style="color: Green;">typeof</span><span style="color: Gray;"> </span><span style="color: Blue;">first</span><span style="color: Gray;"> != </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">string</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">&nbsp; </span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">i</span><span style="color: Gray;">=</span><span style="color: Maroon;">0</span><span style="color: Gray;">, </span><span style="color: Blue;">l</span><span style="color: Gray;"> = </span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">first</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;"> &gt; </span><span style="color: Blue;">second</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> ? </span><span style="color: Blue;">first</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;"> : </span><span style="color: Blue;">second</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">l</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;">++</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;"> !</span><span style="color: Blue;">equal</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">first</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]</span><span style="color: Gray;">, </span><span style="color: Blue;">second</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Green;">false</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">else</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Green;">typeof</span><span style="color: Gray;"> </span><span style="color: Blue;">first</span><span style="color: Gray;"> == </span><span style="color: #8b0000;">'</span><span style="color: Red;">object</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">n</span><span style="color: Gray;"> </span><span style="color: Green;">in</span><span style="color: Gray;"> </span><span style="color: Blue;">first</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;"> !</span><span style="color: Blue;">equal</span><span style="color: Olive;">(</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">first</span><span style="color: Olive;">[</span><span style="color: Blue;">n</span><span style="color: Olive;">]</span><span style="color: Gray;">, </span><span style="color: Blue;">second</span><span style="color: Olive;">[</span><span style="color: Blue;">n</span><span style="color: Olive;">]</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Green;">false</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">else</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">first</span><span style="color: Gray;"> === </span><span style="color: Blue;">second</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">true</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>千万不要直接用==来比较arguments和args里的数组，那样比较的是内存引用，而不是参数的内容。</p>
<p>这种方法的速度很慢，equal方法其实影响不大，但是缓存的结果数量多了以后，每次都要遍历参数列表却是很没效率的（求80以上的fibonacci数列，在firefox3和safari3上都要40ms左右）</p>
<p>如果在实际应用中参数变动不多或者不接受参数的话，可以参考Oliver Steel的这篇<a target="_blank" href="http://osteele.com/archives/2006/04/javascript-memoization">《One-Line JavaScript Memoization》</a>，用很短的函数式风格解决问题：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Blue;">Memoize</span><span style="color: Olive;">(</span><span style="color: Blue;">o</span><span style="color: Gray;">, </span><span style="color: Blue;">p</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">f</span><span style="color: Gray;"> = </span><span style="color: Blue;">o</span><span style="color: Olive;">[</span><span style="color: Blue;">p</span><span style="color: Olive;">]</span><span style="color: Gray;">, </span><span style="color: Blue;">mf</span><span style="color: Gray;">, </span><span style="color: Blue;">value</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">s</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">v</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Blue;">o</span><span style="color: Olive;">[</span><span style="color: Blue;">p</span><span style="color: Olive;">]</span><span style="color: Gray;">=</span><span style="color: Blue;">v</span><span style="color: Gray;">||</span><span style="color: Blue;">mf</span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">((</span><span style="color: Blue;">mf</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">(</span><span style="color: Blue;">s</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">(){</span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">value</span><span style="color: Olive;">}))</span><span style="color: Gray;">.</span><span style="color: Blue;">reset</span><span style="color: Gray;"> = </span><span style="color: Blue;">mf</span><span style="color: Gray;">.</span><span style="color: Blue;">reset</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">value</span><span style="color: Gray;"> = </span><span style="color: Blue;">f</span><span style="color: Gray;">.</span><span style="color: Blue;">apply</span><span style="color: Olive;">(</span><span style="color: Green;">this</span><span style="color: Gray;">,</span><span style="color: Blue;">arguments</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span><span style="color: #ffa500;">//此处修改过，允许接受参数</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">})</span><span style="color: Gray;">.</span><span style="color: Blue;">reset</span><span style="color: Gray;"> = </span><span style="color: Blue;">s</span><span style="color: Olive;">)()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>示例：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">fib</span><span style="color: Gray;"> = </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">temp</span><span style="color: Gray;">: </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">n</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">i</span><span style="color: Gray;">=</span><span style="color: Maroon;">0</span><span style="color: Gray;">;</span><span style="color: Blue;">i</span><span style="color: Gray;">&lt;</span><span style="color: Maroon;">10000</span><span style="color: Gray;">;</span><span style="color: Blue;">i</span><span style="color: Gray;">++</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">n</span><span style="color: Gray;">=</span><span style="color: Blue;">n</span><span style="color: Gray;">+</span><span style="color: Maroon;">2</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">n</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">Memoize</span><span style="color: Olive;">(</span><span style="color: Blue;">fib</span><span style="color: Gray;">,</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">temp</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span><span style="color: #ffa500;">//让fib.temp缓存返回值</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">fib</span><span style="color: Gray;">.</span><span style="color: Blue;">temp</span><span style="color: Olive;">(</span><span style="color: Maroon;">16</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span><span style="color: #ffa500;">//执行结果：20006，被缓存</span></li>
<li><span style="color: Blue;">fib</span><span style="color: Gray;">.</span><span style="color: Blue;">temp</span><span style="color: Olive;">(</span><span style="color: Maroon;">20</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span><span style="color: #ffa500;">//执行结果：20006</span></li>
<li><span style="color: Blue;">fib</span><span style="color: Gray;">.</span><span style="color: Blue;">temp</span><span style="color: Olive;">(</span><span style="color: Maroon;">10</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span><span style="color: #ffa500;">//执行结果：20006</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">fib</span><span style="color: Gray;">.</span><span style="color: Blue;">temp</span><span style="color: Gray;">.</span><span style="color: Blue;">reset</span><span style="color: Olive;">()</span><span style="color: Gray;">; </span><span style="color: #ffa500;">//重置缓存</span></li>
<li><span style="color: Blue;">fib</span><span style="color: Gray;">.</span><span style="color: Blue;">temp</span><span style="color: Olive;">(</span><span style="color: Maroon;">10</span><span style="color: Olive;">)</span><span style="color: Gray;">; </span><span style="color: #ffa500;">//执行结果：20010</span></li></ol></div>
]]></content:encoded>
			<wfw:commentRss>http://www.limboy.com/2008/04/27/javascript_memoization/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>DOM加载事件的终极解决方案</title>
		<link>http://www.limboy.com/2007/04/19/domready/</link>
		<comments>http://www.limboy.com/2007/04/19/domready/#comments</comments>
		<pubDate>Wed, 18 Apr 2007 17:08:37 +0000</pubDate>
		<dc:creator>Dexter.Yy</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.limboy.com/2007/04/19/domready/</guid>
		<description><![CDATA[今天被土豆网的lex鄙视了，因为我的BLOG在Safari里根本无法浏览——loading永远不会结束，很明显，这意味着webkit引擎不支持上次提到的判断DOM加载完成的方法。
既然开了新文章，就干脆重新回顾一下这个问题：如今的javascript编程非常依赖DOM（文档对象模型），对HTML和XML来说，DOM是一个应用程序接口 (API) ，对JS来说，DOM为文档创建了程序可以使用的对象和方法，DOM把前端程序和内容结合在一起，就好像ORM（对象-关系映射，比如PEAR库里的DB_DataObject）把后台程序和关系数据库结合在一起，形象点说它是一颗节点树，没有这棵树的支撑，很多JS方法就无法使用。
传统方式是通过window.onload事件来判断DOM是否加载完成，但实际上它的加载时间里还包括了img标签插入的图片、FLASH等大家伙，很多时候，来不及等这些东西都下载完成才执行JS（特别是当你要用JS给页面元素注册事件、调整外观，用AJAX加载重要内容）。所以必须有一种方法来单独判断DOM是否加载完成。
国外很早就有强者解决了这个问题，但我上次看的资料其实不完整（不求甚解的下场），最终的解决方案是在几个人的BLOG上讨论出来的……blogsphere（博客圈）果然是一种能激发创造性的社区结构……
首先是Dean Edwards指出了两件重要的工具：

Mozilla提供一个很棒的事件：DOMContentLoaded
微软支持defer属性，这并不是私有属性，而是包括在W3C的DOM 1标准里的，但是它似乎没有被XHTML支持，还有一个特点是，defer只能放在script标签里，而不能用JS来添加。

那么首先在Firefox上判断DOM加载完成就很简单了：
if (document.addEventListener)&#160;
{
&#160; &#160; document.addEventListener(&#34;DOMContentLoaded&#34;, init, false);
}
Opera9也支持上面的方法，但更低版本就不行了……
至于IE，最早提出的方法是把init函数放在一个单独的ie_onload.js里执行，在HTML调用脚本时加入条件注释和defer：
&#60;!--[if IE]&#62;&#60;script defer src=&#34;ie_onload.js&#34;&#62;&#60;/script&#62;&#60;![endif]--&#62;
或者：
&#60;!--[if IE]&#62;&#60;script defer src=&#34;javascript:'init()'&#34;&#62;&#60;/script&#62;&#60;![endif]--&#62;
这个方法的缺点是要在HTML里嵌入代码，缺乏灵活性，在Matthias Miller加入讨论后，产生了更方便的实现方法：
// for Internet Explorer
&#160; &#160; &#160; /*@cc_on @*/
&#160; &#160; &#160; /*@if (@_win32)
&#160; &#160; &#160; &#160; &#160; document.write(&#34;&#60;scr&#34;+&#34;ipt id=__ie_onload defer src=//0&#62;&#60;\/scr&#34;+&#34;ipt&#62;&#34;);
&#160; &#160; &#160; &#160; &#160; var script = document.getElementById(&#34;__ie_onload&#34;);
&#160; &#160; &#160; &#160; &#160; script.onreadystatechange = function() {
&#160; &#160; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.limboy.com/2007/04/19/domready/domreadyjpg/' rel='attachment wp-att-107' title='domready.jpg'><img src='http://www.limboy.com/wp-content/uploads/2007/04/domready.jpg' alt='domready.jpg' style="float:left;margin:0 10px 0 0px;" /></a>今天被土豆网的<a href="http://my.opera.com/lexrus/blog/">lex</a>鄙视了，因为我的BLOG在Safari里根本无法浏览——loading永远不会结束，很明显，这意味着webkit引擎不支持<a href="http://www.limboy.com/2007/04/04/theme/">上次提到的</a>判断DOM加载完成的方法。</p>
<p>既然开了新文章，就干脆重新回顾一下这个问题：如今的javascript编程非常依赖DOM（文档对象模型），对HTML和XML来说，DOM是一个应用程序接口 (API) ，对JS来说，DOM为文档创建了程序可以使用的对象和方法，DOM把前端程序和内容结合在一起，就好像ORM（对象-关系映射，比如<a href="http://www.pearchina.com/">PEAR库</a>里的DB_DataObject）把后台程序和关系数据库结合在一起，形象点说它是一颗节点树，没有这棵树的支撑，很多JS方法就无法使用。<span id="more-106"></span></p>
<p>传统方式是通过window.onload事件来判断DOM是否加载完成，但实际上它的加载时间里还包括了img标签插入的图片、FLASH等大家伙，很多时候，来不及等这些东西都下载完成才执行JS（特别是当你要用JS给页面元素注册事件、调整外观，用AJAX加载重要内容）。所以必须有一种方法来单独判断DOM是否加载完成。</p>
<p>国外很早就有强者解决了这个问题，但我上次看的资料其实不完整（不求甚解的下场），最终的解决方案是在几个人的BLOG上讨论出来的……blogsphere（博客圈）果然是一种能激发创造性的社区结构……</p>
<p>首先是<a href="http://dean.edwards.name/weblog/2005/09/busted/">Dean Edwards</a>指出了两件重要的工具：</p>
<ul>
<li>Mozilla提供一个很棒的事件：DOMContentLoaded</li>
<li>微软支持<a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/defer.asp">defer</a>属性，这并不是私有属性，而是包括在W3C的DOM 1标准里的，但是它似乎没有被XHTML支持，还有一个特点是，defer只能放在script标签里，而不能用JS来添加。</li>
</ul>
<p>那么首先在Firefox上判断DOM加载完成就很简单了：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">if</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">addEventListener</span><span style="color: Olive;">)</span><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">addEventListener</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">DOMContentLoaded</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Blue;">init</span><span style="color: Gray;">, </span><span style="color: Green;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>Opera9也支持上面的方法，但更低版本就不行了……</p>
<p>至于IE，最早提出的方法是把init函数放在一个单独的ie_onload.js里执行，在HTML调用脚本时加入条件注释和defer：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">&lt;!--[if IE]&gt;&lt;script defer src=&quot;ie_onload.js&quot;&gt;&lt;/script&gt;&lt;![endif]--&gt;</span></li></ol></div>
<p>或者：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">&lt;!--[if IE]&gt;&lt;script defer src=&quot;javascript:'init()'&quot;&gt;&lt;/script&gt;&lt;![endif]--&gt;</span></li></ol></div>
<p>这个方法的缺点是要在HTML里嵌入代码，缺乏灵活性，在<a href="http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited">Matthias Miller</a>加入讨论后，产生了更方便的实现方法：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">// for Internet Explorer</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">/*@cc_on @*/</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">/*@if (@_win32)</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; document.write(&quot;&lt;scr&quot;+&quot;ipt id=__ie_onload defer src=//0&gt;&lt;\/scr&quot;+&quot;ipt&gt;&quot;);</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var script = document.getElementById(&quot;__ie_onload&quot;);</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; script.onreadystatechange = function() {</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (this.readyState == &quot;complete&quot;) {</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init(); // call the onload handler</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; /*@end @*/</span></li></ol></div>
<p>这里的cc就是conditional compilation（条件编译），跟条件注释很像，具体介绍可以看<a href="http://bbs.blueidea.com/redirect.php?tid=2453449&#038;goto=lastpost&#038;highlight=">这里翻译的文章</a>。这里使用CC是因为内部的代码会引起非IE浏览器的错误（比如Safari会出错）</p>
<p>而“script&#8221;被拆成&#8221;scr&#8221;+&#8221;ipt&#8221;似乎是为了避免与诺顿（Norton Internet Security）发生冲突-_____-b</p>
<p>如果你以为这样就可以应付所有情况了，就会像我一样被Safari用户鄙视……</p>
<p>jQuery的创始人John Resig在邮件列表里给出了Safari的解决方法：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">// for Safari</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: #8b0000;">/</span><span style="color: Red;">WebKit</span><span style="color: #8b0000;">/i</span><span style="color: Gray;">.</span><span style="color: Blue;">test</span><span style="color: Olive;">(</span><span style="color: Teal;">navigator</span><span style="color: Gray;">.</span><span style="color: Blue;">userAgent</span><span style="color: Olive;">))</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span style="color: #ffa500;">// sniff</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_timer</span><span style="color: Gray;"> = </span><span style="color: Blue;">setInterval</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: #8b0000;">/</span><span style="color: Red;">loaded|complete</span><span style="color: #8b0000;">/</span><span style="color: Gray;">.</span><span style="color: Blue;">test</span><span style="color: Olive;">(</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">readyState</span><span style="color: Olive;">))</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">init</span><span style="color: Olive;">()</span><span style="color: Gray;">; </span><span style="color: #ffa500;">// call the onload handler</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">, </span><span style="color: Maroon;">10</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li></ol></div>
<p>最后有人封装了完整的代码：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: #ffa500;">/*</span></li>
<li><span style="color: #ffa500;"> * (c)2006 Dean Edwards/Matthias Miller/John Resig</span></li>
<li><span style="color: #ffa500;"> * Special thanks to Dan Webb's domready.js Prototype extension</span></li>
<li><span style="color: #ffa500;"> * and Simon Willison's addLoadEvent</span></li>
<li><span style="color: #ffa500;"> *</span></li>
<li><span style="color: #ffa500;"> * For more info, see:</span></li>
<li><span style="color: #ffa500;"> * </span><span style="color: Blue;">http://dean.edwards.name/weblog/2006/06/again/</span></li>
<li><span style="color: #ffa500;"> * </span><span style="color: Blue;">http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype</span></li>
<li><span style="color: #ffa500;"> * </span><span style="color: Blue;">http://simon.incutio.com/archive/2004/05/26/addLoadEvent</span></li>
<li><span style="color: #ffa500;"> * </span></li>
<li><span style="color: #ffa500;"> * Thrown together by Jesse Skinner (</span><span style="color: Blue;">http://www.thefutureoftheweb.com/</span><span style="color: #ffa500;">)</span></li>
<li><span style="color: #ffa500;"> *</span></li>
<li><span style="color: #ffa500;"> *</span></li>
<li><span style="color: #ffa500;"> * To use: call addDOMLoadEvent one or more times with functions, ie:</span></li>
<li><span style="color: #ffa500;"> *</span></li>
<li><span style="color: #ffa500;"> *&nbsp; &nbsp; function something() {</span></li>
<li><span style="color: #ffa500;"> *&nbsp; &nbsp; &nbsp;&nbsp; // do something</span></li>
<li><span style="color: #ffa500;"> *&nbsp; &nbsp; }</span></li>
<li><span style="color: #ffa500;"> *&nbsp; &nbsp; addDOMLoadEvent(something);</span></li>
<li><span style="color: #ffa500;"> *</span></li>
<li><span style="color: #ffa500;"> *&nbsp; &nbsp; addDOMLoadEvent(function() {</span></li>
<li><span style="color: #ffa500;"> *&nbsp; &nbsp; &nbsp; &nbsp; // do other stuff</span></li>
<li><span style="color: #ffa500;"> *&nbsp; &nbsp; });</span></li>
<li><span style="color: #ffa500;"> *</span></li>
<li><span style="color: #ffa500;"> */</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Green;">function</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">addDOMLoadEvent</span><span style="color: Olive;">(</span><span style="color: Blue;">func</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_events</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">init</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// quit if this function has already been called</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Blue;">arguments</span><span style="color: Gray;">.</span><span style="color: Blue;">callee</span><span style="color: Gray;">.</span><span style="color: Blue;">done</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">return</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// flag this function so we don't do the same thing twice</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">arguments</span><span style="color: Gray;">.</span><span style="color: Blue;">callee</span><span style="color: Gray;">.</span><span style="color: Blue;">done</span><span style="color: Gray;"> = </span><span style="color: Green;">true</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// kill the timer</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_timer</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">clearInterval</span><span style="color: Olive;">(</span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_timer</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_timer</span><span style="color: Gray;"> = </span><span style="color: Green;">null</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// execute each function in the stack in the order they were added</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">for</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">i</span><span style="color: Gray;">=</span><span style="color: Maroon;">0</span><span style="color: Gray;">;</span><span style="color: Blue;">i</span><span style="color: Gray;"> &lt; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_events</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">;</span><span style="color: Blue;">i</span><span style="color: Gray;">++</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_events</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_events</span><span style="color: Gray;"> = </span><span style="color: Green;">null</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// for Mozilla/Opera9</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">addEventListener</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">addEventListener</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">DOMContentLoaded</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Blue;">init</span><span style="color: Gray;">, </span><span style="color: Green;">false</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// for Internet Explorer</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">/*@cc_on @*/</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">/*@if (@_win32)</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; document.write(&quot;&lt;scr&quot;+&quot;ipt id=__ie_onload defer src=//0&gt;&lt;\/scr&quot;+&quot;ipt&gt;&quot;);</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var script = document.getElementById(&quot;__ie_onload&quot;);</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; script.onreadystatechange = function() {</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (this.readyState == &quot;complete&quot;) {</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init(); // call the onload handler</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };</span></li>
<li><span style="color: #ffa500;">&nbsp; &nbsp; &nbsp; /*@end @*/</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// for Safari</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: #8b0000;">/</span><span style="color: Red;">WebKit</span><span style="color: #8b0000;">/i</span><span style="color: Gray;">.</span><span style="color: Blue;">test</span><span style="color: Olive;">(</span><span style="color: Teal;">navigator</span><span style="color: Gray;">.</span><span style="color: Blue;">userAgent</span><span style="color: Olive;">))</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"> </span><span style="color: #ffa500;">// sniff</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_timer</span><span style="color: Gray;"> = </span><span style="color: Blue;">setInterval</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: #8b0000;">/</span><span style="color: Red;">loaded|complete</span><span style="color: #8b0000;">/</span><span style="color: Gray;">.</span><span style="color: Blue;">test</span><span style="color: Olive;">(</span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">readyState</span><span style="color: Olive;">))</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">init</span><span style="color: Olive;">()</span><span style="color: Gray;">; </span><span style="color: #ffa500;">// call the onload handler</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">, </span><span style="color: Maroon;">10</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// for other browsers</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">onload</span><span style="color: Gray;"> = </span><span style="color: Blue;">init</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">// create event function stack</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_events</span><span style="color: Gray;"> = </span><span style="color: Olive;">[]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: #ffa500;">// add function to event stack</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">__load_events</span><span style="color: Gray;">.</span><span style="color: Blue;">push</span><span style="color: Olive;">(</span><span style="color: Blue;">func</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>而且他还结合了<a href="http://simonwillison.net/2004/May/26/addLoadEvent/">addLoadEvent函数</a>，我在上篇文章里有一种往onload里注册新事件的简单方法，是利用JS的特性：“函数是一等公民”，而这里是利用数组来登记所有事件，与<em>Ajax in Action</em>里提到的Observer模式差不多。有了这段代码，只要使用addDOMLoadEvent(函数名)，就可以反复添加事件函数，而不用担心覆盖原来注册的函数。</p>
<p>另外，喜欢用prototype的话，也可以用这个<a href="http://clientside.cnet.com/code-snippets/event-scripting/a-dom-ready-extension-for-prototype/">扩展</a>。</p>
<p>Matthias Miller还提到了<a href="http://www.outofhanwell.com/blog/index.php?title=using_window_onload_over_https&#038;more=1&#038;c=1&#038;tb=1&#038;pb=1">HTTS加密连接的情况</a>。</p>
<p>国外BLOG上的好东西很多，我觉得想解决技术问题，与其买大部头或畅销书啃，不如用好搜索引擎，多在BLOG之间跳转几下，多看看评论，可以学到更多东西。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.limboy.com/2007/04/19/domready/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>奇幻大辞典online版完工！</title>
		<link>http://www.limboy.com/2007/04/14/fdict/</link>
		<comments>http://www.limboy.com/2007/04/14/fdict/#comments</comments>
		<pubDate>Fri, 13 Apr 2007 16:20:05 +0000</pubDate>
		<dc:creator>Dexter.Yy</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[D&D]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.limboy.com/2007/04/14/%e5%a5%87%e5%b9%bb%e5%a4%a7%e8%be%9e%e5%85%b8online%e7%89%88%e5%8f%91%e5%b8%83%ef%bc%81/</guid>
		<description><![CDATA[A Long Time Ago in a Galaxy Far, Far Away&#8230; Linkcd老爷用FoxPro做了一个辞典软件，虽然没有金山糍粑那样的取词功能，但“奇幻大辞典”拥有专业的奇幻游戏术语词库，成为了广大玩家和苦力翻译们必备的神器，如今回想起来，辞典的最后一次更新居然已经是四年前的事……
时代已经不同了！如今linkcd老爷在惠普搞.net，FoxPro、Delphi这类玩意都早已成为过时的技术，基于Web的应用取代桌面软件成为一种越来越明显的潮流，单机PC游戏陷入低谷，&#8221;online&#8221;的后缀出现在所有经典名词的后面比如魔戒DND科南战锤大航海……其实我想说的就是，奇幻大辞典也与时俱进发布全新的在线版了！
其实这个东西从去年起就挂在NT的服务器里了，最初只有JAY写的一个PHP查询页面，我用AJAX技术重新做了一个华丽（这是重点！）的前端，把PHP页面改写成了“Code Behind”，参考google suggest加入了一些交互功能。因为当时还存在一些BUG和运行效率的问题，不好意思公开。这两天我对代码做了一次重构（说难听一点是“重写”），解决了所有BUG，还加入了键盘操作和缓存机制，感觉已经比较完善了……
永久域名：http://www.limboy.com/project/dict/

在线版的优点也很明显：不需要事先安装，不需要同步数据库。由于时间有限，目前暂时还没有添加新词汇、修改词汇信息和分类查询的功能，以后会根据需要添加。
]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.limboy.com/wp-content/uploads/2007/04/fd1.jpg' title='fd1.jpg'><img src='http://www.limboy.com/wp-content/uploads/2007/04/fd1.jpg' alt='fd1.jpg' style="float:left;margin:0 10px 0 0px;" /></a>A Long Time Ago in a Galaxy Far, Far Away&#8230; <a href="http://www.cnblogs.com/linkcd/">Linkcd老爷</a>用FoxPro做了一个辞典软件，虽然没有金山糍粑那样的取词功能，但“奇幻大辞典”拥有专业的奇幻游戏术语词库，成为了广大玩家和苦力翻译们必备的神器，如今回想起来，辞典的最后一次更新居然已经是四年前的事……</p>
<p>时代已经不同了！如今linkcd老爷在惠普搞.net，FoxPro、Delphi这类玩意都早已成为过时的技术，基于Web的应用取代桌面软件成为一种越来越明显的潮流，单机PC游戏陷入低谷，&#8221;online&#8221;的后缀出现在所有经典名词的后面比如魔戒DND科南战锤大航海……其实我想说的就是，奇幻大辞典也与时俱进发布全新的<a href="http://www.limboy.com/project/dict/">在线版</a>了！<span id="more-102"></span></p>
<p>其实这个东西从去年起就挂在NT的服务器里了，最初只有JAY写的一个PHP查询页面，我用AJAX技术重新做了一个华丽（这是重点！）的前端，把PHP页面改写成了“Code Behind”，参考<a href="http://www.google.com/webhp?complete=1&amp;hl=en">google suggest</a>加入了一些交互功能。因为当时还存在一些BUG和运行效率的问题，不好意思公开。这两天我对代码做了一次重构（说难听一点是“重写”），解决了所有BUG，还加入了键盘操作和缓存机制，感觉已经比较完善了……</p>
<p>永久域名：<a href="http://www.limboy.com/project/dict/">http://www.limboy.com/project/dict/</a></p>
<p><a href='http://www.limboy.com/wp-content/uploads/2007/04/sshot.jpg' title='fdshot'><img src='http://www.limboy.com/wp-content/uploads/2007/04/sshot.thumbnail.jpg' alt='fdshot' /></a></p>
<p>在线版的优点也很明显：不需要事先安装，不需要同步数据库。由于时间有限，目前暂时还没有添加新词汇、修改词汇信息和分类查询的功能，以后会根据需要添加。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.limboy.com/2007/04/14/fdict/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>新作品：可以自由编辑的Google地图，700行javascript+70行php</title>
		<link>http://www.limboy.com/2007/03/13/mapfolio/</link>
		<comments>http://www.limboy.com/2007/03/13/mapfolio/#comments</comments>
		<pubDate>Tue, 13 Mar 2007 10:20:23 +0000</pubDate>
		<dc:creator>Dexter.Yy</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[web服务/应用]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/?p=15</guid>
		<description><![CDATA[以前在龙骑士城堡提过一种想法，就是用GOOGLE MAPS来做桌面游戏玩家的主题地图。当时推荐的是EEMAP的服务，然则这个网站的注册一直需要邀请码，很不方便，而且界面难看，速度也很慢……
当时就想过自己来做一个GOOGLE MAPS API的应用，但一直没时间看API文档。这几天总算有空闲（辞职就是好哑），把想象中的东西基本上做出来了，我把它叫作Free Map Folio v1.0（取自DND设定集的名字），可以像维基百科那样自由编辑，前端是静态的HTML，数据库用xml，方便部署，而交互操作的程序完全用Javascirpt来写，只需要打开一个HTML页面，然后整个使用过程都不需要刷新页面，也不需要从外部获取数据（只用AJAX提交数据）。
实际应用：桌面游戏玩家主题地图（乱加东西要记得删掉）——http://www.ntrpg.org/yy/maps/
演示地址(上面的镜像)：http://www.limboy.com/project/maps/



Javascirpt的主要代码有700行，都写在一个对象里(yymap)，我本来想把每个单独的功能都封装起来，避免重复代码（DRY原则？），不过后来页面右侧栏加入了“地点列表”之后，程序就改复杂了……………以后有空要做一下重构……
用户只需要访问一个静态的HTML页面，唯一一次从外部获取数据是在地图加载的时候，用了API提供的XmlHttpRequest对象，非常方便，比如GXml.parse可以把responseText获得的文本转换成XML DOM。不过用GXmlHttp和GDownloadUrl的时候，IE7都会遇到一个缓存问题（IE6没试过）：刷新页面后，不会重新下载XML文件，因此页面上的数据不会更新。解决方法是在xml文件的地址后面加随机参数（感谢tinyfool的帮助）：
var ramnum = parseInt(100000*Math.random());var request = GXmlHttp.create();
&#160;
request.open(&#34;GET&#34;, &#34;db.xml?x=&#34;+ramnum, true);
标记（Marker）的样式可以自定义，所以我做了一个选择图标的功能，先建立所有图标的基本属性（yymap.baseIcon），包括阴影图片和各种尺寸，然后在创建新标记时，根据用户选择的图标，把地址传给icon.image就行了。其实还可以做一个自定义图片的功能，允许用户在编辑器里上传自己的图片（比如照片）当作图标，只是必须把图片处理成固定大小的32位PNG……
点击标记弹出的信息窗口是最麻烦的东西，因为页面里同时只能存在一个信息窗口，而信息窗口里的内容也不能保存在标记的对象里，所以要修改某个标记对应的信息窗内容，就只能修改它的点击事件：
GEvent.addListener(marker, &#34;click&#34;, function(){
&#160;
yymap.whenClickMarker(marker,info,point,icon.image);
&#160;
});
我在点击事件里传了4个参数：点击的标记对象 , 信息窗的内容, 标记的经纬度, 标记使用的图标， 除了用来显示信息窗，也是为了把它们传给全局变量（因为编辑这个标记的时候会用到）。
为了让右侧栏列表与地图上的图标一一对应，我在列表的每个链接上设了跟标记对应的ID，每次做添加、编辑或删除的操作时，除了修改标记本身的点击事件，还要用ID找到列表上对应的链接，修改链接的点击事件…………总之，感觉这个侧栏列表很添乱……却又是必要的功能……
在我写这篇文章时，还有一个搜索地名的功能没做好。本来API提供了地理译码的功能，可以把符合格式的地名转换成JSON数据（用JS对象来传递数据的格式），但这么方便的东西我却享受不了——地理译码还没有支持中国的地名…………在地图上就能很明显的看到：周围日本、印度，都有详细的城市名字，放大后还有交通信息，而中国是一片空白…………
因此对于不熟悉地理的用户来说，要在这样的中国地图上找到某个城市可能太难了，搜索地名是必须的功能。由于没有地理译码，目前使用GOOGLE MAPS API的网站，比如EEMAP，都是自己建立地名和经纬度对应的数据库。我找到了一个很全的“乡镇级中国行政区划地标”，是GOOGLE EARTH用的KMZ文件，但其实就是压缩过的XML，用WINRAR打开就能看到一个KML文件，可以直接拿来当搜索数据库。我考虑过两种实现方法：把用户输入的中文地名用AJAX发给PHP，让PHP搜索这个XML文件里匹配的标签，然后返回相应的经纬度；或者直接用GXmlHttp下载XML，然后用JS的DOM方法来搜索相应的标签，第二种方法很合我的胃口，不需要借道PHP，遗憾的是…………这意味着搜索时要用AJAX获得19M的XML数据……
更新：地名搜索已经完成了，模糊搜索范围包括省会、地级市、县城、村镇……足行匹配，搜索对象在KML文件里排名越靠后，搜索时间越长，不过最多应该不超过5秒……
我刚才测试了一下，搜索不到结果时4.36s，搜索最后一个地名“番阳”需要4.02s，搜索北京1.16s，搜索克拉玛依只需要华丽的328ms
php是由以前的同事Skylin帮忙写的，由于PHP只负责根据AJAX提交的数据，修改XML文件，所以内容很少……然则Skylin不肯用PHP5自带的XML类，而是自己写正则……最后代码只有几十行……果然是高手风范……
比如，这是remove.php:
&#60;?php
&#160;
include&#160;&#34;./globals.php&#34;;
&#160;
$file_content = join('',file(&#34;../db.xml&#34;));if(preg_match(&#34;/&#60;marker&#62;rn&#60;id&#62;&#34;.intval($_POST['id']).&#34;&#60;/id&#62;.*&#60;/marker&#62;rnrn/isU&#34;,$file_content,$array))
&#160;
{
&#160;
$file_content = str_replace($array[0],'',$file_content);
&#160;
}
&#160;
$fp = fopen(&#34;../db.xml&#34;,&#34;w+&#34;);
&#160;
flock($fp,LOCK_EX);
&#160;
fputs($fp,$file_content);
&#160;
flock($fp,LOCK_UN);
&#160;
fclose($fp);
&#160;
?&#62;
不过正则也容易出现问题，例如：在我最初做的XML数据库里面，标签的前面都有缩进，大概因为有的缩进是TAB，有的是空格，导致正则一直出错，只好把XML里的缩进全部删掉了……
目前已经全部完工，可能还有一些小BUG需要修改，比如：在简介里输入全角字符（比如·和——），会导致后面的字符都无法保存。P.S. 单引号、双引号和&#8221;&#38;&#8221;容易引起JS错误，我把它们都屏蔽了-_____-b
]]></description>
			<content:encoded><![CDATA[<p><a href="http://picasaweb.google.com/dexter.yy/BLOG/photo#5048726806888874194"><img src="http://lh3.google.com/image/dexter.yy/RhCuSBSagNI/AAAAAAAAAEw/L9rGLEK-8Ws/s288/map.jpg" style="float:left;margin:0px 10px 5px 0px;width:180px;" /></a>以前在龙骑士城堡<a href="http://www.cndkc.net/bbs/read-htm-tid-26098-keyword-.html" target="_blank">提过一种想法</a>，就是用GOOGLE MAPS来做桌面游戏玩家的主题地图。当时推荐的是<a href="http://www.eemap.org/map/247" target="_blank">EEMAP</a>的服务，然则这个网站的注册一直需要邀请码，很不方便，而且界面难看，速度也很慢……</p>
<p>当时就想过自己来做一个GOOGLE MAPS API的应用，但一直没时间看<a href="http://www.zmap.org/doc/maps/documentation/">API文档</a>。这几天总算有空闲（辞职就是好哑），把想象中的东西基本上做出来了，我把它叫作Free Map Folio v1.0（取自<a href="http://www.wizards.com/default.asp?x=products/dndacc/886480000">DND设定集</a>的名字），可以像维基百科那样自由编辑，前端是静态的HTML，数据库用xml，方便部署，而交互操作的程序完全用Javascirpt来写<span id="more-15"></span>，只需要打开一个HTML页面，然后整个使用过程都不需要刷新页面，也不需要从外部获取数据（只用AJAX提交数据）。</p>
<p>实际应用：桌面游戏玩家主题地图（乱加东西要记得删掉）——<a href="http://www.ntrpg.org/yy/maps/">http://www.ntrpg.org/yy/maps/</a><br />
演示地址(上面的镜像)：<a href="http://www.limboy.com/project/maps/">http://www.limboy.com/project/maps/</a></p>
<p><br/><br />
<a href="http://www.yupoo.com/photos/view?id=ff808081114495c301114a33155e49ce" tip="来YUPOO看我的照片"><img src="http://photo1.yupoo.com/20070313/152852_206019246.jpg" alt="新作品-HTML+PHP+XML轻量级维基地图-2" border="0" height="262" width="420" /></a></p>
<p><a href="http://www.yupoo.com/photos/view?id=ff808081114495c301114a330a1549cc" tip="来YUPOO看我的照片"><img src="http://photo1.yupoo.com/20070313/152849_1838550568.jpg" alt="新作品-HTML+PHP+XML轻量级维基地图-1" border="0" height="262" width="420" /></a></p>
<p>Javascirpt的<a href="http://www.ntrpg.org/yy/maps/js/main.js">主要代码</a>有700行，都写在一个对象里(yymap)，我本来想把每个单独的功能都封装起来，避免重复代码（DRY原则？），不过后来页面右侧栏加入了“地点列表”之后，程序就改复杂了……………以后有空要做一下重构……</p>
<p>用户只需要访问一个静态的HTML页面，唯一一次从外部获取数据是在地图加载的时候，用了API提供的<a href="http://www.zmap.org/doc/maps/documentation/#XML_and_RPC_overview">XmlHttpRequest对象</a>，非常方便，比如<a href="http://www.zmap.org/doc/maps/documentation/reference.html#GXml" target="_blank">GXml.parse</a>可以把responseText获得的文本转换成XML DOM。不过用GXmlHttp和GDownloadUrl的时候，IE7都会遇到一个缓存问题（IE6没试过）：刷新页面后，不会重新下载XML文件，因此页面上的数据不会更新。解决方法是在xml文件的地址后面加随机参数（感谢<a href="http://blog.donews.com/tinyfool/">tinyfool</a>的帮助）：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">ramnum</span><span style="color: Gray;"> = </span><span style="color: Blue;">parseInt</span><span style="color: Olive;">(</span><span style="color: Maroon;">100000</span><span style="color: Gray;">*</span><span style="color: Teal;">Math</span><span style="color: Gray;">.</span><span style="color: Blue;">random</span><span style="color: Olive;">())</span><span style="color: Gray;">;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">request</span><span style="color: Gray;"> = </span><span style="color: Blue;">GXmlHttp</span><span style="color: Gray;">.</span><span style="color: Blue;">create</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">request</span><span style="color: Gray;">.</span><span style="color: Blue;">open</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">GET</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">db.xml?x=</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">+</span><span style="color: Blue;">ramnum</span><span style="color: Gray;">, </span><span style="color: Green;">true</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li></ol></div>
<p>标记（Marker）的样式可以自定义，所以我做了一个选择图标的功能，先建立所有图标的基本属性（yymap.baseIcon），包括阴影图片和各种尺寸，然后在创建新标记时，根据用户选择的图标，把地址传给icon.image就行了。其实还可以做一个自定义图片的功能，允许用户在编辑器里上传自己的图片（比如照片）当作图标，只是必须把图片处理成固定大小的32位PNG……</p>
<p>点击标记弹出的信息窗口是最麻烦的东西，因为页面里同时只能存在一个信息窗口，而信息窗口里的内容也不能保存在标记的对象里，所以要修改某个标记对应的信息窗内容，就只能修改它的点击事件：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">GEvent</span><span style="color: Gray;">.</span><span style="color: Blue;">addListener</span><span style="color: Olive;">(</span><span style="color: Blue;">marker</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">click</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">, </span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">yymap</span><span style="color: Gray;">.</span><span style="color: Blue;">whenClickMarker</span><span style="color: Olive;">(</span><span style="color: Blue;">marker</span><span style="color: Gray;">,</span><span style="color: Blue;">info</span><span style="color: Gray;">,</span><span style="color: Blue;">point</span><span style="color: Gray;">,</span><span style="color: Blue;">icon</span><span style="color: Gray;">.</span><span style="color: Blue;">image</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Olive;">})</span><span style="color: Gray;">;</span></li></ol></div>
<p>我在点击事件里传了4个参数：点击的标记对象 , 信息窗的内容, 标记的经纬度, 标记使用的图标， 除了用来显示信息窗，也是为了把它们传给全局变量（因为编辑这个标记的时候会用到）。</p>
<p>为了让右侧栏列表与地图上的图标一一对应，我在列表的每个链接上设了跟标记对应的ID，每次做添加、编辑或删除的操作时，除了修改标记本身的点击事件，还要用ID找到列表上对应的链接，修改链接的点击事件…………总之，感觉这个侧栏列表很添乱……却又是必要的功能……</p>
<p>在我写这篇文章时，还有一个搜索地名的功能没做好。本来API提供了<a href="http://www.zmap.org/doc/maps/documentation/#Geocoding_JavaScript">地理译码</a>的功能，可以把符合格式的地名转换成JSON数据（用JS对象来传递数据的格式），但这么方便的东西我却享受不了——地理译码还没有支持中国的地名…………在地图上就能很明显的看到：周围日本、印度，都有详细的城市名字，放大后还有交通信息，而中国是一片空白…………</p>
<p>因此对于不熟悉地理的用户来说，要在这样的中国地图上找到某个城市可能太难了，搜索地名是必须的功能。由于没有地理译码，目前使用GOOGLE MAPS API的网站，比如EEMAP，都是自己建立地名和经纬度对应的数据库。我找到了一个很全的“<a href="http://bbs.godeyes.cn/Announce/Announce.asp?BoardID=100&amp;ID=77707">乡镇级中国行政区划地标</a>”，是GOOGLE EARTH用的KMZ文件，但其实就是压缩过的XML，用WINRAR打开就能看到一个KML文件，可以直接拿来当搜索数据库。我考虑过两种实现方法：把用户输入的中文地名用AJAX发给PHP，让PHP搜索这个XML文件里匹配的标签，然后返回相应的经纬度；或者直接用GXmlHttp下载XML，然后用JS的DOM方法来搜索相应的标签，第二种方法很合我的胃口，不需要借道PHP，遗憾的是…………这意味着搜索时要用AJAX获得19M的XML数据……</p>
<blockquote><p>更新：地名搜索已经完成了，模糊搜索范围包括省会、地级市、县城、村镇……足行匹配，搜索对象在KML文件里排名越靠后，搜索时间越长，不过最多应该不超过5秒……</p>
<p>我刚才测试了一下，搜索不到结果时4.36s，搜索最后一个地名“番阳”需要4.02s，搜索北京1.16s，搜索克拉玛依只需要华丽的328ms</p></blockquote>
<p>php是由以前的同事Skylin帮忙写的，由于PHP只负责根据AJAX提交的数据，修改XML文件，所以内容很少……然则Skylin不肯用PHP5自带的XML类，而是自己写正则……最后代码只有几十行……果然是高手风范……</p>
<p>比如，这是remove.php:</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">&lt;?php</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Green;">include</span><span style="color: Gray;">&nbsp;</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">./globals.php</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #00008b;">$file_content</span><span style="color: Gray;"> = </span><span style="color: Blue;">join</span><span style="color: Olive;">(</span><span style="color: #8b0000;">''</span><span style="color: Gray;">,</span><span style="color: Blue;">file</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">../db.xml</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">))</span><span style="color: Gray;">;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">preg_match</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">/&lt;marker&gt;rn&lt;id&gt;</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">.</span><span style="color: Blue;">intval</span><span style="color: Olive;">(</span><span style="color: #00008b;">$_POST</span><span style="color: Olive;">[</span><span style="color: #8b0000;">'</span><span style="color: Red;">id</span><span style="color: #8b0000;">'</span><span style="color: Olive;">])</span><span style="color: Gray;">.</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">&lt;/id&gt;.*&lt;/marker&gt;rnrn/isU</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">,</span><span style="color: #00008b;">$file_content</span><span style="color: Gray;">,</span><span style="color: #00008b;">$array</span><span style="color: Olive;">))</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #00008b;">$file_content</span><span style="color: Gray;"> = </span><span style="color: Blue;">str_replace</span><span style="color: Olive;">(</span><span style="color: #00008b;">$array</span><span style="color: Olive;">[</span><span style="color: Maroon;">0</span><span style="color: Olive;">]</span><span style="color: Gray;">,</span><span style="color: #8b0000;">''</span><span style="color: Gray;">,</span><span style="color: #00008b;">$file_content</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: #00008b;">$fp</span><span style="color: Gray;"> = </span><span style="color: Blue;">fopen</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">../db.xml</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">,</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">w+</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">flock</span><span style="color: Olive;">(</span><span style="color: #00008b;">$fp</span><span style="color: Gray;">,</span><span style="color: Blue;">LOCK_EX</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">fputs</span><span style="color: Olive;">(</span><span style="color: #00008b;">$fp</span><span style="color: Gray;">,</span><span style="color: #00008b;">$file_content</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">flock</span><span style="color: Olive;">(</span><span style="color: #00008b;">$fp</span><span style="color: Gray;">,</span><span style="color: Blue;">LOCK_UN</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">fclose</span><span style="color: Olive;">(</span><span style="color: #00008b;">$fp</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;</span></li>
<li><span style="color: Blue;">?&gt;</span></li></ol></div>
<p>不过正则也容易出现问题，例如：在我最初做的XML数据库里面，标签的前面都有缩进，大概因为有的缩进是TAB，有的是空格，导致正则一直出错，只好把XML里的缩进全部删掉了……</p>
<p>目前已经全部完工，可能还有一些小BUG需要修改，比如：在简介里输入全角字符（比如·和——），会导致后面的字符都无法保存。P.S. 单引号、双引号和&#8221;&amp;&#8221;容易引起JS错误，我把它们都屏蔽了-_____-b</p>
]]></content:encoded>
			<wfw:commentRss>http://www.limboy.com/2007/03/13/mapfolio/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>依然是回顾: 围绕技术名词的争论</title>
		<link>http://www.limboy.com/2006/12/08/expression/</link>
		<comments>http://www.limboy.com/2006/12/08/expression/#comments</comments>
		<pubDate>Thu, 07 Dec 2006 19:27:43 +0000</pubDate>
		<dc:creator>Dexter.Yy</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[代码]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/index.php/2006/12/08/expression/</guid>
		<description><![CDATA[上个月微软开始把传说中的Expression拿出来show了,这东西对微软来说是具有战略意义的，比IE7要重要的多。要理解它的意义，首先要了解微软。
大家都知道Google的核心价值观之一就是“一切以用户为中心”（进而发展出现在最流行的“用户体验至上”），而微软最重视并不是最终用户的感受，虽然你今年看到它马不停蹄的推出IE7、推出OFFICE2007、推出VISTA……仿佛为了满足广大普通用户而忙的不亦乐乎，其实那都是被行业趋势和竞争对手逼出来的。微软最重视的是开发者。这几年微软在互联网上落后、在主要的软件产品上停步不前，是什么让它依然能站在业界顶端？
.net
Visual Studio
MSDN
以上就是微软赖以维生的三件“神器”，只要用它们俘获大量的开发者，占据技术市场，就能继续维持垄断地位，普通用户只有接受的份——想想那些采用IE私有技术编写的网页和基于ActiveX开发的网上银行，想想那些基于win平台的商业游戏，就算你对产品本身有怨言，你敢不用IE么？敢不用windows么？用户体验什么的根本不重要，重要的是让全世界的开发者在做软件、web或网络服务时都依赖微软的技术、微软的工具、微软的知识、微软的底层平台和服务器……
这才是真正的垄断之道。
而Expression简单来说就是: FrontPage的接班人、微软的新三剑客，用来对付Adobe的三剑客：Flash/Flex、Photoshop/Illustrator、Dreamweaver（排名分先后, Dreamweaver早就不顶事了，目前公司里做前台的人都用editplus和aptana，反倒是php程序员在用Dreamweaver——因为他们没有更实用的IDE，Zend Studio被无视了。传说中的Dreamweaver CS3也很让人失望，卖点居然是集成了一个JS框架，可以通过拖拽直接生成一些Ajax效果，也就是说在学.net和flash那一套，其实Dreamweaver过去是，以后也仍然应该是一个有WYSIWYG（所见即所得）功能的文本编辑器，WYSIWYG是它的卖点，但WYSIWYG不应该成为开发的局限，而应该侧重于调试和分析，也就是说它需要的是Firebug1.0那样的功能）。括号里写太长果然就要跑题了，继续说微软——只要打败了Adobe，俘获了那些web前端和RIA开发人员，加上旧三剑客的信徒，微软就可以一统天下了。
其实web开发技术的World War II早就打响了，回顾今年，大部分人都在疯狂的学习Ajax（实质是javascript、基于XML的XHTML和DOM），传统的Flash开发者则都不甘落后的开始研究Flex2和ActionScript3。当然也有人叛逃到其他阵营。这两大参战方具有很多共同点，都是富客户端（RIA）技术，都强调跨平台和兼容性，而且实质上都是XML+脚本语言，不同点是，前者拥有大量开放式标准和开源社区的支持，快速高效，后者则有完善的开发工具、顶尖商业公司的支持、更易于理解和上手。连服务器端方面也不平静，传统的java,php,.net三分天下的地盘里杀入了Ruby on Rails(虽然暂时只是雷声大雨点小)。微软的Expression虽然是迟到的参战者，但如果真的能成气候，明年，最多后年，就可以看到Blizzard游戏里常见的三方势力大战了。
虽然这会让很多人迷茫，但如果你想通了，会发现搅这滩混水或仅仅是旁观，都是很有趣的……其实还不到明年，上个月，就已经热火朝天的吵起来了：
首先是CSDN的两位老师在被Expression俘虏后开始传教：
孟岩老师的感慨（央视其实应该搞一个“技术人生”）——
《谁不是“过渡技术”？》
孟岩老师预言2008年的主流——
《这一天终于来了》
韩磊老师的同感——
《“这一天终于来了”》
在老师们的感染下，新青年们开始进一步探讨“昨日黄花”——
《DHTML+Ajax? MXML+ActionScript? XAML+C#? 是巧合，还是必然？》
Ajaxcn站长Dlee开始反击——
《争论：Ajax技术是否即将没落？》
今天在Matrix（中国最大的Java社区）上看到这一篇：
《2007年web开发技术预言》
当然这个跟国内的争论无关，调查数据来自SitePoint和Ektron的报告
2007年么&#8230;&#8230;一定吵的更热闹。
至于日常生活么，倒不一定会受到什么干扰，比如我们公司里有一个很擅长Flash和AS的PHP程序员，他现在每天工作中都要写大量的JS，昨天又加班到9点，我想他是没有什么时间去和人争论技术名词的。
]]></description>
			<content:encoded><![CDATA[<p><a href="http://bp0.blogger.com/_FPgtQV0mSoM/RXmgk1y6uJI/AAAAAAAAAAU/Up8WDQXx2MM/s1600-h/micros-763387.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;width:140px;" src="http://bp0.blogger.com/_FPgtQV0mSoM/RXmgk1y6uJI/AAAAAAAAAAU/Up8WDQXx2MM/s200/micros-763387.jpg" alt="" id="BLOGGER_PHOTO_ID_5006209015575394450" border="0" /></a>上个月微软开始把传说中的<a href="http://www.microsoft.com/products/expression/en/default.mspx">Expression</a>拿出来show了,这东西对微软来说是具有战略意义的，比IE7要重要的多。要理解它的意义，首先要了解微软。</p>
<p>大家都知道Google的<a href="http://www.google.com/intl/zh-CN/corporate/tenthings.html">核心价值观</a>之一就是“一切以用户为中心”（进而发展出现在最流行的“用户体验至上”），而微软最重视并不是最终用户的感受，虽然你今年看到它马不停蹄的推出IE7、推出OFFICE2007、推出VISTA……仿佛为了满足广大普通用户而忙的不亦乐乎，其实那都是被行业趋势和竞争对手逼出来的。<span style="font-weight:bold;">微软最重视的是开发者。</span>这几年微软在互联网上落后、在主要的软件产品上停步不前，是什么让它依然能站在业界顶端？<span id="more-70"></span></p>
<blockquote><p>.net<br />
Visual Studio<br />
<a href="http://msdn2.microsoft.com/zh-cn/default.aspx">MSDN</a></p></blockquote>
<p>以上就是微软赖以维生的三件“神器”，只要用它们俘获大量的开发者，占据技术市场，就能继续维持垄断地位，普通用户只有接受的份——想想那些采用IE私有技术编写的网页和基于ActiveX开发的网上银行，想想那些基于win平台的商业游戏，就算你对产品本身有怨言，你敢不用IE么？敢不用windows么？用户体验什么的根本不重要，重要的是让全世界的开发者在做软件、web或网络服务时都依赖微软的技术、微软的工具、微软的知识、微软的底层平台和服务器……</p>
<p>这才是真正的垄断之道。</p>
<p>而Expression简单来说就是: FrontPage的接班人、微软的新三剑客，用来对付Adobe的三剑客：Flash/Flex、Photoshop/Illustrator、Dreamweaver（排名分先后, Dreamweaver早就不顶事了，目前公司里做前台的人都用editplus和<a href="http://www.aptana.com/">aptana</a>，反倒是php程序员在用Dreamweaver——因为他们没有更实用的IDE，Zend Studio被无视了。<a href="http://www.shou-nao.com/tw/charles/article.cfm?ATC_ID=B605A477-9ABD-1246-74DD0C321F58AEB5">传说中的Dreamweaver CS3</a>也很让人失望，卖点居然是集成了一个JS框架，可以通过拖拽直接生成一些Ajax效果，也就是说在学.net和flash那一套，其实Dreamweaver过去是，以后也仍然应该是一个有WYSIWYG（所见即所得）功能的文本编辑器，WYSIWYG是它的卖点，但WYSIWYG不应该成为开发的局限，而应该侧重于调试和分析，也就是说它需要的是<a href="http://www.getfirebug.com/">Firebug1.0</a>那样的功能）。括号里写太长果然就要跑题了，继续说微软——只要打败了Adobe，俘获了那些web前端和RIA开发人员，加上旧三剑客的信徒，微软就可以一统天下了。</p>
<p>其实web开发技术的World War II早就打响了，回顾今年，大部分人都在疯狂的学习Ajax（实质是javascript、基于XML的XHTML和DOM），传统的Flash开发者则都不甘落后的开始研究Flex2和ActionScript3。当然也有人<a href="http://www.luar.com.hk/flashbook/archives/001333.php">叛逃到其他阵营</a>。这两大参战方具有很多共同点，都是富客户端（RIA）技术，都强调跨平台和兼容性，而且实质上都是XML+脚本语言，不同点是，前者拥有大量开放式标准和开源社区的支持，快速高效，后者则有完善的开发工具、顶尖商业公司的支持、更易于理解和上手。连服务器端方面也不平静，传统的java,php,.net三分天下的地盘里杀入了<a href="http://www-128.ibm.com/developerworks/cn/java/j-cb05096.html">Ruby on Rails</a>(虽然暂时只是雷声大雨点小)。微软的Expression虽然是<a href="http://www.cnetnews.com.cn/news/softwares/story/0,3800055189,39549927,00.htm">迟到的参战者</a>，但如果真的能成气候，明年，最多后年，就可以看到Blizzard游戏里常见的三方势力大战了。</p>
<p>虽然这会让很多人迷茫，但如果你想通了，会发现搅这滩混水或仅仅是旁观，都是很有趣的……其实还不到明年，上个月，就已经热火朝天的吵起来了：</p>
<p>首先是CSDN的两位老师在被Expression俘虏后开始传教：</p>
<p>孟岩老师的感慨（央视其实应该搞一个“技术人生”）——<br />
<a href="http://blog.csdn.net/myan/archive/2006/11/20/1398915.aspx">《谁不是“过渡技术”？》</a></p>
<p>孟岩老师预言2008年的主流——<br />
<a href="http://blog.csdn.net/myan/archive/2006/11/21/1402346.aspx">《这一天终于来了》</a></p>
<p>韩磊老师的同感——<br />
<a href="http://blog.csdn.net/grhunter/archive/2006/11/22/1405239.aspx">《“这一天终于来了”》</a></p>
<p>在老师们的感染下，新青年们开始进一步探讨“昨日黄花”——<br />
<a href="http://www.wubingstudy.com/Article120.aspx">《DHTML+Ajax? MXML+ActionScript? XAML+C#? 是巧合，还是必然？》</a></p>
<p>Ajaxcn站长Dlee开始反击——<br />
<a href="http://www.matrix.org.cn/resource/article/2006-11-28/5bad47b9-7eb3-11db-babc-9753a314dd4b.html">《争论：Ajax技术是否即将没落？》</a></p>
<p>今天在Matrix（中国最大的Java社区）上看到这一篇：<br />
<a href="http://www.matrix.org.cn/resource/article/2006-12-08/ab918451-8669-11db-b1d1-19025991d682.html">《2007年web开发技术预言》</a><br />
当然这个跟国内的争论无关，调查数据来自SitePoint和Ektron的报告</p>
<p>2007年么&#8230;&#8230;一定吵的更热闹。</p>
<p>至于日常生活么，倒不一定会受到什么干扰，比如我们公司里有一个很擅长Flash和AS的PHP程序员，他现在每天工作中都要写大量的JS，昨天又加班到9点，我想他是没有什么时间去和人争论技术名词的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.limboy.com/2006/12/08/expression/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

