<?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>Thinking for Fun &#187; JavaScript</title>
	<atom:link href="http://jsfox.cn/blog/category/javascript/feed" rel="self" type="application/rss+xml" />
	<link>http://jsfox.cn/blog</link>
	<description>网络 ● 生活 ● 技术</description>
	<lastBuildDate>Tue, 01 Jun 2010 01:52:41 +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>Even Faster Web Sites: 读书笔记(二)</title>
		<link>http://jsfox.cn/blog/javascript/even-faster-websites-notes2.html</link>
		<comments>http://jsfox.cn/blog/javascript/even-faster-websites-notes2.html#comments</comments>
		<pubDate>Sun, 24 Jan 2010 08:54:18 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[前端]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=170</guid>
		<description><![CDATA[这次因为一个项目的原因，又重读了《Even Faster Web Sites》书里的第四章：Loading scripts without blocking，并且在Cuzillion里做了大量测试，又发现了很多有意思的细节。发现自己读书太糙，自责一下。结合实际工作，加上自己的理解，再把这一章的实用内容总结一下。
要解决的问题
页面的script标签引入外部js文件时，会阻塞后续外部资源的下载和加载，包括图片、CSS文件、iframe等等。
1. Script DOM Element比较常用
&#8220;Script DOM Element&#8221;方法是常见的方法，也就是createElement(&#8220;script&#8221;)的方法下载js文件，以此并行加载后续资源。这其实是很棒的一个方法，因为不需要担心跨域，而且我们在中文应用中，不用担心编码的问题（可以为&#60;script&#62;指定编码）。但这里需要注意的是，非IE浏览器下，这种方法会阻止window.onload事件，因此如果你的js文件很大，可能会带来用户体验不好。IE浏览器对这种贴script标签的行为是“无动于衷”的，不会在状态栏、光标和进度圈上做任何指示。看来IE也不是一无是处嘛，哈哈！测试地址。
2. 个人不提倡使用XHR Eval
XHR Eval方法我不提倡使用，首先是中文编码上会遇到麻烦，其次跨域问题。另外就是下面这句：
eval(xhrObj.responseText);
当js文件比较大的时候，用eval会相对较慢，并带来安全性隐患。
3. XHR Inject是个好东西
如果编码和跨域问题都不是问题，那么XHR Inject就是最好的方法了。这是XHR Eval和DOM Script的一个这种办法，实现机制就是：
var s = document.createElement('script');
s.text = xhrObj.responseText;
这种方法避开了evil eval，并且和DOM Script一样，可以按顺序加载js文件，当然，不会阻塞后续资源的加载。更为重要的是，在所有浏览器下，这种方法都不会阻止渲染和onload事件，体现了XMLHTTPRequest的本色。测试地址在此。
4. defer属性可以快速尝试
Script标签的defer属性，可以让后续资源并行加载。在实际的项目中，偶尔也可以尝试使用，因为比较快捷。Firefox 3.1以后，也开始支持script的defer属性啦。
5. document.write(&#8220;a.js&#8221;)的注意事项
注意：在&#60;head&#62;用document.write来插入js脚本，只能让浏览器并行加载&#60;head&#62;里的资源。也就是说，&#60;head&#62;里write脚本，会阻塞&#60;body&#62;的加载。测试地址。另外关于document.write，还有两个需要注意的问题。第一，它只能带来“并行加载js文件”的效果，对其他资源无效；第二，IE、Chrome支持，Firefox不支持。
6. Script in Iframe方法强烈不赞同
在iframe放js，来实现页面资源并行加载，无疑是得不偿失的行为。首先，iframe太沉重了；其次，你还得改你的js代码。反正我是不能接受的，哈哈。
结束语
在开发中，如果要加载数个js大文件，比较实际的做法还是插入script标签的方法。如果没有编码和跨域问题，用XHR Inject方法当然更好啦。
欢迎指正！
]]></description>
			<content:encoded><![CDATA[<p>这次因为一个项目的原因，又重读了《Even Faster Web Sites》书里的第四章：Loading scripts without blocking，并且在Cuzillion里做了大量测试，又发现了很多有意思的细节。发现自己读书太糙，自责一下。结合实际工作，加上自己的理解，再把这一章的实用内容总结一下。</p>
<h3>要解决的问题</h3>
<p>页面的script标签引入外部js文件时，会阻塞后续外部资源的下载和加载，包括图片、CSS文件、iframe等等。</p>
<h3>1. Script DOM Element比较常用</h3>
<p>&#8220;Script DOM Element&#8221;方法是常见的方法，也就是createElement(&#8220;script&#8221;)的方法下载js文件，以此并行加载后续资源。这其实是很棒的一个方法，因为不需要担心跨域，而且我们在中文应用中，不用担心编码的问题（可以为&lt;script&gt;指定编码）。但这里需要注意的是，非IE浏览器下，这种方法会阻止window.onload事件，因此如果你的js文件很大，可能会带来用户体验不好。IE浏览器对这种贴script标签的行为是“无动于衷”的，不会在状态栏、光标和进度圈上做任何指示。看来IE也不是一无是处嘛，哈哈！<a title="IE对Script DOM Element方法无动于衷" href="http://stevesouders.com/cuzillion/?c0=bj1dfff10_0_f&amp;c1=bi1hfff2_0_f&amp;c2=bi1hfff2_0_f&amp;t=1264320241" target="_blank">测试地址</a>。</p>
<h3>2. 个人不提倡使用XHR Eval</h3>
<p>XHR Eval方法我不提倡使用，首先是中文编码上会遇到麻烦，其次跨域问题。另外就是下面这句：<span id="more-170"></span></p>
<pre>eval(xhrObj.responseText);</pre>
<p>当js文件比较大的时候，用eval会相对较慢，并带来安全性隐患。</p>
<h3>3. XHR Inject是个好东西</h3>
<p>如果编码和跨域问题都不是问题，那么XHR Inject就是最好的方法了。这是XHR Eval和DOM Script的一个这种办法，实现机制就是：</p>
<pre>var s = document.createElement('script');
s.text = xhrObj.responseText;</pre>
<p>这种方法避开了evil eval，并且和DOM Script一样，可以按顺序加载js文件，当然，不会阻塞后续资源的加载。更为重要的是，在所有浏览器下，这种方法都不会阻止渲染和onload事件，体现了XMLHTTPRequest的本色。<a title="使用XHR Inject" href="http://stevesouders.com/cuzillion/?c0=bj1ifff10_0_f&amp;c1=bi1hfff2_0_f&amp;c2=bi1hfff2_0_f&amp;c3=bj1ifff10_0_f&amp;t=1264321809123" target="_blank">测试地址在此</a>。</p>
<h3>4. defer属性可以快速尝试</h3>
<p>Script标签的defer属性，可以让后续资源并行加载。在实际的项目中，偶尔也可以尝试使用，因为比较快捷。Firefox 3.1以后，也开始支持script的defer属性啦。</p>
<h3>5. document.write(&#8220;a.js&#8221;)的注意事项</h3>
<p>注意：在&lt;head&gt;用document.write来插入js脚本，只能让浏览器并行加载&lt;head&gt;里的资源。也就是说，&lt;head&gt;里write脚本，会阻塞&lt;body&gt;的加载。<a title="测试head里document.write" href="http://stevesouders.com/cuzillion/?c0=hj1wfff2_0_f&amp;c1=hj1dfff2_0_f&amp;c2=bi1hfff2_0_f&amp;c3=bi1hfff2_0_f&amp;c4=bj1dfff3_1_f&amp;c5=bj1dfff3_1_f&amp;c6=bi1hfff2_0_f&amp;c7=bi1hfff2_0_f&amp;t=1264319269150" target="_blank">测试地址</a>。另外关于document.write，还有两个需要注意的问题。第一，它只能带来“并行加载js文件”的效果，对其他资源无效；第二，IE、Chrome支持，Firefox不支持。</p>
<h3>6. Script in Iframe方法强烈不赞同</h3>
<p>在iframe放js，来实现页面资源并行加载，无疑是得不偿失的行为。首先，iframe太沉重了；其次，你还得改你的js代码。反正我是不能接受的，哈哈。</p>
<h3>结束语</h3>
<p>在开发中，如果要加载数个js大文件，比较实际的做法还是插入script标签的方法。如果没有编码和跨域问题，用XHR Inject方法当然更好啦。</p>
<p>欢迎指正！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/even-faster-websites-notes2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>只做题，先不说话</title>
		<link>http://jsfox.cn/blog/javascript/understanding-javascript-prototype-chain.html</link>
		<comments>http://jsfox.cn/blog/javascript/understanding-javascript-prototype-chain.html#comments</comments>
		<pubDate>Thu, 03 Sep 2009 08:29:50 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[constructor]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[__proto__]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=161</guid>
		<description><![CDATA[已知：
var str = "string";
var Fn = function() {var i;};
var f = new Fn();
下面的语句执行结果，你能说对几个？
   1. str.__proto__
   2. str.prototype
   3. str.constructor
   4. str.__proto__.constructor
   5. Fn.__proto__
   6. Fn.prototype
   7. Fn.constructor
   8. Fn.__proto__.constructor
   9. Fn.__proto__.__proto__
  10. f.__proto__
  11. f.prototype
 [...]]]></description>
			<content:encoded><![CDATA[<p>已知：</p>
<pre>var str = "string";
var Fn = function() {var i;};
var f = new Fn();</pre>
<p>下面的语句执行结果，你能说对几个？</p>
<pre>   1. str.__proto__
   2. str.prototype
   3. str.constructor
   4. str.__proto__.constructor
   5. Fn.__proto__
   6. Fn.prototype
   7. Fn.constructor
   8. Fn.__proto__.constructor
   9. Fn.__proto__.__proto__
  10. f.__proto__
  11. f.prototype
  12. f.constructor
  13. f.__proto__.constructor
  14. f.__proto__.__proto__</pre>
<p>测试页面：<a title="测试JavaScript原型" href="http://jsfox.cn/blog/test/test_proto.html" target="_blank">test_proto.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/understanding-javascript-prototype-chain.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Even Faster Web Sites: 读书笔记(一)</title>
		<link>http://jsfox.cn/blog/javascript/even-faster-websites-notes1.html</link>
		<comments>http://jsfox.cn/blog/javascript/even-faster-websites-notes1.html#comments</comments>
		<pubDate>Fri, 21 Aug 2009 04:31:43 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[前端]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=156</guid>
		<description><![CDATA[《Even Faster Web Sites》是Steve Souders的新书。Steve Souders现在是Google工程师，《High Performance Web Sites》一书的作者，Google Web Ex系列讲座的主持人，对前端优化有很专业的研究。他的UA Profiler和Cuzillion项目尤其引人注目。
《High Performance Web Sites》这本书相信大家都比较熟悉，Souders在其中主要讲解了Yahoo!的14条网站性能军规。很是期待这本《Even Faster Web Sites》，可惜国内市面上还没有。偶得电子版一套，迫不及待打印出来，细细读来。
这本书只有一多半是Souders写的，其他部分是Crockford, NCZ等人的贡献，因此十分有内容。这次先记一些关于页面加载性能方面的读书笔记。
Splitting the initial payload

要提高前端性能，可以这样：页面在第一次加载时，只加载渲染页面所需要的资源（主要针对js），以及一个ScriptLoader方法。其他js资源在需要的时候再动态加载。这样做的挑战就是分离用于初次渲染的js资源，也就是找到split。微软有一个Doloto项目是做这个的，但Doloto还没有向外公布，所以我们得手动搞分裂了。
Loading scripts without blocking
外部js文件在下载和执行时，大多数浏览器都会阻塞其后面的内容（ps这也是可以理解的）。要防止这种阻塞，有若干种办法。我们比较常用的大概是XHR注入和Script tag。Souders还介绍了XHR Eval, Script in Iframe, Script Defer, document.write(&#60;script&#62;)等，并且画出了决策树。这些方法原理都是用异步加载外部js文件，以提高页面渲染速度。方法类似于我们用script tag来实现类ajax跨域应用。
大家可以用Cuzillion来真实测试一下堵塞情形，非常有意思，非常有必要，非常好。
前两天NCZ在他的博客上也对这种异步加载作了介绍，The best way to load external JavaScript。他认为这项技术的best practice是，首先写一个scriptLoader.js，再把页面所需要的其他js都放在second.js里，把scriptLoader.js放在&#60;/body&#62;之前，再紧跟行内js加载second.js文件。确实不错，而且YUI和Google Analytics都这么做了。
那么到底用哪种方法来做script loader呢，在实际应用中，我认为如果不需要跨域、不考虑多个js文件加载顺序的话，XHR Injection最好，因为它不会阻塞onload事件（发现TinyMCE加载插件就是这个原理）；否则的话，就是用script tag方法。
Positioning inline scripts
行内js在执行时，会阻塞其后内容的并行加载、页面渲染。顺便说，如果执行时间过长（100ms以上），用户会感觉到卡，体验非常不好。为了防止阻塞，可以用setTimeout来实现异步调用。那么文档下载完之后，为了给浏览器喘息的机会（进行渲染），延时多久才让这些js执行呢，IE下0ms即可，Firefox下是250ms。
另外有一个大忌，就是外部css文件紧跟行内js的情况。这样会造成比较严重的阻塞。是什么原因呢？行内js一般不会被阻塞，除非代码前面有css。
&#60;link rel='stylesheet' type='text/css' href='a.css' /&#62;
&#60;script type="text/javascript"&#62;
// do a lot [...]]]></description>
			<content:encoded><![CDATA[<p>《Even Faster Web Sites》是<a title="Steve Souders" href="http://stevesouders.com/" target="_blank">Steve Souders</a>的新书。Steve Souders现在是Google工程师，《High Performance Web Sites》一书的作者，Google Web E<sup>x</sup>系列讲座的主持人，对前端优化有很专业的研究。他的<a title=" ua profiler" href="http://stevesouders.com/ua/" target="_blank">UA Profiler</a>和<a title="Cuzillion" href="http://stevesouders.com/cuzillion/" target="_blank">Cuzillion</a>项目尤其引人注目。</p>
<p>《High Performance Web Sites》这本书相信大家都比较熟悉，Souders在其中主要讲解了Yahoo!的14条网站性能军规。很是期待这本《Even Faster Web Sites》，可惜国内市面上还没有。偶得电子版一套，迫不及待打印出来，细细读来。</p>
<p>这本书只有一多半是Souders写的，其他部分是Crockford, NCZ等人的贡献，因此十分有内容。这次先记一些关于页面加载性能方面的读书笔记。</p>
<h4>Splitting the initial payload</h4>
<p><span id="more-156"></span></p>
<p>要提高前端性能，可以这样：页面在第一次加载时，只加载渲染页面所需要的资源（主要针对js），以及一个ScriptLoader方法。其他js资源在需要的时候再动态加载。这样做的挑战就是分离用于初次渲染的js资源，也就是找到split。微软有一个Doloto项目是做这个的，但Doloto还没有向外公布，所以我们得手动搞分裂了。</p>
<h4>Loading scripts without blocking</h4>
<p>外部js文件在下载和执行时，大多数浏览器都会阻塞其后面的内容（ps这也是可以理解的）。要防止这种阻塞，有若干种办法。我们比较常用的大概是XHR注入和Script tag。Souders还介绍了XHR Eval, Script in Iframe, Script Defer, document.write(&lt;script&gt;)等，并且画出了决策树。这些方法原理都是用异步加载外部js文件，以提高页面渲染速度。方法类似于我们用script tag来实现类ajax跨域应用。</p>
<p>大家可以用Cuzillion来真实测试一下堵塞情形，非常有意思，非常有必要，非常好。</p>
<p>前两天NCZ在他的博客上也对这种异步加载作了介绍，<a title="The best way to load external JavaScript" href="http://www.nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/" target="_blank">The best way to load external JavaScript</a>。他认为这项技术的best practice是，首先写一个scriptLoader.js，再把页面所需要的其他js都放在second.js里，把scriptLoader.js放在&lt;/body&gt;之前，再紧跟行内js加载second.js文件。确实不错，而且YUI和Google Analytics都这么做了。</p>
<p>那么到底用哪种方法来做script loader呢，在实际应用中，我认为如果不需要跨域、不考虑多个js文件加载顺序的话，XHR Injection最好，因为它不会阻塞onload事件（发现TinyMCE加载插件就是这个原理）；否则的话，就是用script tag方法。</p>
<h4>Positioning inline scripts</h4>
<p>行内js在执行时，会阻塞其后内容的并行加载、页面渲染。顺便说，如果执行时间过长（100ms以上），用户会感觉到卡，体验非常不好。为了防止阻塞，可以用setTimeout来实现异步调用。那么文档下载完之后，为了给浏览器喘息的机会（进行渲染），延时多久才让这些js执行呢，IE下0ms即可，Firefox下是250ms。</p>
<p>另外有一个大忌，就是外部css文件紧跟行内js的情况。这样会造成比较严重的阻塞。是什么原因呢？行内js一般不会被阻塞，除非代码前面有css。</p>
<pre>&lt;link rel='stylesheet' type='text/css' href='a.css' /&gt;
&lt;script type="text/javascript"&gt;
// do a lot of things
&lt;/script&gt;</pre>
<p>假如行内js前有一个外部css文件（如上述代码），那么这段js要等到css文件完全下载完才会被执行，js被阻塞，造成了页面剩余内容被阻塞，恶劣的连锁反应被引发。</p>
<p>先总结这么多，欢迎指正！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/even-faster-websites-notes1.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>获得原始href属性的方法</title>
		<link>http://jsfox.cn/blog/javascript/get-right-href-attribute.html</link>
		<comments>http://jsfox.cn/blog/javascript/get-right-href-attribute.html#comments</comments>
		<pubDate>Sat, 08 Aug 2009 05:35:16 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[cross-browser]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[href]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[IE]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=141</guid>
		<description><![CDATA[JavaScript里得到某个链接的href属性时，有三种方式，总结一下：
1. 直接获得href属性，也就是
var url = el.href;  // el是一个a元素
2. 使用getAttribute方法，像这样：
var url = el.getAttribute("href");
3. IE下的getAttribute方法有第二个参数，参见msdn的这篇。第二个参数如果是2，意思是以字符串形式返回。
var url = el.getAttribute("href", 2);
获得href属性的这三种方法，同样的，有三点，让人很费解，而且浏览器实现各不相同。

如果href写的是相对地址，得到属性时，浏览器可能会自动转为绝对地址。（很多情况下我们是不希望这样的）
如果href里有汉字，浏览器会自动编码吗？
如果href里有特殊字符，浏览器会自动编码吗？例如大括号{}。

为此我做了一个小测试页面（点这里可测试），得到了如下的结果：



获得href和src属性的浏览器差异（相对地址与自动编码情况）



.href
getAttribute(&#8220;href&#8221;)
getAttribute(&#8220;href&#8221;, 2)


IE6
转绝对，不编码
转绝对，不编码
正常


IE7
转绝对，汉字不编码，特殊符号编码
转绝对，汉字不编码，特殊符号编码
正常


IE8 as IE7
转绝对，汉字不编码，特殊符号编码
转绝对，汉字不编码，特殊符号编码
正常


IE8 standard
转绝对，汉字不编码，特殊符号编码
正常
正常


Firefox 3.0+
转绝对，全部编码
正常
正常


Chrome 2.0
转绝对，全部编码
正常
正常


Safari 4.0
转绝对，汉字编码，特殊符号不编码
正常
正常


Opera 10.0beta
转绝对，汉字编码，特殊符号不编码
正常
正常



其中，“正常”的意思是，得到href属性里原始链接，不自动转绝对地址、汉字和符号都不编码。
结论，如果想得到href里的未经转换、未经编码的原始内容，IE浏览器下全部使用getAttribute(&#8220;href&#8221;, 2)，其他浏览器下使用getAttribute(&#8220;href&#8221;)即可，这在序列化DOM时会非常有用；如果想得到绝对地址、编不编码没关系，那就用href属性。
]]></description>
			<content:encoded><![CDATA[<p>JavaScript里得到某个链接的href属性时，有三种方式，总结一下：</p>
<p>1. 直接获得href属性，也就是</p>
<pre>var url = el.href;  // el是一个a元素</pre>
<p>2. 使用getAttribute方法，像这样：</p>
<pre>var url = el.getAttribute("href");</pre>
<p>3. IE下的getAttribute方法有第二个参数，参见<a title="msdn getAttribute notes" href="http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx" target="_blank">msdn的这篇</a>。第二个参数如果是2，意思是以字符串形式返回。</p>
<pre>var url = el.getAttribute("href", 2);</pre>
<p>获得href属性的这三种方法，同样的，有三点，让人很费解，而且浏览器实现各不相同。</p>
<ol>
<li>如果href写的是相对地址，得到属性时，浏览器可能会自动转为绝对地址。（很多情况下我们是不希望这样的）</li>
<li>如果href里有汉字，浏览器会自动编码吗？</li>
<li>如果href里有特殊字符，浏览器会自动编码吗？例如大括号{}。</li>
</ol>
<p>为此我做了一个小测试页面（<a title="测试获得链接的href属性" href="http://jsfox.cn/blog/test/test_href.html" target="_blank">点这里可测试</a>），得到了如下的结果：<span id="more-141"></span></p>
<table border="0">
<tbody>
<tr>
<th style="font-size:12px" colspan="4">获得href和src属性的浏览器差异（相对地址与自动编码情况）</th>
</tr>
<tr>
<td width="20%"></td>
<td width="25%"><strong>.href</strong></td>
<td width="25%"><strong>getAttribute(&#8220;href&#8221;)</strong></td>
<td width="30%"><strong>getAttribute(&#8220;href&#8221;, 2)</strong></td>
</tr>
<tr>
<td><strong>IE6</strong></td>
<td>转绝对，不编码</td>
<td>转绝对，不编码</td>
<td>正常</td>
</tr>
<tr>
<td><strong>IE7</strong></td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>正常</td>
</tr>
<tr>
<td><strong>IE8 as IE7</strong></td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>正常</td>
</tr>
<tr>
<td><strong>IE8 standard</strong></td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>正常</td>
<td>正常</td>
</tr>
<tr>
<td><strong>Firefox 3.0+</strong></td>
<td>转绝对，全部编码</td>
<td>正常</td>
<td>正常</td>
</tr>
<tr>
<td><strong>Chrome 2.0</strong></td>
<td>转绝对，全部编码</td>
<td>正常</td>
<td>正常</td>
</tr>
<tr>
<td><strong>Safari 4.0</strong></td>
<td>转绝对，汉字编码，特殊符号不编码</td>
<td>正常</td>
<td>正常</td>
</tr>
<tr>
<td><strong>Opera 10.0beta</strong></td>
<td>转绝对，汉字编码，特殊符号不编码</td>
<td>正常</td>
<td>正常</td>
</tr>
</tbody>
</table>
<p>其中，“正常”的意思是，得到href属性里原始链接，不自动转绝对地址、汉字和符号都不编码。</p>
<p>结论，如果想得到href里的未经转换、未经编码的原始内容，IE浏览器下全部使用getAttribute(&#8220;href&#8221;, 2)，其他浏览器下使用getAttribute(&#8220;href&#8221;)即可，这在序列化DOM时会非常有用；如果想得到绝对地址、编不编码没关系，那就用href属性。</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/get-right-href-attribute.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JavaScript调试技巧之：断点调试(2)</title>
		<link>http://jsfox.cn/blog/javascript/debug-js-using-break-points-part2.html</link>
		<comments>http://jsfox.cn/blog/javascript/debug-js-using-break-points-part2.html#comments</comments>
		<pubDate>Tue, 04 Aug 2009 06:31:47 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE8]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Safari]]></category>
		<category><![CDATA[调试]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=116</guid>
		<description><![CDATA[上次总结了Firefox下进行JavaScript断点调试的技巧，这次来看一下其他浏览器下的调试。一点说明，这里的调试技巧都不借助于浏览器之外的工具，例如Aptana，VS2008等。如果要找这方面的一些资料，我这里没有哈。
其他浏览器，主要是Opera, Safari, Chrome和IE8。这之中除了IE8，它们的调试功能都挺不错的，基本都可以搜索脚本，加入断点，查看调用栈、本地变量，以及强大的console。
1. 使用Opera的Dragonfly进行断点调试

打开Tools &#8211; Advanced &#8211; Developer Tools，即可看到类似于Firebug的开发工具，名字叫做Dragonfly，也就是蜻蜓。在这里可以查看页面结构，查看网络交互，以及断点调试，并且可以在调试过程中使用Command Line (console)。
Opera on WindowsXP也属于YUI要支持的A-grade（详见此表格），所以我们在开发的时候，也要尽量去支持。此外Dragonfly的DOM查看工具有一个亮点，Export current DOM view。我们可以在线做一些DOM改动，然后Export一下，即可得到改动后的HTML代码，非常方便。
2. 使用Chrome和Safari进行断点调试
如果你觉得Opera太小众，那么你可以在Safari或者Chrome上进行调试。两个浏览器的调试方式、界面极其相似，所以这里以Safari 4.0为例。打开Menu &#8211; Develop &#8211; Start Debugging JavaScript，即可弹出一个调试工具。值得一提的是，Safari和Chrome的调试工具最好不要Dock到浏览器下面，因为弹出来的话，调试界面是刚刚好的。
首先找到要调试的脚本：
设置断点，重新加载页面（或者执行动作）：
在右侧查看本地变量和函数调用栈：
Safari的调试工具一个亮点是，console和断点调试在同一个界面上，这样可以非常方便地在程序中断时，利用console来做一些验证操作。
3. IE8的断点调试功能
IE8自带的开发者工具，虽然极其难用，但也可以断点调试。断点调试的方法与上述雷同。
可以看到，IE8似乎莫名其妙地终止了js代码的识别。这样的话，从74行往后，都没办法加断点了，真不可思议。但我们有时为了兼容IE，不得不在IE下进行一些调试，怎么办呢？可以用上一篇文章的办法，在需要中断的位置加入debugger语句，这样程序运行时，IE8就会中断在debugger语句上了。
总结
有时候我们为了实现JavaScript程序的cross-browser，即兼容若干浏览器版本，会希望在不同浏览器上进行调试。IE8开发者工具出现之后，几大浏览器都可以调试了。先不论好不好用，总算都有了！
我的个人习惯是：对于一般的功能性调试，使用Firebug即可满足需求。Firefox扩展开发需要调试的，使用JavaScript Debugger（Venkman），页面脚本一般不用这个，因为它启动比较慢。对于浏览器兼容性需要的调试，使用该浏览器的开发者工具即可。对于IE6的调试……%￥……%……&#38;×&#38;×#￥%￥@@，我是没别的办法，只能用眼睛来调了……
欢迎交流！
]]></description>
			<content:encoded><![CDATA[<p>上次总结了<a title="JavaScript调试技巧之：断点调试(1)" href="http://jsfox.cn/blog/javascript/debug-js-using-break-points-part1.html" target="_self">Firefox下进行JavaScript断点调试</a>的技巧，这次来看一下其他浏览器下的调试。一点说明，这里的调试技巧都不借助于浏览器之外的工具，例如Aptana，VS2008等。如果要找这方面的一些资料，我这里没有哈。</p>
<p>其他浏览器，主要是Opera, Safari, Chrome和IE8。这之中除了IE8，它们的调试功能都挺不错的，基本都可以搜索脚本，加入断点，查看调用栈、本地变量，以及强大的console。</p>
<h3>1. 使用Opera的Dragonfly进行断点调试</h3>
<div id="attachment_117" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/breaked-locals-opera.png"><img class="size-medium wp-image-117" title="breaked-locals-opera" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/breaked-locals-opera-300x152.png" alt="使用Opera进行断点调试" width="300" height="152" /></a><p class="wp-caption-text">使用Opera Dragonfly进行断点调试</p></div>
<p><span id="more-116"></span></p>
<p>打开Tools &#8211; Advanced &#8211; Developer Tools，即可看到类似于Firebug的开发工具，名字叫做<a title="Opera Dragonfly 蜻蜓" href="http://www.opera.com/dragonfly/" target="_blank">Dragonfly</a>，也就是蜻蜓。在这里可以查看页面结构，查看网络交互，以及断点调试，并且可以在调试过程中使用Command Line (console)。</p>
<p>Opera on WindowsXP也属于YUI要支持的A-grade（<a title="YUI Graded Browser Support Chart" href="http://jsfox.cn/blog/javascript/is-your-web-app-beta.html" target="_self">详见此表格</a>），所以我们在开发的时候，也要尽量去支持。此外Dragonfly的DOM查看工具有一个亮点，Export current DOM view。我们可以在线做一些DOM改动，然后Export一下，即可得到改动后的HTML代码，非常方便。</p>
<h3>2. 使用Chrome和Safari进行断点调试</h3>
<p>如果你觉得Opera太小众，那么你可以在Safari或者Chrome上进行调试。两个浏览器的调试方式、界面极其相似，所以这里以Safari 4.0为例。打开Menu &#8211; Develop &#8211; Start Debugging JavaScript，即可弹出一个调试工具。值得一提的是，Safari和Chrome的调试工具最好不要Dock到浏览器下面，因为弹出来的话，调试界面是刚刚好的。</p>
<p>首先找到要调试的脚本：</p>
<div id="attachment_118" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/find-scripts-safari.PNG"><img class="size-medium wp-image-118" title="find-scripts-safari" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/find-scripts-safari-300x261.PNG" alt="使用Safari进行JavaScript调试：找到脚本" width="300" height="261" /></a><p class="wp-caption-text">使用Safari进行JavaScript调试：找到脚本</p></div>
<p>设置断点，重新加载页面（或者执行动作）：</p>
<div id="attachment_120" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/breakpoint-safari.PNG"><img class="size-medium wp-image-120" title="breakpoint-safari" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/breakpoint-safari-300x158.PNG" alt="使用Safari进行JavaScript调试：设置断点" width="300" height="158" /></a><p class="wp-caption-text">使用Safari进行JavaScript调试：设置断点</p></div>
<p>在右侧查看本地变量和函数调用栈：</p>
<div id="attachment_119" class="wp-caption aligncenter" style="width: 296px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/breaked-locals-safari.PNG"><img class="size-medium wp-image-119" title="breaked-locals-safari" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/breaked-locals-safari-286x300.PNG" alt="使用Safari进行JavaScript调试：变量查看" width="286" height="300" /></a><p class="wp-caption-text">使用Safari进行JavaScript调试：变量查看</p></div>
<p>Safari的调试工具一个亮点是，console和断点调试在同一个界面上，这样可以非常方便地在程序中断时，利用console来做一些验证操作。</p>
<h3>3. IE8的断点调试功能</h3>
<p>IE8自带的开发者工具，虽然极其难用，但也可以断点调试。断点调试的方法与上述雷同。</p>
<div id="attachment_121" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/poor-ie8-debugging.png"><img class="size-medium wp-image-121" title="poor-ie8-debugging" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/poor-ie8-debugging-300x149.png" alt="使用IE8开发者工具进行断点调试" width="300" height="149" /></a><p class="wp-caption-text">使用IE8开发者工具进行断点调试</p></div>
<p>可以看到，IE8似乎莫名其妙地终止了js代码的识别。这样的话，从74行往后，都没办法加断点了，真不可思议。但我们有时为了兼容IE，不得不在IE下进行一些调试，怎么办呢？可以用上一篇文章的办法，在需要中断的位置加入debugger语句，这样程序运行时，IE8就会中断在debugger语句上了。</p>
<h3>总结</h3>
<p>有时候我们为了实现JavaScript程序的cross-browser，即兼容若干浏览器版本，会希望在不同浏览器上进行调试。IE8开发者工具出现之后，几大浏览器都可以调试了。先不论好不好用，总算都有了！</p>
<p>我的个人习惯是：对于一般的功能性调试，使用Firebug即可满足需求。Firefox扩展开发需要调试的，使用JavaScript Debugger（Venkman），页面脚本一般不用这个，因为它启动比较慢。对于浏览器兼容性需要的调试，使用该浏览器的开发者工具即可。对于IE6的调试……%￥……%……&amp;×&amp;×#￥%￥@@，我是没别的办法，只能用眼睛来调了……</p>
<p>欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/debug-js-using-break-points-part2.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JavaScript调试技巧之：断点调试(1)</title>
		<link>http://jsfox.cn/blog/javascript/debug-js-using-break-points-part1.html</link>
		<comments>http://jsfox.cn/blog/javascript/debug-js-using-break-points-part1.html#comments</comments>
		<pubDate>Mon, 03 Aug 2009 16:26:00 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[调试]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=77</guid>
		<description><![CDATA[如果您还没有阅读《JavaScript调试技巧之：快速定位》，建议先看看那篇。说不定，用快速定位就能解决问题了，呵呵。这次我会总结记录一下断点调试的笔记，希望也对大家有用，欢迎补充交流！
首先，在各个浏览器中，断点调试支持的最好的当然是Firefox，Firefox不仅可以使用Firebug调试页面js脚本，还可以用高级调试工具例如JavaScript Debugger (Venkman) 来调试Firefox扩展里的js。除此之外，Firefox还支持一些更为高级的断点调试、变量监视功能。
其他浏览器里，Opera、Chrome和Safari的调试功能也比较好用。Opera的DragonFly速度相对比较快，界面清爽，功能强大，但不如Safari等友好。相比来说，IE8的程序员工具简直没法用。
这次时间有限，先来总结一下Firefox下的调试技巧。
1. 使用Firebug进行断点调试
使用Firebug调试JavaScript非常方便。具体步骤：
a. 打开Firebug后，启用“脚本”调试，找到引用的脚本文件（或者行内js）；
b. 在适当的位置加入断点；
c. 如果断点已经执行过，则刷新页面，这时脚本就会在断点处中断。如果断点没有执行过，那可以直接执行页面上的动作（例如点击按钮等），然后代码会在断点处中断；
d. 观察函数调用栈，观察local变量，也可以进行单步执行，进行调试。
确实非常简单！用Firebug断点调试的优点总结如下：

能加断点的行用绿色行号，非常直观；
call stack用两种方式显示出来，很方便；
本地变量的显示非常清晰明了。

2. 使用JavaScript Debugger进行断点调试
这是老牌的调试工具，之前叫做Venkman，可以以扩展形式安装在Firefox上，我们在这里就称他为Venkman吧。它不仅能够调试页面脚本，还能调试Firefox扩展（extension）里的js。我们在做Firefox扩展开发时，Venkman是必不可少的工具，老田强力推荐！当然，Firefox本身的逻辑实现，也是用JavaScript来做到的。我们现在可以用Venkman来调试一下Firefox本身。Firefox的核心js是browser.js，在这个路径下：
chrome://browser/content/browser.js
我们打开Venkman之后，在Loaded Scripts里填入browser.js，这个js文件就会被过滤出来（如果没有看到browser.js，那么你可能需要查一下是否选上了Debug-&#62;Exclude browser files）。
我们找到让浏览器后退的代码，然后点击Firefox的后退按钮，这时Venkman就会停在BrowserBack方法上！让我们再一步一步地看一看，Firefox自己到底做了什么。btw，实现Firefox的js代码也不是很漂亮嘛~~~
Venkman当然也带有一个console，利用这个console，我们可以看一看浏览器层次的window和document都是什么东西。类似于Firebug和其他浏览器的console，只要直接输入js代码片段即可！
有兴趣的话，可以在这里发现更多有关Firefox开发（以及扩展开发）的好玩的东西！
3. 使用debugger在程序中加入断点
另外还有一个少为人知的断点加入方法。我们可以在程序中加入debugger语句，这样Firefox的调试工具会停留在这条语句上，代码也暂停执行，和加入断点的效果一样。例如：
var myfunc = {
    get_field_value_callback : function() {
        debugger;
        var ed = this, target = ed.currSpan;
        [...]]]></description>
			<content:encoded><![CDATA[<p>如果您还没有阅读《<a title="JavaScript调试技巧之：快速定位" href="http://jsfox.cn/blog/javascript/debug-js-quick-locate.html" target="_self">JavaScript调试技巧之：快速定位</a>》，建议先看看那篇。说不定，用快速定位就能解决问题了，呵呵。这次我会总结记录一下断点调试的笔记，希望也对大家有用，欢迎补充交流！</p>
<p>首先，在各个浏览器中，断点调试支持的最好的当然是Firefox，Firefox不仅可以使用Firebug调试页面js脚本，还可以用高级调试工具例如JavaScript Debugger (Venkman) 来调试Firefox扩展里的js。除此之外，Firefox还支持一些更为高级的断点调试、变量监视功能。</p>
<p>其他浏览器里，Opera、Chrome和Safari的调试功能也比较好用。Opera的<a title="下载和安装带有DragonFly的Opera" href="http://www.opera.com/dragonfly/" target="_blank">DragonFly</a>速度相对比较快，界面清爽，功能强大，但不如Safari等友好。相比来说，IE8的程序员工具简直没法用。</p>
<p>这次时间有限，先来总结一下Firefox下的调试技巧。<span id="more-77"></span></p>
<h3><strong>1. 使用Firebug进行断点调试</strong></h3>
<p>使用Firebug调试JavaScript非常方便。具体步骤：</p>
<p>a. 打开Firebug后，启用“脚本”调试，找到引用的脚本文件（或者行内js）；</p>
<div id="attachment_105" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/find-scripts-firebug.PNG"><img class="size-medium wp-image-105" title="find-scripts-firebug" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/find-scripts-firebug-300x180.PNG" alt="用Firebug找到要调试的脚本（点击放大）" width="300" height="180" /></a><p class="wp-caption-text">用Firebug找到要调试的脚本（点击放大）</p></div>
<p>b. 在适当的位置加入断点；</p>
<p>c. 如果断点已经执行过，则刷新页面，这时脚本就会在断点处中断。如果断点没有执行过，那可以直接执行页面上的动作（例如点击按钮等），然后代码会在断点处中断；</p>
<div id="attachment_103" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/breaked-locals-firebug.PNG"><img class="size-medium wp-image-103" title="breaked-locals-firebug" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/breaked-locals-firebug-300x90.PNG" alt="用Firebug进行断点调试" width="300" height="90" /></a><p class="wp-caption-text">用Firebug进行断点调试（点击放大）</p></div>
<p>d. 观察函数调用栈，观察local变量，也可以进行单步执行，进行调试。</p>
<p>确实非常简单！用Firebug断点调试的优点总结如下：</p>
<ul>
<li>能加断点的行用绿色行号，非常直观；</li>
<li>call stack用两种方式显示出来，很方便；</li>
<li>本地变量的显示非常清晰明了。</li>
</ul>
<h3>2. 使用JavaScript Debugger进行断点调试</h3>
<p>这是老牌的调试工具，之前叫做<a title="download venkman! The most powerful JavaScript Debugger! " href="http://www.mozilla.org/projects/venkman/">Venkman</a>，可以以扩展形式安装在Firefox上，我们在这里就称他为Venkman吧。它不仅能够调试页面脚本，还能调试Firefox扩展（extension）里的js。我们在做Firefox扩展开发时，Venkman是必不可少的工具，老田强力推荐！当然，Firefox本身的逻辑实现，也是用JavaScript来做到的。我们现在可以用Venkman来调试一下Firefox本身。Firefox的核心js是browser.js，在这个路径下：</p>
<address>chrome://browser/content/browser.js</address>
<p>我们打开Venkman之后，在Loaded Scripts里填入browser.js，这个js文件就会被过滤出来（如果没有看到browser.js，那么你可能需要查一下是否选上了Debug-&gt;Exclude browser files）。</p>
<div id="attachment_107" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/venkman-select-scripts.png"><img class="size-medium wp-image-107" title="venkman-select-scripts" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/venkman-select-scripts-300x262.png" alt="Venkman：选择要调试的js文件" width="300" height="262" /></a><p class="wp-caption-text">Venkman：选择要调试的js文件（点击放大）</p></div>
<p>我们找到让浏览器后退的代码，然后点击Firefox的后退按钮，这时Venkman就会停在BrowserBack方法上！让我们再一步一步地看一看，Firefox自己到底做了什么。btw，实现Firefox的js代码也不是很漂亮嘛~~~</p>
<div id="attachment_108" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/venkman-breaked.png"><img class="size-medium wp-image-108" title="venkman-breaked" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/venkman-breaked-300x204.png" alt="用JavaScript Debugger调试Firefox" width="300" height="204" /></a><p class="wp-caption-text">用JavaScript Debugger断点调试Firefox（点击放大）</p></div>
<p>Venkman当然也带有一个console，利用这个console，我们可以看一看浏览器层次的window和document都是什么东西。类似于Firebug和其他浏览器的console，只要直接输入js代码片段即可！</p>
<div id="attachment_106" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/08/console-venkman.png"><img class="size-medium wp-image-106" title="console-venkman" src="http://jsfox.cn/blog/wp-content/uploads/2009/08/console-venkman-300x217.png" alt="使用Venkman自带的console" width="300" height="217" /></a><p class="wp-caption-text">使用Venkman自带的console（点击放大）</p></div>
<p>有兴趣的话，可以在这里发现更多有关Firefox开发（以及扩展开发）的好玩的东西！</p>
<h3>3. 使用debugger在程序中加入断点</h3>
<p>另外还有一个少为人知的断点加入方法。我们可以在程序中加入debugger语句，这样Firefox的调试工具会停留在这条语句上，代码也暂停执行，和加入断点的效果一样。例如：</p>
<pre>var myfunc = {
    get_field_value_callback : function() {
        debugger;
        var ed = this, target = ed.currSpan;
        /* do something more */
    }
}</pre>
<p>这时重新加载页面，断点就会停留在debugger语句上。这样，我们就可以在写代码时随心所欲地加入断点了。另外，其他浏览器（包括IE8！Surprise！）同样支持debugger语句！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/debug-js-using-break-points-part1.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JavaScript调试技巧之：快速定位</title>
		<link>http://jsfox.cn/blog/javascript/debug-js-quick-locate.html</link>
		<comments>http://jsfox.cn/blog/javascript/debug-js-quick-locate.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 16:48:03 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[IE8]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Safari]]></category>
		<category><![CDATA[调试]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=22</guid>
		<description><![CDATA[赶紧总结一下JavaScript的调试技巧，这次首先是“快速定位”篇。
快速定位，其实就是快速定位程序的错误，所以也算是调试。这个在实际的码代码时往往比较实用。大多数情况下，你的js代码不多（少于1000行），只要能迅速发现代码的错误，往往不用复杂的调试。关于常用的快速定位方法，我总结了一下几点，欢迎大家补充。
1. 使用alert
alert其实比较实用。本地调试中，在合适的位置写alert，打出来一些变量，虽然比较土，但是往往事半功倍！另外有一个alert技巧，想看看一个对象中的属性和它的值吗，试试这个：
var str = "", i;
for (i in obj) {
  str += i + ": " +obj[i] + "\n";
}
alert(str);
2. 使用地址栏

使用地址栏，输入javascript: doSomething()，可以在Runtime时输出或者执行一些代码。输出东西时也使用alert，例如在地址栏输入：
javascript: alert(document.getElementsByTagName("a").length);
可以输入当前的document下的链接数量。如果想执行已经加载的自定义函数，可以输入例如：
javascript: deleteFirstChildNode();
3. 错误查看器
最快捷的错误查看器当属Firefox的错误控制台，快捷键ctrl+shift+j。在你觉得脚本执行不正常时，首先按一下这个快捷键，往往能立刻知道哪里出了问题，并且点一下就能到问题脚本所在的位置，非常方便，强烈推荐！
4. 用浏览器的扩展或插件查看错误
这个话题比较大，一时说不完，所以先说说用扩展或插件来查看错误。对我来讲，Firebug一般就够用了，比较常见，就不截图了。启用Firebug控制台后，如果页面上js脚本错误，就会立刻在右下角显示出来，点击可以查看错误。有一点需注意，我的Firebug有时会报这个带乱码的错误：
 (¹Õ Location.toString
我一直不清楚这个为什么会乱码，但我知道这个是跨域的错误，比较常见。
其他浏览器的错误查看器，在这里我也简单总结一下：
Chrome：菜单 &#8211; 开发人员 &#8211; JavaScript控制台，下方可以看到类似于Firebug的console，在这里可以看到错误和警告信息。
Opera：菜单 &#8211; 工具 &#8211; 高级 &#8211; Error Console，功能比较强大，可以查看各类错误。
Safari：4.0版跟Chrome查看方式一样。Chrome/Opera/Safari都可以在Develope Tools里看到错误信息。
IE8：非常不好用，但是也有。开发人员工具 &#8211; Script标签 &#8211; 点击右边的console。在这个console里可以看到错误信息，但是不太友好。
5. console.log
在代码中使用console.log，也就是类似于alert，只不过把想要的信息输出到console里。console对象在Firefox、Chrome、Safari里都可以使用。除了console.log，还有console.error，console.info等等。详见Firebug的console API。
6. Console
最后正式介绍一下Console，也就是控制台。Life is short, use console！以Firebug的console为例，把几个常用功能介绍总结一下：

查看js对象

输入一个名字，例如window，window对象就会出现在结果中。这时可以点击这个window对象！点击以后就可以在DOM标签中查看这个对象的所有属性。那么现在应该能看到window下的全局变量了，方便吧！

查看DOM对象

输入document.getElementById(&#8220;el_id&#8221;)，这时el_id这个元素就会出现在结果中，点击可以看到它的详情，例如看看它当时的HTML代码。

在Runtime执行脚本

输入任何的js代码，立刻执行。这样可以很方便地测试页面上的脚本了。也可以在多行模式中执行输入的js。
关于这个console，在输入js脚本时，别忘了按tab键进行代码自动补齐哦！代码补齐和提示功能，在Chrome、Safari和Opera里同样有效，IE8就惨点了。Chrome和Safari做的也非常好，大家可以试一下啊。
简而言之，掌握快速定位，可以迅速解决JavaScript开发中的琐碎问题，以上办法中，我的建议是，遇到问题先用错误查看器看一下，不行再使用Console，基本上就能很快定位问题原因了！
]]></description>
			<content:encoded><![CDATA[<p>赶紧总结一下JavaScript的调试技巧，这次首先是“快速定位”篇。</p>
<p>快速定位，其实就是快速定位程序的错误，所以也算是调试。这个在实际的码代码时往往比较实用。大多数情况下，你的js代码不多（少于1000行），只要能迅速发现代码的错误，往往不用复杂的调试。关于常用的快速定位方法，我总结了一下几点，欢迎大家补充。</p>
<p><strong>1. 使用alert</strong></p>
<p>alert其实比较实用。本地调试中，在合适的位置写alert，打出来一些变量，虽然比较土，但是往往事半功倍！另外有一个alert技巧，想看看一个对象中的属性和它的值吗，试试这个：</p>
<pre>var str = "", i;
for (i in obj) {
  str += i + ": " +obj[i] + "\n";
}
alert(str);</pre>
<p><strong>2. 使用地址栏</strong></p>
<p><span id="more-22"></span></p>
<p>使用地址栏，输入javascript: doSomething()，可以在Runtime时输出或者执行一些代码。输出东西时也使用alert，例如在地址栏输入：</p>
<pre>javascript: alert(document.getElementsByTagName("a").length);</pre>
<p>可以输入当前的document下的链接数量。如果想执行已经加载的自定义函数，可以输入例如：</p>
<pre>javascript: deleteFirstChildNode();</pre>
<p><strong>3. 错误查看器</strong></p>
<p>最快捷的错误查看器当属Firefox的错误控制台，快捷键ctrl+shift+j。在你觉得脚本执行不正常时，首先按一下这个快捷键，往往能立刻知道哪里出了问题，并且点一下就能到问题脚本所在的位置，非常方便，强烈推荐！</p>
<p><strong>4. 用浏览器的扩展或插件查看错误</strong></p>
<p>这个话题比较大，一时说不完，所以先说说用扩展或插件来查看错误。对我来讲，Firebug一般就够用了，比较常见，就不截图了。启用Firebug控制台后，如果页面上js脚本错误，就会立刻在右下角显示出来，点击可以查看错误。有一点需注意，我的Firebug有时会报这个带乱码的错误：</p>
<pre> <span style="color: #ff0000;">(¹Õ Location.toString</span></pre>
<p>我一直不清楚这个为什么会乱码，但我知道这个是跨域的错误，比较常见。</p>
<p>其他浏览器的错误查看器，在这里我也简单总结一下：
<a href='http://jsfox.cn/blog/javascript/debug-js-quick-locate.html/attachment/chrome_error_console' title='chrome_error_console'><img width="150" height="132" src="http://jsfox.cn/blog/wp-content/uploads/2009/07/chrome_error_console-150x132.png" class="attachment-thumbnail" alt="Chrome错误控制台" title="chrome_error_console" /></a>
<a href='http://jsfox.cn/blog/javascript/debug-js-quick-locate.html/attachment/ie8_error_console' title='IE8_error_console'><img width="150" height="150" src="http://jsfox.cn/blog/wp-content/uploads/2009/07/IE8_error_console-150x150.png" class="attachment-thumbnail" alt="IE8错误查看器" title="IE8_error_console" /></a>
<a href='http://jsfox.cn/blog/javascript/debug-js-quick-locate.html/attachment/opera_error_console' title='opera_error_console'><img width="150" height="150" src="http://jsfox.cn/blog/wp-content/uploads/2009/07/opera_error_console-150x150.png" class="attachment-thumbnail" alt="Opera错误控制台" title="opera_error_console" /></a>
</p>
<p>Chrome：菜单 &#8211; 开发人员 &#8211; JavaScript控制台，下方可以看到类似于Firebug的console，在这里可以看到错误和警告信息。</p>
<p>Opera：菜单 &#8211; 工具 &#8211; 高级 &#8211; Error Console，功能比较强大，可以查看各类错误。</p>
<p>Safari：4.0版跟Chrome查看方式一样。Chrome/Opera/Safari都可以在Develope Tools里看到错误信息。</p>
<p>IE8：非常不好用，但是也有。开发人员工具 &#8211; Script标签 &#8211; 点击右边的console。在这个console里可以看到错误信息，但是不太友好。</p>
<p><strong>5. console.log</strong></p>
<p>在代码中使用console.log，也就是类似于alert，只不过把想要的信息输出到console里。console对象在Firefox、Chrome、Safari里都可以使用。除了console.log，还有console.error，console.info等等。详见Firebug的<a title="Firebug Console API" href="http://getfirebug.com/console.html" target="_self">console API</a>。</p>
<p><strong>6. Console</strong></p>
<p>最后正式介绍一下Console，也就是控制台。Life is short, use console！以Firebug的console为例，把几个常用功能介绍总结一下：</p>
<ul>
<li>查看js对象</li>
</ul>
<p style="padding-left: 30px;">输入一个名字，例如window，window对象就会出现在结果中。这时可以点击这个window对象！点击以后就可以在DOM标签中查看这个对象的所有属性。那么现在应该能看到window下的全局变量了，方便吧！</p>
<ul>
<li>查看DOM对象</li>
</ul>
<p style="padding-left: 30px;">输入document.getElementById(&#8220;el_id&#8221;)，这时el_id这个元素就会出现在结果中，点击可以看到它的详情，例如看看它当时的HTML代码。</p>
<ul>
<li>在Runtime执行脚本</li>
</ul>
<p style="padding-left: 30px;">输入任何的js代码，立刻执行。这样可以很方便地测试页面上的脚本了。也可以在多行模式中执行输入的js。</p>
<p>关于这个console，在输入js脚本时，别忘了按tab键进行代码自动补齐哦！代码补齐和提示功能，在Chrome、Safari和Opera里同样有效，IE8就惨点了。Chrome和Safari做的也非常好，大家可以试一下啊。</p>
<p>简而言之，掌握快速定位，可以迅速解决JavaScript开发中的琐碎问题，以上办法中，我的建议是，遇到问题先用错误查看器看一下，不行再使用Console，基本上就能很快定位问题原因了！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/debug-js-quick-locate.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>提高JavaScript程序的鲁棒性</title>
		<link>http://jsfox.cn/blog/javascript/make-your-javascript-robust.html</link>
		<comments>http://jsfox.cn/blog/javascript/make-your-javascript-robust.html#comments</comments>
		<pubDate>Thu, 09 Jul 2009 18:17:08 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=26</guid>
		<description><![CDATA[我是学控制理论出身，一个控制系统的鲁棒性，确实是在做系统设计时需要着重注意的。什么是控制系统的鲁棒性？
所谓“鲁棒性”，是指控制系统在一定（结构，大小）的参数摄动下，维持某些性能的特性（摘自百度百科……汗）。
在软件设计和开发中，同样也要时刻考虑提高鲁棒性。那么如何提高JavaScript程序的鲁棒性呢？我认为，RIA的鲁棒性，一般来讲，主要跟js的代码规范性和DOM操作有关系。下面我总结几点开发中需要注意的地方，让页面跑不死、不报错。这些事情可能在实际开发中都是小事，但是对于提高软件整体的鲁棒性，是非常critical的！
1. 严禁使用全局变量
唉，这个我可是亲身体会并深受其害啊！话说，当时我修改一个页面，开发一段脚本，需要写cookie。我发现页面上以前有人引用了一个js文件，里面有setCookie函数，好啊，拿来用！结果这个cookie死活都写不对。检查了半天，才发现这个页面引用的另外一个js文件也有一个setCookie函数，函数的参数和刚才那个不一样，而我调用的估计是这个函数！应该是之前的两个同事在同一个页面上自己搞自己的，结果竟然函数重名，而这两个函数都是全局的！设想一下，加入两个人都在全局范围内搞一个var i = 0; 那岂不是更加疯掉。

这个故事得到的教训，首先当然是同一个team的开发者应该多兼容并包，团结协作。其次呢，页面的js较多的时候，一定要有一个好的层次，避免全局变量。避免全局变量的一个方式是namespace。例如创建一个这样的程序结构：
var my_project = {
  dom : {
    get : function() {},
    make : function() {} // etc.
  },
  cookie : {
    get : function() {},
    set : function() {},
    remove : function() {}
  },

  util : {
   [...]]]></description>
			<content:encoded><![CDATA[<p>我是学控制理论出身，一个控制系统的鲁棒性，确实是在做系统设计时需要着重注意的。什么是控制系统的鲁棒性？</p>
<p>所谓“鲁棒性”，是指控制系统在一定（结构，大小）的参数摄动下，维持某些性能的特性（摘自百度百科……汗）。</p>
<p>在软件设计和开发中，同样也要时刻考虑提高鲁棒性。那么如何提高JavaScript程序的鲁棒性呢？我认为，RIA的鲁棒性，一般来讲，主要跟js的代码规范性和DOM操作有关系。下面我总结几点开发中需要注意的地方，让页面跑不死、不报错。这些事情可能在实际开发中都是小事，但是对于提高软件整体的鲁棒性，是非常critical的！</p>
<p><strong>1. 严禁使用全局变量</strong></p>
<p>唉，这个我可是亲身体会并深受其害啊！话说，当时我修改一个页面，开发一段脚本，需要写cookie。我发现页面上以前有人引用了一个js文件，里面有setCookie函数，好啊，拿来用！结果这个cookie死活都写不对。检查了半天，才发现这个页面引用的另外一个js文件也有一个setCookie函数，函数的参数和刚才那个不一样，而我调用的估计是这个函数！应该是之前的两个同事在同一个页面上自己搞自己的，结果竟然函数重名，而这两个函数都是全局的！设想一下，加入两个人都在全局范围内搞一个var i = 0; 那岂不是更加疯掉。</p>
<p><span id="more-26"></span></p>
<p>这个故事得到的教训，首先当然是同一个team的开发者应该多兼容并包，团结协作。其次呢，页面的js较多的时候，一定要有一个好的层次，避免全局变量。避免全局变量的一个方式是namespace。例如创建一个这样的程序结构：</p>
<pre>var my_project = {
  dom : {
    get : function() {},
    make : function() {} // etc.
  },
  cookie : {
    get : function() {},
    set : function() {},
    remove : function() {}
  },

  util : {
    // some project utilities
  }
}</pre>
<p><strong>2. 多使用短路表达式</strong></p>
<p>全局变量的部分说的有点多了，大概是因为老田我经历过那类痛苦吧。短路表达式就是&amp;&amp;和||，在这里用来提高鲁棒性。举两个例子，第一，要得到某div节点的第一个节点的nodeName：</p>
<pre>var div = document.getElementById("div_id");
var node_name;
if (div &amp;&amp; div.firstChild) { // 在用firstChild前，先判断div是否存在
  node_name = div.firstChild.nodeName;
}</pre>
<p>其次，用||来快速解决一些浏览器兼容性问题：</p>
<pre>// 得到元素内文本的跨浏览器解决方案
var text = span.innerText || span.textContent || "";</pre>
<p>再例，用||来设置默认值：</p>
<pre>// 设置默认值
var my_attr = span.getAttribute("my_attr") || default_value;</pre>
<p><strong>3. 操作元素前，首先判断其存在</strong></p>
<p>在第二条里面已经举过例子。再举一例：</p>
<pre>var input = document.getElementsByName("input")[0];
if (input) {
  target = input.value;
}</pre>
<p><strong>4. 良好的代码缩进和格式</strong></p>
<p>Doug Crockford，《JavaScirpt: The Good Parts》的作者，在<a href="http://youtube.com/?v=hQVTIJBZook" target="_blank">给Google做演讲</a>的时候，详细分析了代码格式的重要性。比如：</p>
<pre>return
{
  name : span.nodeName,
  value : span.innerHTML
}</pre>
<p>写这种代码的人肯定是C出身。js里面，后果就是return nothing。js有语句的自动补全机制，return这一样，会自动在末尾加上分号，导致返回。如果不注意的话，程序出了问题，很难找到原因。所以一定要养成一个代码格式的好习惯，把左大括号和return啊，if啊，function()啊，写在一起。也就是：</p>
<pre>return {
  // something
}</pre>
<p><strong>5. 使用跨浏览器的代码</strong></p>
<p>在对DOM进行读取和操作时，处处想着浏览器兼容性这件事，免得最后返工，自己给自己找麻烦。比如，只用document.getElementById；用nodeName，而不用tagName；不用getElementsByClassName等先进的选择器；不用applyElement, removeNode, swapNode等IE only的方法。</p>
<p>在浏览器兼容性方面，强烈推荐ppk的站点<a title="quirksmode.org" href="http://quirksmode.org" target="_blank">quirksmode.org</a>。ppk此人对各个浏览器都进行了测试，工作十分扎实，是我们的榜样啊！</p>
<p><strong>6. 变量尽早定义</strong></p>
<p>JavaScript的变量作用域是所在的整个function，在写代码的时候，如果变量在想用的时候再定义，很容易变得难于管理。在开发逻辑比较复杂的程序时，非常容易混乱，甚至变量重名。</p>
<p><strong>7. 小心NodeList</strong></p>
<p>NodeList，也就是节点列表，是一个陷阱，他不是静态的，而是危险的动态结构，它会立即反映文档的变化。一个经典的死循环案例：</p>
<pre>var lis = ul.getElementsByTagName("li");
for (var i = 0; i &lt; lis.length; i++) {
  ul.appendChild(lis[i].cloneNode(true));
}</pre>
<p>上面的代码里，这些li的length不是固定的，而是随着DOM的变化而变化。这个错误我是经历过一次啊，不过不是死循环。还拿这个ul和li举例子吧，我想删掉某个ul下面的所有li，代码类似于下面的样子，大家看看有什么问题呢？</p>
<pre>var lis = ul.getElemenetsByTagName("li");
for (var i = 0; i &lt; lis.length; i++) {
  ul.removeChild(lis[i]);
}</pre>
<p><strong>8. 使用===和!==</strong></p>
<p>某些人可能会问，我用==用的挺好的啊，为什么要用===？那我要反问，既然===更加严谨，没有类型转换，而==充满陷阱，为什么不用===？没有自信吗？哦，那只能说明你的程序不稳定，鲁棒性不好了。</p>
<p>==会进行自动类型转换，Crockford称它为evil twins。其他的不说了，举几个例子：</p>
<pre>alert(0 == '');  // true
alert(false == '0'); //true
alert('\r\n' == 0); // true</pre>
<p><strong>9. 不要用with</strong></p>
<p>在设计JavaScript这门语言的时候，with本来是为一些操作提供快捷方式的，但是设计的不够好，可以说js里面没有with会更好。举一个使用with的例子：</p>
<pre>with(element.style) {
  position = "absolute";
  left = "100px";
  top = "100px";
}</pre>
<p>首先with破坏了这门语言的变量作用域结构。在js里面，postion, left和top本来应该变成全局变量的。可能有些人说，这样正好，我可以通过with来控制变量作用域！想法不错，JavaScript 1.7也引入了let语句来做这件事。但是，with会产生无法预想的后果，举例：</p>
<pre>var a = '';
var obj = {b: 'b'};
with(obj) {
 a = b;
}
alert(a); // result: 'b'</pre>
<p>这里的a又变成外部变量了！除了这种诡异的事情之外，with语句的执行速度相对来说是非常缓慢的。所以结论就是，想要提高程序的鲁棒性，就不要用with。</p>
<p><strong>10. 不要用eval</strong></p>
<p>eval可以把一段字符串当作js代码来执行。eval经常被一些新手拿来用，例如：</p>
<pre>eval("value = obj." + key + ";");</pre>
<p>其实他完全可以：</p>
<pre>value = obj["key"];</pre>
<p>eval执行的时候会启用js解释器来执行这一小片代码，速度会慢很多。除此之外，程序的可调试性、可维护性大大降低。类eval的语句还有：</p>
<pre>window.setTimeout("var i = 0", 1000);</pre>
<pre>var sum = new Function("x", "y", "return x+y");</pre>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/make-your-javascript-robust.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web应用程序的beta精神</title>
		<link>http://jsfox.cn/blog/javascript/is-your-web-app-beta.html</link>
		<comments>http://jsfox.cn/blog/javascript/is-your-web-app-beta.html#comments</comments>
		<pubDate>Thu, 09 Jul 2009 14:59:38 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[Gmail]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=61</guid>
		<description><![CDATA[Gmail的logo上终于没有了Beta字样，于此同时，Google Calendar，Google Docs也脱离了beta。Gmail长达七年之久的开发与测试终于结束。
从2004年的愚人节到现在，Gmail一直beta着。在此期间，Gmail小组又加入了很多创新性、革命性的东西在里面。例如加入了Gtalk，让大家在网页上聊天，甚至后来在网页上视频通话；加入了pop邮件的功能；使用long polling来实时获取新邮件；创新性地用标签，而不是文件夹来分类邮件。这些都是之前的网页开发者很难想象、很难做到的。
不过，更值得一提的是web应用程序的beta精神。Web App和桌面程序不同，有很多因素会影响其稳定性。例如网络环境，例如浏览器的兼容性和浏览器设置等等。事实上JavaScript本身就是一个设计上存在缺陷的语言，浏览器对它的支持也不尽相同，而CSS在不同浏览器下的差异更是让我们费尽脑子。这些因素都让我们无法理直气壮地说自己的web程序没有问题。一个复杂的网页程序，在Firefox下运行正常了，你敢说在IE5.5下运行也正常？你敢说在Konqueror下显示和运行都没有问题？大概正因如此，Gmail一直都没有脱离beta。也就是说，上个世纪的浏览器大战造成的兼容性问题，折磨了Gmail整整7年啊。
关于对浏览器的支持，Yahoo!有他的GBS表，也就是Graded Browser Support，很被国外的开发者认可（btw前一段时间刚刚drop掉了IE6 on Windows2000，让我倍感欣慰，说明XP下也不远了！）。
（ 图片来源，Yahoo! UI Library）
我认为可以用这个表格当作一个web程序可称为正式版的参考。不知道Google是不是也用的这个表格，或者有一个类似的chart。无论如何，Gmail beta 5年告诉我们，一个web应用程序，想要说自己是正式版，很难。
]]></description>
			<content:encoded><![CDATA[<p>Gmail的logo上终于没有了Beta字样，于此同时，Google Calendar，Google Docs也脱离了beta。Gmail长达<a href="http://www.techcrunch.com/2008/06/06/the-evolution-of-pre-launch-gmail-in-screenshots/" target="_blank">七年之久</a>的开发与测试终于结束。</p>
<div id="attachment_64" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2009/07/gmail3.jpg"><img class="size-medium wp-image-64" title="Gmail最初设计稿的其中一张" src="http://jsfox.cn/blog/wp-content/uploads/2009/07/gmail3-300x222.jpg" alt="Gmail最初设计稿的其中一张" width="300" height="222" /></a><p class="wp-caption-text">Gmail最初设计稿的其中一张（图片来源：TechCrunch）</p></div>
<p>从2004年的愚人节到现在，Gmail一直beta着。在此期间，Gmail小组又加入了很多创新性、革命性的东西在里面。例如加入了Gtalk，让大家在网页上聊天，甚至后来在网页上视频通话；加入了pop邮件的功能；使用long polling来实时获取新邮件；创新性地用标签，而不是文件夹来分类邮件。这些都是之前的网页开发者很难想象、很难做到的。</p>
<p>不过，更值得一提的是web应用程序的beta精神。Web App和桌面程序不同，有很多因素会影响其稳定性。例如网络环境，例如浏览器的兼容性和浏览器设置等等。事实上JavaScript本身就是一个设计上存在缺陷的语言，浏览器对它的支持也不尽相同，而CSS在不同浏览器下的差异更是让我们费尽脑子。这些因素都让我们无法理直气壮地说自己的web程序没有问题。一个复杂的网页程序，在Firefox下运行正常了，你敢说在IE5.5下运行也正常？你敢说在Konqueror下显示和运行都没有问题？大概正因如此，Gmail一直都没有脱离beta。也就是说，上个世纪的浏览器大战造成的兼容性问题，折磨了Gmail整整7年啊。<span id="more-61"></span></p>
<p style="text-align: left;">关于对浏览器的支持，Yahoo!有他的GBS表，也就是Graded Browser Support，很被国外的开发者认可（btw前一段时间刚刚drop掉了IE6 on Windows2000，让我倍感欣慰，说明XP下也不远了！）。</p>
<div id="attachment_63" class="wp-caption aligncenter" style="width: 379px"><a href="http://developer.yahoo.com/yui/articles/gbs/"><img class="size-full wp-image-63" title="YUI Graded Browser Support Chart" src="http://jsfox.cn/blog/wp-content/uploads/2009/07/yui-gbs.png" alt="YUI Graded Browser Support Chart" width="369" height="311" /></a><p class="wp-caption-text">YUI Graded Browser Support Chart</p></div>
<p>（ 图片来源，Yahoo! UI Library）</p>
<p>我认为可以用这个表格当作一个web程序可称为正式版的参考。不知道Google是不是也用的这个表格，或者有一个类似的chart。无论如何，Gmail beta 5年告诉我们，一个web应用程序，想要说自己是正式版，很难。</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/is-your-web-app-beta.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>由IE一例处理comment节点的bug得到的结论</title>
		<link>http://jsfox.cn/blog/javascript/ie-comment-element-bug.html</link>
		<comments>http://jsfox.cn/blog/javascript/ie-comment-element-bug.html#comments</comments>
		<pubDate>Thu, 09 Jul 2009 12:05:18 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[HTML]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=29</guid>
		<description><![CDATA[近期处理一个项目，需要“翻译”页面的注释节点。功能在Firefox下一切正常，项目进行非常顺利。拿到IE全系列下，却非常不正常，把注释翻译成ELEMENT Node，页面立刻飞掉。检查不出来原因，抓狂了好几天。
后来发现，问题出在IE渲染li的时候。我们的项目里，有时候要求注释节点需要插入在li的后面。虽然这不太标准，但是实际应用中，也是没办法的事。IE6+会把注释节点包进li里面，真是无语。
例如页面上的代码：
&#60;ul id="test"&#62;
  &#60;!-- comment_begin --&#62;
  &#60;li&#62;asdf&#60;/li&#62;
  &#60;li&#62;asdf&#60;/li&#62;
  &#60;li&#62;asdf&#60;/li&#62;
  &#60;!-- comment_end --&#62;
&#60;/ul&#62;
试试document.getElementById(&#8220;test&#8221;).innerHTML，弹出：
&#60;!-- comment_begin --&#62;
&#60;LI&#62;asdf
&#60;LI&#62;asdf
&#60;LI&#62;asdf &#60;!-- comment_end --&#62;&#60;/LI&#62;

用IE8的开发者工具，也能看到同样的效果。IE其实是用这个代码来渲染页面的。最后的解决办法只好先“预处理”一下，把注释节点挪出来，大概是这样：
var lis = document.getElementsByTagName("li");
for (var i = 0, l = lis.length; i &#60; l; i++) {
  if (lis[i].lastChild.nodeType === \8) {
    lis[i].parentNode.appendChild(lis[i].lastChild);
  }
}
这个bug说明一个问题，IE系列浏览器，包括IE8，内部的渲染还是使用的陈旧的HTML渲染方式，哪怕页面的文档类型DOCTYPE是xhtml。像这次遇到的问题，真是很难发现。IE浏览器真是无端耗费我们的青春啊！
]]></description>
			<content:encoded><![CDATA[<p>近期处理一个项目，需要“翻译”页面的注释节点。功能在Firefox下一切正常，项目进行非常顺利。拿到IE全系列下，却非常不正常，把注释翻译成ELEMENT Node，页面立刻飞掉。检查不出来原因，抓狂了好几天。</p>
<p>后来发现，问题出在IE渲染li的时候。我们的项目里，有时候要求注释节点需要插入在li的后面。虽然这不太标准，但是实际应用中，也是没办法的事。IE6+会把注释节点包进li里面，真是无语。</p>
<p>例如页面上的代码：</p>
<pre>&lt;ul id="test"&gt;
  &lt;!-- comment_begin --&gt;
  &lt;li&gt;asdf&lt;/li&gt;
  &lt;li&gt;asdf&lt;/li&gt;
  &lt;li&gt;asdf&lt;/li&gt;
  &lt;!-- comment_end --&gt;
&lt;/ul&gt;</pre>
<p>试试document.getElementById(&#8220;test&#8221;).innerHTML，弹出：</p>
<pre>&lt;!-- comment_begin --&gt;
&lt;LI&gt;asdf
&lt;LI&gt;asdf
&lt;LI&gt;asdf &lt;!-- comment_end --&gt;&lt;/LI&gt;</pre>
<p><span id="more-29"></span></p>
<p>用IE8的开发者工具，也能看到同样的效果。IE其实是用这个代码来渲染页面的。最后的解决办法只好先“预处理”一下，把注释节点挪出来，大概是这样：</p>
<pre>var lis = document.getElementsByTagName("li");
for (var i = 0, l = lis.length; i &lt; l; i++) {
  if (lis[i].lastChild.nodeType === \8) {
    lis[i].parentNode.appendChild(lis[i].lastChild);
  }
}</pre>
<p>这个bug说明一个问题，IE系列浏览器，包括IE8，内部的渲染还是使用的陈旧的HTML渲染方式，哪怕页面的文档类型DOCTYPE是xhtml。像这次遇到的问题，真是很难发现。IE浏览器真是无端耗费我们的青春啊！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/ie-comment-element-bug.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
