<?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>葵中剑&#039;s Blog - SwordAir.com</title>
	<atom:link href="http://www.swordair.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.swordair.com/blog</link>
	<description>Embracing the dream I keep going forward, despite of a glorious death.</description>
	<lastBuildDate>Mon, 14 May 2012 07:02:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>nodejs目录遍历</title>
		<link>http://www.swordair.com/blog/2012/05/923/</link>
		<comments>http://www.swordair.com/blog/2012/05/923/#comments</comments>
		<pubDate>Mon, 14 May 2012 07:01:11 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[Note]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=923</guid>
		<description><![CDATA[近期解决一个问题的时候，需要一个简单的目录遍历。目录遍历挺常见，操作一个文件夹里的所有文件，替换或者添加删除某些东西是非常普遍的操作。由于 nodejs 本身并没有提供类似的API，所以这部分就得由自己实现。

虽然没有直接的遍历API，但是 nodejs 的文件操作也已经非常便利，用 <code>fs.readdir</code> 和 <code>fs.stat</code> 这两个API的组合就能达到目的。]]></description>
			<content:encoded><![CDATA[<p>近期解决一个问题的时候，需要一个简单的目录遍历。目录遍历挺常见，操作一个文件夹里的所有文件，替换或者添加删除某些东西是非常普遍的操作。由于 nodejs 本身并没有提供类似的API，所以这部分就得由自己实现。</p>
<p>虽然没有直接的遍历API，但是 nodejs 的文件操作也已经非常便利，用 <code>fs.readdir</code> 和 <code>fs.stat</code> 这两个API的组合就能达到目的。</p>
<p>出于参半程序员的懒惰的劣根性，其实在这之前我也搜索过看看是否有现成的可以拿来用，也确实有这种完善的 module，比如 <a href="https://github.com/coolaj86/node-walk">node-walk</a>，我试用过后觉得还是非常不错的：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> walk <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'walk'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	files <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> getFileList<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> walker  <span style="color: #339933;">=</span> walk.<span style="color: #660066;">walk</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/dirName'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> followLinks<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	walker.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'file'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>root<span style="color: #339933;">,</span> stat<span style="color: #339933;">,</span> next<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    files.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>root <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> stat.<span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    next<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	walker.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'end'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>files<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>files<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>但是我使用其同步方法的时候并未达到同步的效果，不知是我哪里用法有问题。后来因为寻找原因的时间太长也就只好先放弃。其实我只是需要一个简单的同步遍历，所以用module就显得复杂化了。当然搜索过程中也找到了几个简单实现，但代码搞的复杂了，明明递归能轻易做到的情况下却用了数组循环&#8230;</p>
<p>所以最后吧，还是得自己写：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> fs <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	fileList <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> walk<span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> dirList <span style="color: #339933;">=</span> fs.<span style="color: #660066;">readdirSync</span><span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	dirList.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>fs.<span style="color: #660066;">statSync</span><span style="color: #009900;">&#40;</span>path <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">isDirectory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			walk<span style="color: #009900;">&#40;</span>path <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #000066; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
			fileList.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>path <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
walk<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/dirName'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>fileList<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>递归调用 <code>walk</code> 遍历一个路径里所有的目录并将文件添加到文件列表里。这么做的结果是典型的深度优先，但往往程序往往对结果列表的序列有层次上的要求。所以如果按照广度优先的话，代码上可能需要略微调整一下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> walk<span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> dirList <span style="color: #339933;">=</span> fs.<span style="color: #660066;">readdirSync</span><span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	dirList.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>fs.<span style="color: #660066;">statSync</span><span style="color: #009900;">&#40;</span>path <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">isFile</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			fileList.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>path <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	dirList.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>fs.<span style="color: #660066;">statSync</span><span style="color: #009900;">&#40;</span>path <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">isDirectory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			walk<span style="color: #009900;">&#40;</span>path <span style="color: #339933;">+</span> <span style="color: #3366CC;">'/'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>调整的也不多，只是每次需要先push所有的文件，然后再依次遍历子目录。</p>
<p>偷鸡不成蚀把米，想着偷懒，结果绕个圈回来还是自己写来的快——这么点懒都要偷，真是无药可救了。</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>2012/02/14 -- <a href="http://www.swordair.com/blog/2012/02/797/" title="NodeJS之始">NodeJS之始</a></li><li>2012/05/03 -- <a href="http://www.swordair.com/blog/2012/05/901/" title="jsdom——node.js的DOM">jsdom——node.js的DOM</a></li><li>2012/03/21 -- <a href="http://www.swordair.com/blog/2012/03/796/" title="JavaScript vs jQuery 元素集合">JavaScript vs jQuery 元素集合</a></li><li>2012/01/18 -- <a href="http://www.swordair.com/blog/2012/01/743/" title="jQuery plugin &#8211; Scroll to Top">jQuery plugin &#8211; Scroll to Top</a></li><li>2011/10/25 -- <a href="http://www.swordair.com/blog/2011/10/714/" title="function与感叹号">function与感叹号</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/05/923/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>昆腾2G硬盘拆解</title>
		<link>http://www.swordair.com/blog/2012/05/907/</link>
		<comments>http://www.swordair.com/blog/2012/05/907/#comments</comments>
		<pubDate>Sat, 12 May 2012 10:07:07 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[DIY]]></category>
		<category><![CDATA[Quantum]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=907</guid>
		<description><![CDATA[拿出这么一块硬盘并非说明了自己使用计算机的时间，而恰恰只能说明自己是多么的穷苦。我在上了大学之后才有了第一台电脑，但是很快因为在学校呆的时间比较长所以就把机器借给别人使用。后来，我用废旧的零件组装了第二台机器，于是这块硬盘被我从二手市场里论斤买来，然后装进了一台奔三的机器里。

那时的主流硬盘尺寸为160G，CPU为奔四2.8G。所以这块2G的昆腾即使配上奔三依然短板，因为奔三时代的主流硬盘容量就已经是30G了。所以这块昆腾2G硬盘，从现在的角度来看，确实有一些年头了。电路板上的灰尘向我们展示了它这十几年来的沧桑——而就是这么一块略感古董的5.25寸硬盘，最后还是被我拆了。其实这块硬盘除了有几处坏道被我屏蔽以外，时至今日都能正常工作。里面是一个98精简版系统，和一个叫心跳回忆的有约会失败BUG的游戏，然后，就再无其他了。

<div class="img-border">
<img class="aligncenter size-full wp-image-908" src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_01.jpg" alt="quantum_2g_dismantling_01" width="640" height="480" />
</div>]]></description>
			<content:encoded><![CDATA[<p>拿出这么一块硬盘并非说明了自己使用计算机的时间，而恰恰只能说明自己是多么的穷苦。我在上了大学之后才有了第一台电脑，但是很快因为在学校呆的时间比较长所以就把机器借给别人使用。后来，我用废旧的零件组装了第二台机器，于是这块硬盘被我从二手市场里论斤买来，然后装进了一台奔三的机器里。</p>
<p>那时的主流硬盘尺寸为160G，CPU为奔四2.8G。所以这块2G的昆腾即使配上奔三依然短板，因为奔三时代的主流硬盘容量就已经是30G了。所以这块昆腾2G硬盘，从现在的角度来看，确实有一些年头了。电路板上的灰尘向我们展示了它这十几年来的沧桑——而就是这么一块略感古董的5.25寸硬盘，最后还是被我拆了。其实这块硬盘除了有几处坏道被我屏蔽以外，时至今日都能正常工作。里面是一个98精简版系统，和一个叫心跳回忆的有约会失败BUG的游戏，然后，就再无其他了。</p>
<div class="img-border">
<img class="aligncenter size-full wp-image-908" src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_01.jpg" alt="quantum_2g_dismantling_01" width="640" height="480" />
</div>
<p>我拆过很多硬盘，当然这块仍然是最古老的。现代的3.5寸的硬盘在外观看起来要更紧密。并且相对于现在硬盘上非常普遍的“六星”螺丝，这块昆腾用的还是十字螺丝。</p>
<div class="img-border">
<img class="aligncenter size-full wp-image-909" src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_02.jpg" alt="quantum_2g_dismantling_02" width="640" height="480" />
</div>
<p>98年1月21日，到现在为止，它已经有了14.4年的历史了。比起现在的贴纸，这货的参数完全印刷在盘体上。</p>
<div class="img-border">
<img class="aligncenter size-full wp-image-910" src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_03.jpg" alt="quantum_2g_dismantling_03" width="640" height="480" />
</div>
<p>拧下了所以周围的十字螺丝后，终于在中间看到了这颗唯一的六星螺丝。拧开的同时可以听到硬盘边发泡密封慢慢裂开，同时空气漏进去盘体而发出的丝丝声。</p>
<div class="img-border">
<img class="aligncenter size-full wp-image-911" src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_04.jpg" alt="quantum_2g_dismantling_04" width="640" height="480" />
</div>
<p>打开盘体，光洁的盘片映入眼帘。硕大的盘片比起3.5寸硬盘的大出很多，所以视觉冲击力自然也大出许多。</p>
<div class="img-border">
<img class="aligncenter size-full wp-image-912" src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_05.jpg" alt="quantum_2g_dismantling_05" width="640" height="480" />
</div>
<p>磁头的特写，比起现在的硬盘，可能这部分显得就不怎么精致了。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_06.jpg" alt="quantum_2g_dismantling_06" width="640" height="480" class="aligncenter size-full wp-image-913" />
</div>
<p>和其他硬盘一样，光滑如镜子。镜中反射出来的是我种的矮向日葵。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_07.jpg" alt="quantum_2g_dismantling_07" width="640" height="480" class="aligncenter size-full wp-image-914" />
</div>
<p>开盘后的全貌。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_08.jpg" alt="quantum_2g_dismantling_08" width="640" height="480" class="aligncenter size-full wp-image-915" />
</div>
<p>线圈在镜头里很整齐，旁边的塑料小件顿时让我明白这货“敲盘”声音为什么这么响了。随处可见的大型十字螺丝，总是显露出粗狂的风格感，</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_09.jpg" alt="quantum_2g_dismantling_09" width="640" height="480" class="aligncenter size-full wp-image-916" />
</div>
<p>5.25寸和3.5寸盘片的对比，当真是差了很多啊。不过容量差的也很多，2G VS &#8230; 30G &#8230; 有一种时代进步创生出来的悲凉。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_10.jpg" alt="quantum_2g_dismantling_10" width="640" height="480" class="aligncenter size-full wp-image-917" />
</div>
<p>和现在硬盘里只有一块磁铁不同的是，这货有两块。顺便说一下，很多人想着要把这块磁铁从金属片上拆下来。其实这个磁铁是用一点点胶水粘在上面的。所以单单位移是去不下来的。最好的办法，是用老虎钳或者台钳先将金属片弄弯，然后让磁铁的边缘产生一些空隙，最后塞进薄一点的钢尺就能慢慢分离开了，并不需要很费力。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_11.jpg" alt="quantum_2g_dismantling_11" width="640" height="480" class="aligncenter size-full wp-image-918" />
</div>
<p>拆完了的硬盘，光秃秃的马达和盘壳，还是那么的沧桑。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/quantum_2g_dismantling_12.jpg" alt="quantum_2g_dismantling_12" width="640" height="480" class="aligncenter size-full wp-image-919" />
</div>
<p>每次拆硬盘，都感觉像是拆解一件精密的工艺品。各种铝质的小件做工看的我赏心悦目，很多零件都不舍得扔掉，但即使就这么放着也着实无用武之地。掏空的硬盘算是一个藏私房钱的好地方哟~谁能想到，计算机里装着的是一块肚子空空的硬盘，里面没有光亮的盘片，但也许有毛爷爷！</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>2011/10/19 -- <a href="http://www.swordair.com/blog/2011/10/704/" title="十年PCDIY">十年PCDIY</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/05/907/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>修复A590IS残缺的电池仓扣</title>
		<link>http://www.swordair.com/blog/2012/05/903/</link>
		<comments>http://www.swordair.com/blog/2012/05/903/#comments</comments>
		<pubDate>Sat, 05 May 2012 13:41:52 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[DIY]]></category>
		<category><![CDATA[A590IS]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=903</guid>
		<description><![CDATA[我的相机——Canon PowerShot A590IS 我写过多次，可惜它命运多舛，这次又成了我的博客内容。在 <a href="http://www.swordair.com/blog/2012/02/812/">修复A590IS电池报警缺陷问题</a> 里，我解决了电池容量误报的问题。今天，我修理的是折断的电池仓扣

A590IS 的一大缺点就是机身太差，强度实在有点弱不禁风。特别是电池仓的扣子，一次跌落就会轻而易举地折断。我的相机的这个在前面板的挂钩一样的钩子很早就折断了，这个扣子的材料和固定用的另一个主机身的扣子的材料不同，很脆，所以才异常脆弱。以前，因为一直有完好的机身上的扣子挂住电池仓盖，所以勉强使用至今。在修复了电池误报问题后，理应不再受电池困扰的我却仍偶尔遇到电量问题，仔细查看在发现是因为缺少一个扣子，电池盖盖不严而总是接触不良。

于是，虽然这是一个坏了很久的地方，但既然影响使用就应该想想办法。

<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/fix_a590is_battery_box_2.jpg" alt="fix_a590is_battery_box_2" width="640" height="240" class="aligncenter size-full wp-image-905" />
</div>]]></description>
			<content:encoded><![CDATA[<p>我的相机——Canon PowerShot A590IS 我写过多次，可惜它命运多舛，这次又成了我的博客内容。在 <a href="http://www.swordair.com/blog/2012/02/812/">修复A590IS电池报警缺陷问题</a> 里，我解决了电池容量误报的问题。今天，我修理的是折断的电池仓扣</p>
<p>A590IS 的一大缺点就是机身太差，强度实在有点弱不禁风。特别是电池仓的扣子，一次跌落就会轻而易举地折断。我的相机的这个在前面板的挂钩一样的钩子很早就折断了，这个扣子的材料和固定用的另一个主机身的扣子的材料不同，很脆，所以才异常脆弱。以前，因为一直有完好的机身上的扣子挂住电池仓盖，所以勉强使用至今。在修复了电池误报问题后，理应不再受电池困扰的我却仍偶尔遇到电量问题，仔细查看在发现是因为缺少一个扣子，电池盖盖不严而总是接触不良。</p>
<p>于是，虽然这是一个坏了很久的地方，但既然影响使用就应该想想办法。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/fix_a590is_battery_box_2.jpg" alt="fix_a590is_battery_box_2" width="640" height="240" class="aligncenter size-full wp-image-905" />
</div>
<p>扣子坏的很彻底，整个折断了。这个位置非常难办，很难找到支点。由于这个损坏的钩子受力，所以用胶水是不靠谱的。我理所当然地第一想到的办法是更换整个前面板，于是淘宝和google了一下，发觉这个位置损坏的用户还真不少，很多人求购整个前面板，仅仅为了修复这个小小的钩子。可惜这款机型实在老了点，淘宝上只有一家店出手这种面板，但是要价110，坑爹啊！一部新机的当前价格都只有500，一个塑料壳子就要110？果断放弃。</p>
<p>只好自己另想办法。在电池仓的外面加装固定杆？还是整个做一个新的套子？一开始的想法太复杂，后来观察了一下电池盖，发现卡口有近四分之一指甲的大小，于是灵机一动：这足够放的下一个螺丝。于是我翻出以前拆机的各种螺丝零件，里面还有儿时玩过的四驱车配件，在凌乱的一堆螺丝里找合适的。不能太长也不能太短，螺帽不能太大也不能太小，找了一会终于找到一个合适的，于是立即开工。</p>
<p>先把折断的扣子留下的部分用锯子锯平，用小刀修一下。然后从柜子里挖出电磨机，装上最小号的钻头，对准卡口钻一个小洞。然后在放上螺丝，慢慢捻入，直到捻穿。整个过程不到10分钟，装好相机，效果非常好。只是在钻孔时有点倾斜，所以螺帽没有完全对准电池盖上的卡口，有点碰擦。给电磨换上砂轮直接打掉多余的螺帽部分，伴着嘈杂的一段声响，我的A590IS又重获新生了。</p>
<p>修好后，只要不去看，使用起来完全没有感觉。用螺帽代替了折断的卡口，这次应该不会再折断了吧~</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/fix_a590is_battery_box_1.jpg" alt="fix_a590is_battery_box_1" width="640" height="240" class="aligncenter size-full wp-image-904" />
</div>
<p>我只有一部相机，虽然从大学时代开始我就嚷嚷着要买单反，不过数年已过，我仍然只有我的A590IS。其实仔细想象，虽然我喜爱摄影，但是购买单反的投入和产出实在太悬殊，随着时间的推移，越来越理性的消费习惯让我和单反越走越远了。未来可能仍然还是A590IS陪着我，记录着我的生活点滴。它其实还很年轻，才拍了7000张都不到的照片，不完全修好它真心觉得有点可惜。</p>
<p>最后这篇文章里的图片还是A590IS拍摄的，当然拆掉了面板，用裸机拍照的时候按键小到影响了一些稳定性。不过至少不像上次拆电路板那样，无法好好的记录这样一次重生。</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>2012/02/26 -- <a href="http://www.swordair.com/blog/2012/02/812/" title="修复A590IS电池报警缺陷问题">修复A590IS电池报警缺陷问题</a></li><li>2011/10/13 -- <a href="http://www.swordair.com/blog/2011/10/680/" title="以木为戒Ⅱ">以木为戒Ⅱ</a></li><li>2010/07/20 -- <a href="http://www.swordair.com/blog/2010/07/407/" title="A590IS和摄影">A590IS和摄影</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/05/903/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>jsdom——node.js的DOM</title>
		<link>http://www.swordair.com/blog/2012/05/901/</link>
		<comments>http://www.swordair.com/blog/2012/05/901/#comments</comments>
		<pubDate>Thu, 03 May 2012 05:59:37 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[Application]]></category>
		<category><![CDATA[Front-end]]></category>
		<category><![CDATA[System]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[jsdom]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=901</guid>
		<description><![CDATA[最近一周一直在写node，感觉很爽。不过 node 虽好却没有 DOM 还是有很多不方便的地方。好在有 <a rel="external" href="https://github.com/tmpvar/jsdom">jsdom</a> —— 一个 W3C DOM 的 JS 实现。用这玩意相当犀利，它不仅可以将文档解析成 DOM，而且，你还可以用 YUI 或着 jQuery 去操作生成的 DOM。这在从页面中提取数据时格外有用。

虽然在类Unix系统上安装jsdom非常简单，但在window上就要麻烦许多，下面这些依赖还得独立安装。

<ul>
	<li><del><a rel="external" href="https://github.com/TooTallNate/node-gyp">node-gyp</a></del> (nodejs 0.6.13 以上，node-gyp 已经被包含在 npm 中)</li>
	<li><a rel="external" href="http://www.python.org/ftp/python/2.7.3/python-2.7.3.msi">Python</a></li>
	<li><a rel="external" href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express">Microsoft Visual C++ Express 2010</a></li>
</ul>

装完后我赶紧使用了一下：

<pre lang="javascript" line="1">
var jsdom = require('jsdom');
jsdom.env('http://www.swordair.com',['http://localhost/aptana/code/js-lib/jquery-1.7.1.js'],function(errors, window){
	console.log("contents:", window.$("div.blog-update-title").next().html());
});
</pre>

效果妥妥的，无法想象的便利和快捷！]]></description>
			<content:encoded><![CDATA[<p>最近一周一直在写node，感觉很爽。不过 node 虽好却没有 DOM 还是有很多不方便的地方。好在有 <a rel="external" href="https://github.com/tmpvar/jsdom">jsdom</a> —— 一个 W3C DOM 的 JS 实现。用这玩意相当犀利，它不仅可以将文档解析成 DOM，而且，你还可以用 YUI 或着 jQuery 去操作生成的 DOM。这在从页面中提取数据时格外有用。</p>
<p>虽然在类Unix系统上安装jsdom非常简单，但在window上就要麻烦许多，下面这些依赖还得独立安装。</p>
<ul>
<li><del><a rel="external" href="https://github.com/TooTallNate/node-gyp">node-gyp</a></del> (nodejs 0.6.13 以上，node-gyp 已经被包含在 npm 中)</li>
<li><a rel="external" href="http://www.python.org/ftp/python/2.7.3/python-2.7.3.msi">Python</a></li>
<li><a rel="external" href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express">Microsoft Visual C++ Express 2010</a></li>
</ul>
<p>装完后我赶紧使用了一下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> jsdom <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'jsdom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
jsdom.<span style="color: #660066;">env</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http://www.swordair.com'</span><span style="color: #339933;">,</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'http://localhost/aptana/code/js-lib/jquery-1.7.1.js'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errors<span style="color: #339933;">,</span> window<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;contents:&quot;</span><span style="color: #339933;">,</span> window.$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;div.blog-update-title&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>效果妥妥的，无法想象的便利和快捷！</p>
<p><strong>下面是我走的很多弯路，但作为错误信息源保留下来，以便有需要的人能够搜索到并解决他们的问题。</strong></p>
<p>一开始，我就按照 <a rel="external" href="https://github.com/tmpvar/jsdom">jsdom</a> 的 README 直接安装：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">npm install jsdom</pre></td></tr></table></div>

<p>当然，那肯定是不行的。我的系统是xp并且几乎没有安装过什么常用开发工具。结果报错，信息如下：<br />
出现如下错误信息：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">D:\xampp\htdocs\aptana\code\js\nodejs\playground\node_modules\jsdom\node_m
odules\contextify&gt;node &quot;C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bi
n\\..\..\node_modules\node-gyp\bin\node-gyp.js&quot; rebuild
info it worked if it ends with ok
ERR! Error: Python does not seem to be installed
    at failNoPython (C:\Program Files\nodejs\node_modules\npm\node_modules\node-
gyp\lib\configure.js:78:14)
    at Object.oncomplete (C:\Program Files\nodejs\node_modules\npm\node_modules\
node-gyp\lib\configure.js:66:11)
ERR! not ok
npm WARN optional dependency failed, continuing contextify@0.1.2
jsdom@0.2.14 ./node_modules/jsdom
├── cssom@0.2.3
├── request@2.9.202
└── htmlparser@1.7.6</pre></td></tr></table></div>

<p>根据 ERR! Error: Python does not seem to be installed，应该是没有安装Python的缘故。赶紧到官方网站下了Python，2.x.x和3.x.x都装了(后来知道其实用的是Python27)。</p>
<p>在搜索过程中，了解到可能还需要安装 node-gyp，所以顺便把 node-gyp 也一并装上：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">npm install -g node-gyp</pre></td></tr></table></div>

<p>继续 <code>npm install jsdom</code> 安装 jsdom，不过仍然报错：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">D:\xampp\htdocs\aptana\code\js\nodejs\playground\node_modules\jsdom\node_m
odules\contextify&gt;node &quot;C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bi
n\\..\..\node_modules\node-gyp\bin\node-gyp.js&quot; rebuild
info it worked if it ends with ok
info downloading: http://nodejs.org/dist/v0.6.15/node-v0.6.15.tar.gz
info downloading: http://nodejs.org/dist/v0.6.15/node.lib
spawn C:\Python27\python.exe [ 'd:\\Documents and Settings\\jianwang2\\.node-gyp
\\0.6.15\\tools\\gyp_addon',
  'binding.gyp',
  '-ID:\\xampp\\htdocs\\aptana\\code\\js\\nodejs\\playground\\node_modules
\\jsdom\\node_modules\\contextify\\build\\config.gypi',
  '-f',
  'msvs',
  '-G',
  'msvs_version=2010' ]
ERR! Error: Can't find &quot;msbuild.exe&quot;. Do you have Microsoft Visual Studio C++ 20
10 installed?
    at Object.oncomplete (C:\Program Files\nodejs\node_modules\npm\node_modules\
node-gyp\lib\build.js:105:20)
ERR! not ok
npm WARN optional dependency failed, continuing contextify@0.1.2
jsdom@0.2.14 ./node_modules/jsdom
├── cssom@0.2.3
├── request@2.9.202
└── htmlparser@1.7.6</pre></td></tr></table></div>

<p>错误信息 ERR! Error: Can&#8217;t find &#8220;msbuild.exe&#8221;. Do you have Microsoft Visual Studio C++ 2010 installed? 显示无法找到编译器 msbuild.exe，并询问我是否安装有 Visual Studio C++ 2010。我擦，当然没有！</p>
<p>这里我偷懒了一下(后来证明是个错误)，我知道 .Net 4.0 里包含有 msbuild.exe，所以直接到微软官方下载了 .Net 4.0。安装，运行 <code>npm install jsdom</code>，还是不行：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">D:\xampp\htdocs\aptana\code\js\nodejs\playground\node_modules\jsdom\node_m
odules\contextify&gt;node &quot;C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bi
n\\..\..\node_modules\node-gyp\bin\node-gyp.js&quot; rebuild
info it worked if it ends with ok
spawn C:\Python27\python.exe [ 'd:\\Documents and Settings\\jianwang2\\.node-gyp
\\0.6.15\\tools\\gyp_addon',
  'binding.gyp',
  '-ID:\\xampp\\htdocs\\aptana\\code\\js\\nodejs\\playground\\node_modules
\\jsdom\\node_modules\\contextify\\build\\config.gypi',
  '-f',
  'msvs',
  '-G',
  'msvs_version=2010' ]
spawn C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild.exe [ 'build/binding
.sln',
  '/clp:Verbosity=minimal',
  '/nologo',
  '/p:Configuration=Release;Platform=Win32' ]
D:\xampp\htdocs\aptana\code\js\nodejs\playground\node_modules\jsdom\node_
modules\contextify\build\contextify.vcxproj(1,685): error MSB4019: The imported
 project &quot;D:\Microsoft.Cpp.Default.props&quot; was not found. Confirm that the path
in the &lt;Import&gt; declaration is correct, and that the file exists on disk.
ERR! Error: `C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild.exe` failed w
ith exit code: 1
    at Array.0 (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\l
ib\build.js:176:25)
    at EventEmitter._tickCallback (node.js:192:40)
ERR! not ok
npm WARN optional dependency failed, continuing contextify@0.1.2
jsdom@0.2.14 ./node_modules/jsdom
├── cssom@0.2.3
├── request@2.9.202
└── htmlparser@1.7.6</pre></td></tr></table></div>

<p>信息显示 msbuild.exe 被找到，不过编译失败。这次是报 error MSB4019: The imported project &#8220;D:\Microsoft.Cpp.Default.props&#8221; was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.</p>
<p>好吧，看来还是得安上 Microsoft Visual Studio C++ 2010。到官网下了 <a rel="external" href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express">Microsoft Visual C++ Express 2010</a>，一阵漫长的等待后，再次运行安装jsdom，终于成功：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">D:\xampp\htdocs\aptana\code\js\nodejs\playground\node_modules\jsdom\node_m
odules\contextify&gt;node &quot;C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bi
n\\..\..\node_modules\node-gyp\bin\node-gyp.js&quot; rebuild
info it worked if it ends with ok
spawn C:\Python27\python.exe [ 'd:\\Documents and Settings\\jianwang2\\.node-gyp
\\0.6.15\\tools\\gyp_addon',
  'binding.gyp',
  '-ID:\\xampp\\htdocs\\aptana\\code\\js\\nodejs\\playground\\node_modules
\\jsdom\\node_modules\\contextify\\build\\config.gypi',
  '-f',
  'msvs',
  '-G',
  'msvs_version=2010' ]
spawn C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild.exe [ 'build/binding
.sln',
  '/clp:Verbosity=minimal',
  '/nologo',
  '/p:Configuration=Release;Platform=Win32' ]
  contextify.cc
d:\Documents and Settings\jianwang2\.node-gyp\0.6.15\src\node_object_wrap.h(57)
: warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent&lt;T&gt;' needs
to have dll-interface to be used by clients of class 'node::ObjectWrap' [D:\xam
pp\htdocs\aptana\code\js\nodejs\playground\node_modules\jsdom\node_module
s\contextify\build\contextify.vcxproj]
          with
          [
              T=v8::Object
          ]
d:\Program Files\Microsoft Visual Studio 10.0\VC\include\xlocale(323): warning
C4530: C++ exception handler used, but unwind semantics are not enabled. Specif
y /EHsc [D:\xampp\htdocs\aptana\code\js\nodejs\playground\node_modules\js
dom\node_modules\contextify\build\contextify.vcxproj]
C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(990,5):
warning MSB8012: TargetPath(D:\xampp\htdocs\aptana\code\js\nodejs\playgro
und\node_modules\jsdom\node_modules\contextify\build\Release\contextify.dll) do
es not match the Linker's OutputFile property value (D:\xampp\htdocs\aptana\swo
rd-code\js\nodejs\playground\node_modules\jsdom\node_modules\contextify\build\R
elease\contextify.node). This may cause your project to build incorrectly. To c
orrect this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) pr
operty values match the value specified in %(Link.OutputFile). [D:\xampp\htdocs
\aptana\code\js\nodejs\playground\node_modules\jsdom\node_modules\context
ify\build\contextify.vcxproj]
C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(991,5):
warning MSB8012: TargetExt(.dll) does not match the Linker's OutputFile propert
y value (.node). This may cause your project to build incorrectly. To correct t
his, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property v
alues match the value specified in %(Link.OutputFile). [D:\xampp\htdocs\aptana\
code\js\nodejs\playground\node_modules\jsdom\node_modules\contextify\buil
d\contextify.vcxproj]
     Creating library D:\xampp\htdocs\aptana\code\js\nodejs\playground\no
  de_modules\jsdom\node_modules\contextify\build\Release\contextify.lib and obj
  ect D:\xampp\htdocs\aptana\code\js\nodejs\playground\node_modules\jsdom
  \node_modules\contextify\build\Release\contextify.exp
  Generating code
  Finished generating code
  contextify.vcxproj -&gt; D:\xampp\htdocs\aptana\code\js\nodejs\playground\
  node_modules\jsdom\node_modules\contextify\build\Release\contextify.dll
info done ok
jsdom@0.2.14 ./node_modules/jsdom
├── cssom@0.2.3
├── request@2.9.202
├── htmlparser@1.7.6
└── contextify@0.1.2 (bindings@0.3.0)</pre></td></tr></table></div>

<p>虽然有几个警告，不过看到 info done ok，说明安装完成了。至此绕了一个大圈终于装完 jsdom。其实也是后来才发现的，自己没仔细看 node-gyp 的说明，人家写的清清楚楚的：</p>
<ul>
<li>Python (v2.7.2 recommended, v3.x.x not yet supported)</li>
<li>Microsoft Visual C++ (Express version works well)</li>
</ul>
<p>所以以后万不可盲目，说明先看看清楚，走别人的弯路，让别人无路可走～</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>2012/05/14 -- <a href="http://www.swordair.com/blog/2012/05/923/" title="nodejs目录遍历">nodejs目录遍历</a></li><li>2012/02/14 -- <a href="http://www.swordair.com/blog/2012/02/797/" title="NodeJS之始">NodeJS之始</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/05/901/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>特修斯之车</title>
		<link>http://www.swordair.com/blog/2012/05/898/</link>
		<comments>http://www.swordair.com/blog/2012/05/898/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 16:44:19 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[DIY]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[forever]]></category>
		<category><![CDATA[Theseus]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=898</guid>
		<description><![CDATA[标题杜撰自特修斯之船（<a rel="external" href="http://en.wikipedia.org/wiki/Ship_of_Theseus">Ship of Theseus</a>）,一个著名的古老的哲学问题。wiki上这么描述：

<blockquote><p>Plutarch thus questions whether the ship would remain the same if it were entirely replaced, piece by piece. Centuries later, the philosopher Thomas Hobbes introduced a further puzzle, wondering: what would happen if the original planks were gathered up after they were replaced, and used to build a second ship. Which ship, if either, is the original Ship of Theseus?</p></blockquote>

在国内，也随着诸如十个著名的悖论之类的文章流传甚广：

<blockquote><p>一艘可以在海上航行几百年的船，归功于不间断的维修和替换部件。只要一块木板腐烂了，它就会被替换掉，以此类推，直到所有的功能部件都不是最开始的那些了。问题是，最终产生的这艘船是否还是原来的那艘特修斯之船，还是一艘完全不同的船？如果不是原来的船，那么在什么时候它不再是原来的船了？哲学家Thomas Hobbes后来对此进来了延伸，如果用特修斯之船上取下来的老部件来重新建造一艘新的船，那么两艘船中哪艘才是真正的特修斯之船？</p></blockquote>

还在大学时代其实就对这类哲学问题非常着迷，不过后来现实生活的冲击里渐渐觉得哲学，其实还是适合做老年人的玩物。这个特修斯之船的问题从当年听到后就一直没有想通，直到自己遇到这样的事——十多年的老永久自行车，一辆伴着我从初中直到大学毕业的自行车，在经历岁月洗礼后，被大修了数次——现在它是否还是我的爱车？如果不是，从何时开始的？

<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/theseus_forever_bike_1.jpg" alt="theseus forever bike 1" width="640" height="240" class="aligncenter size-full wp-image-899" />
</div>]]></description>
			<content:encoded><![CDATA[<p>标题杜撰自特修斯之船（<a rel="external" href="http://en.wikipedia.org/wiki/Ship_of_Theseus">Ship of Theseus</a>）,一个著名的古老的哲学问题。wiki上这么描述：</p>
<blockquote><p>Plutarch thus questions whether the ship would remain the same if it were entirely replaced, piece by piece. Centuries later, the philosopher Thomas Hobbes introduced a further puzzle, wondering: what would happen if the original planks were gathered up after they were replaced, and used to build a second ship. Which ship, if either, is the original Ship of Theseus?</p>
</blockquote>
<p>在国内，也随着诸如十个著名的悖论之类的文章流传甚广：</p>
<blockquote><p>一艘可以在海上航行几百年的船，归功于不间断的维修和替换部件。只要一块木板腐烂了，它就会被替换掉，以此类推，直到所有的功能部件都不是最开始的那些了。问题是，最终产生的这艘船是否还是原来的那艘特修斯之船，还是一艘完全不同的船？如果不是原来的船，那么在什么时候它不再是原来的船了？哲学家Thomas Hobbes后来对此进来了延伸，如果用特修斯之船上取下来的老部件来重新建造一艘新的船，那么两艘船中哪艘才是真正的特修斯之船？</p>
</blockquote>
<p>还在大学时代其实就对这类哲学问题非常着迷，不过后来现实生活的冲击里渐渐觉得哲学，其实还是适合做老年人的玩物。这个特修斯之船的问题从当年听到后就一直没有想通，直到自己遇到这样的事——十多年的老永久自行车，一辆伴着我从初中直到大学毕业的自行车，在经历岁月洗礼后，被大修了数次——现在它是否还是我的爱车？如果不是，从何时开始的？</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/theseus_forever_bike_1.jpg" alt="theseus forever bike 1" width="640" height="240" class="aligncenter size-full wp-image-899" />
</div>
<p>这辆老车十几年来已经换过数次零件，但因为使用频繁而粗暴，各个部件又几乎都快损耗殆尽——脚踏板碎了，钢圈弯了，座椅破了，刹车失灵了&#8230;也许是到该换车的时候了，我在晚上搜索了数晚，在数个等级的自行车里徘徊——吉安特？不，还是美利达勇士吧&#8230;不，公爵更好？不，太贵了，还是继续国产永久吧&#8230;最后在自己折磨自己数日后，修车的年头居然又占了上风。</p>
<p>于是我又想起了特修斯之船，并急于得出一个结论，这辆老车还是不是它自己？我的天，我干嘛这么蛋疼！</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/05/theseus_forever_bike_2.jpg" alt="theseus forever bike 2" width="640" height="240" class="aligncenter size-full wp-image-900" />
</div>
<p>但很快，我就找到了答案。</p>
<p>当我摆弄着这辆老车的数个苍老的元件的时候，各种记忆就像泉水一样从心头涌出来。十几年风里来雨里去，忍受我暴力的骑行，每次我都把它重新修好，也许不知不觉间，它的诸多零件早已经不再是原配，但陪伴在我身边的这十几年，无疑是它存在的证明。即使所有的零件都面目全非，但总有一些东西被保留，被继承，至少其名存于认识它的人的记忆里。</p>
<p>十几年后，甚至是几十年后，朋友相聚，也许大家的变化都很大。然而，<strong>船依旧是船，车依旧是车，人也依旧是人</strong>。那个你心里的人，也依旧还是她。</p>
<p>淘宝买回新的座椅和踏脚，准备了机油和工具，修车！在我心里，它理所当然要比那些光鲜亮丽的新车好100倍！</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>No Related Post</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/05/898/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Chrome的alert与重复focus</title>
		<link>http://www.swordair.com/blog/2012/04/897/</link>
		<comments>http://www.swordair.com/blog/2012/04/897/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 09:25:02 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[Note]]></category>
		<category><![CDATA[alert]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[focus]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=897</guid>
		<description><![CDATA[前段时间，在写一个placeholder插件的时候，遇到了一个Chrome下的诡异问题，一段简单的代码，就可以使得浏览器弹出无限循环的 alert 提示框。

我用的代码片段精简到最后是这样的：

<pre lang="html" line="1">
<input id="test" placeholder="placeholder" type="text" />
<script type="text/javascript">
	document.getElementById('test').onfocus = function(){
		alert('focus!');
	}
</script>
</pre>

可能是一时图方便，没log而是用lalert。结果<strong>当点掉alert提示框，Chrome会重复 <code>focus</code> 事件，而其他浏览器则不会。</strong>

我用的是 Chrome 18，看起来在 alert被点掉的瞬间，输入框再次获得了一次焦点，而这次的焦点获取同样触发了 <code>focus</code> 事件，再次弹出alert，然后如此循环往复...

好在这种现象只存在于Chrome里，其他浏览器都完全正常，虽然它们在点掉 alert 弹出框后的行为也不尽相同，但是无一会重复触发 <code>focus</code>。

随后我测试了主流浏览器的行为，整理一张简单的表以备参考。]]></description>
			<content:encoded><![CDATA[<p>前段时间，在写一个placeholder插件的时候，遇到了一个Chrome下的诡异问题，一段简单的代码，就可以使得浏览器弹出无限循环的 alert 提示框。</p>
<p>我用的代码片段精简到最后是这样的：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;input id=&quot;test&quot; placeholder=&quot;placeholder&quot; type=&quot;text&quot; /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	document.getElementById('test').onfocus = function(){
		alert('focus!');
	}
&lt;/script&gt;</pre></td></tr></table></div>

<p>可能是一时图方便，没log而是用lalert。结果<strong>当点掉alert提示框，Chrome会重复 <code>focus</code> 事件，而其他浏览器则不会。</strong></p>
<p>我用的是 Chrome 18，看起来在 alert被点掉的瞬间，输入框再次获得了一次焦点，而这次的焦点获取同样触发了 <code>focus</code> 事件，再次弹出alert，然后如此循环往复&#8230;</p>
<p>好在这种现象只存在于Chrome里，其他浏览器都完全正常，虽然它们在点掉 alert 弹出框后的行为也不尽相同，但是无一会重复触发 <code>focus</code>。</p>
<p>随后我测试了主流浏览器的行为，整理一张简单的表以备参考:</p>
<table>
<tr>
<th>浏览器</th>
<th>行为</th>
</tr>
<tr>
<td>IE8</td>
<td>点掉alert后，输入框保留焦点，不重复触发focus</td>
</tr>
<tr>
<td>Firefox 11</td>
<td>点掉alert后，输入框焦点丢失，不重复触发focus</td>
</tr>
<tr>
<td>Chrome 18</td>
<td>点掉alert后，输入框保留焦点，重复触发focus陷入循环</td>
</tr>
<tr>
<td>Opera 10.60</td>
<td>点掉alert后，输入框保留焦点，不重复触发focus</td>
</tr>
<tr>
<td>Safari 10.60</td>
<td>点掉alert后，输入框保留焦点，不重复触发focus</td>
</tr>
</table>
<p>可见 IE8，Opera 和 Safari 的表现是一样的，<strong>唯独 Firefox 会丢失焦点</strong>，还有就是<strong>唯独 Chrome 会重复 focus</strong>。</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>2011/04/09 -- <a href="http://www.swordair.com/blog/2011/04/580/" title="Chrome中的text-shadow">Chrome中的text-shadow</a></li><li>2010/12/29 -- <a href="http://www.swordair.com/blog/2010/12/510/" title="CSS3 box-shadow 详解(2)">CSS3 box-shadow 详解(2)</a></li><li>2010/11/04 -- <a href="http://www.swordair.com/blog/2010/11/492/" title="CSS3 box-shadow 详解(1)">CSS3 box-shadow 详解(1)</a></li><li>2010/07/07 -- <a href="http://www.swordair.com/blog/2010/07/398/" title="漫谈font-size">漫谈font-size</a></li><li>2010/05/13 -- <a href="http://www.swordair.com/blog/2010/05/347/" title="跨浏览器边框探索">跨浏览器边框探索</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/04/897/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>葵花，播种生活的希望</title>
		<link>http://www.swordair.com/blog/2012/04/886/</link>
		<comments>http://www.swordair.com/blog/2012/04/886/#comments</comments>
		<pubDate>Sat, 21 Apr 2012 17:00:41 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[Plant]]></category>
		<category><![CDATA[sunflower]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=886</guid>
		<description><![CDATA[认识我的人都知道我有多么喜爱向日葵，以至于网名也与葵花有关。当然也不算是无缘无故喜欢上的，儿时的某些景象会像烙印一样镌刻，葵花在我心里就是这种感觉。当下我又种起了向日葵，只是品种是盆栽，而不是株高数米的庞然大物。

<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/04/sunflower_seedling_1.jpg" alt="" title="sunflower_seedling_1" width="640" height="480" class="aligncenter size-full wp-image-887" />
</div>

儿时我曾经种过两次向日葵。那时还有自家菜田，能放下很多蔬菜和花草，若非有这样的环境，恐怕一辈子都难接触到真正向日葵的风采。]]></description>
			<content:encoded><![CDATA[<p>认识我的人都知道我有多么喜爱向日葵，以至于网名也与葵花有关。当然也不算是无缘无故喜欢上的，儿时的某些景象会像烙印一样镌刻，葵花在我心里就是这种感觉。当下我又种起了向日葵，只是品种是盆栽，而不是株高数米的庞然大物。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/04/sunflower_seedling_1.jpg" alt="" title="sunflower_seedling_1" width="640" height="480" class="aligncenter size-full wp-image-887" />
</div>
<p>儿时我曾经种过两次向日葵。那时还有自家菜田，能放下很多蔬菜和花草，若非有这样的环境，恐怕一辈子都难接触到真正向日葵的风采。</p>
<p>第一次看到向日葵的时候我根本不认识它，那只是一株路边石缝里我偶然瞥见的寸长小苗。儿时的自己当然什么都不懂，就拿一个小药品装着这株小苗回家赶紧去做作业了。我从来没想过它会长成什么，不过时间流转，换了一个又一个大药瓶，直到药瓶放不下，又装进花瓶，然后又一个又一个的加大尺寸，终于在家里最大花盆都嫌小的时候，我把这株已经半人高的植物下到菜地里去种。</p>
<p>虽然对于一个小孩而言，这仅仅是一种会向着太阳歪脑袋的奇怪植物，不过童年里的残碎记忆经过时间的发酵，早就变得美轮美奂。只是结果并不理想，这株不明植物我只种了人一般高，虽然最后开花结子，知道了它叫向日葵，但可能因为独种或者是营养不良的缘故，种子都是空的。</p>
<p>第二年春天，我跑遍家附近的各个角落，寻找向日葵，最后在别家篱笆边找到两株。这次我直接就下地栽种，请教了爷爷施肥的技巧，每天精心呵护，两株向日葵很快就长的粗壮挺拔。</p>
<p>到了后来，我更是把自养蚕蛾交配后死去的尸体也埋到了这两株葵花的脚下。那以后葵花的长势就更加势不可挡了，顶端伸出围墙，株高接近3米。父辈和邻里都没见过这么高的向日葵，但恐怕当时的我，还无法用语言组织出“你们不知道这下面有多少蚕蛾的冤魂”这样的冷笑话。</p>
<p>每天放学第一件事就是看看自家的向日葵长的怎么样，越看越喜欢，什么时候喜欢上的呢？不清楚。向日葵对我来说已经不再是神奇的小植物——对于一个身高1米4都不到的小屁孩而言，向日葵俨然已经是顶天立地，它守望着太阳的光辉，在夏日的微风里微微摇曳。日出而东，日落向西，迎朝露，披霞光，虽无浓郁花香，却引得蜜蜂飞舞，那光景里溢满安定和希望。</p>
<p>但烙刻在心里的却是几乎相反的景象。</p>
<p>一天早上当我推开房门，看到的景象是这样：明媚的阳光洒向院中，两株葵花被昨夜的狂风暴雨折断成4节，上半截都歪歪斜斜地倚靠在篱笆上。但是花枝却都整个地弯成了U形，两朵花盘依旧执着地向着东日艳阳。</p>
<p>后来两株花都谢了枯了，但在我的心里那种执着却发了芽。那之后我没有再种过向日葵，后来的城市化也让我永远失去了再种葵花的条件。不过数十年后，今天我仍旧向往葵花的坚毅，沉默地微笑地向着阳光。即使在最黑暗的时候，也祈求自己的阳光终有一日会洒满全身的每个角落。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/04/sunflower_seedling_2.jpg" alt="" title="sunflower_seedling_2" width="640" height="480" class="aligncenter size-full wp-image-888" />
</div>
<p>偶然？心血来潮？都有可能，但我又种起了我心爱的向日葵，虽然只是矮株品种，但是看着它们发芽，每天慢慢地在阳光中成长起来，仍然是充满了希望之光——不知不觉地，也渐渐觉得生活本身也当是应该如此的。</p>
<p>种些植物吧，然后看着它们成长，看着它们开花结果，那种喜悦和慰藉，无疑给平静的生活抹上了淡雅的一丝笑意。</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>No Related Post</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/04/886/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>调试样式：debug.css</title>
		<link>http://www.swordair.com/blog/2012/04/889/</link>
		<comments>http://www.swordair.com/blog/2012/04/889/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 09:54:24 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[bookmarklet]]></category>
		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=889</guid>
		<description><![CDATA[之前写过一篇 <a href="http://www.swordair.com/blog/2011/08/675/">开发过程中的调试样式</a>，讲述了著名的37signals团队如何用样式视觉化代码的缺陷。但那只是浅尝辄止地提及了一下，现在我整理了一份相对完整的样式表。]]></description>
			<content:encoded><![CDATA[<p>之前写过一篇 <a href="http://www.swordair.com/blog/2011/08/675/">开发过程中的调试样式</a>，讲述了著名的37signals团队如何用样式视觉化代码的缺陷。但那只是浅尝辄止地提及了一下，现在我整理了一份相对完整的样式表。</p>
<p>由于是一个工具，主要是以用为主。所以如果你不想看下面的详细解释和说明，你可以直接将下面的链接拖动到书签栏：</p>
<p><a href="javascript:(function(){var elm = document.createElement('link');elm.setAttribute('rel','stylesheet');elm.setAttribute('type','text/css');elm.setAttribute('href','http://www.swordair.com/css/debug.css');if(typeof elm != undefined){document.getElementsByTagName('head')[0].appendChild(elm);}})();">Debug CSS by 葵中剑</a></p>
<p>这是一个 js 的 bookmarklet，它的作用只是简单地在页面注入一段样式。在把它放到书签栏之后，打开你喜欢的网站，然后点击这个书签，看看发生了什么？:)</p>
<p>RSS可能看不到，你也可以复制下面的代码并保存为一个书签，或者直接复制到浏览器地址栏后回车，效果是一样的：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">javascript<span style="color: #339933;">:</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #003366; font-weight: bold;">var</span> elm <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'link'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>elm.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'rel'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'stylesheet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>elm.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'type'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'text/css'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>elm.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'href'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'http://www.swordair.com/css/debug.css'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>if<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> elm <span style="color: #339933;">!=</span> undefined<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elm<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>然后我再开始详细说明这个样式都干了些什么——你自己也可以根据自己需要编写符合自身使用的调试样式，但通常包含我在下面讨论的几个要素。</p>
<h4>什么是调试样式？</h4>
<p>调试样式就是利用CSS选择器和特殊的样式，视觉化代码缺陷的手段。最常用的样式可能如下所示：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="css" style="font-family:monospace;">img<span style="color: #00AA00;">:</span>not<span style="color: #00AA00;">&#40;</span><span style="color: #00AA00;">&#91;</span><span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">&#93;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">:</span>not<span style="color: #00AA00;">&#40;</span><span style="color: #00AA00;">&#91;</span><span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">&#93;</span><span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span> <span style="color: #933;">2px</span> <span style="color: #993333;">solid</span> <span style="color: #993333;">red</span> !important<span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>这段代码将页面里的没有设置高宽的图片全部添加2px的红色边框，使得我们能从页面上一下子看到识别它。这类样式通常包含这几个特点：</p>
<ul>
<li>因为能检查的大部分是属性，所以大量的使用属性选择器</li>
<li>有 !important 用于提升特殊性</li>
<li>大多通过鲜艳的背影和边框凸显问题元素</li>
</ul>
<p>前两条没什么可说的，最后一条，在当前的浏览器背景下，边框已经可以有很多种替代方式，并且这些方式更好。调试样式应该尽可能避免与页面样式的冲突，所以用 <code>outline</code> 替代 <code>boder</code> 可以避免调试样式对布局的影响，因为 <code>outline</code> 并不像 <code>border</code> 那样占据空间。而另一个替代的边框标注的方案是 <code>box-shadow</code> 模拟的边框，因为其同样不占据空间。并且，我们调试使用的浏览器都支持CSS3。</p>
<p>也许你已经可以想到，还有哪些问题需要被调试样式标出。根据检验的严格程度，标出的内容也不尽相同，但一个相对严格的样式应该包含下面这些项：</p>
<ul>
<li>行内样式：通常这可以容忍</li>
<li>缺失必要属性：典型例子就是 <code>img</code> 标签的 <code>alt</code></li>
<li>属性为空值或常用占位值：典型例子就是 <code>a</code> 标签的 <code>href</code></li>
<li>元素内容为空：很常见，但能避免</li>
<li>废弃的属性：应尽量避免</li>
<li>废弃的元素：应尽量避免</li>
</ul>
<p>这个列表自上而下是有顺序的，这样做是基于样式复写的考虑。当然也是个人习惯，我并不喜欢在调试样式里添加太多颜色和样式区分，线型和线粗就已经能很好的反应问题的严重程度。实际使用的时候配合3种颜色足以表示所有的情况。</p>
<p>本来打算把上面列出来的项逐个说明，不过现在觉得那样的话这篇东西就太长了。所以就请直接点击查看最终的代码吧:</p>
<p><a href="http://www.swordair.com/css/debug-strict.css">debug-strict.css</a> 以及 <a href="http://www.swordair.com/css/debug.css">debug.css</a></p>
<p>我提供了两个版本，前者在实际使用时效果太强，所以轻微修改了一下，两者相比有如下不同：</p>
<ol>
<li><code>img</code> 没有 <code>title</code> 非常常见，所以从debug-strict.css里移除了</li>
<li>不设高宽的 <code>img</code> 也很常见，所以单独拿出来用蓝色线标注</li>
</ol>
<p>完成这个样式表的时候也同时参考了 Eric Myers toolkit，不过那个 toolkit 已经严重过期。比如 <code>u</code>，<code>s</code>，<code>menu</code> 等元素在HTML5中，被赋予了新的使命，已经不再是废弃元素。相反，<code>table</code> 的 <code>summary</code> 等属性反而被新标准废弃。这样的情况还有很多，但毕竟<strong>标准还是不断在更新完善中</strong>。</p>
<p>这个样式表过期属性和元素参照的是最新版的 <a rel="external" href="http://dev.w3.org/html5/html4-differences/">HTML5 differences from HTML4</a>，当然还包括了一些这份草案没有列出的项。其实，这份样式表本来就是我翻译这篇文档的附带产物:)~</p>
<h4>实际使用分析</h4>
<p>前面讲了这么多，无非是纸上谈兵，下面就来点实际截图。</p>
<h5>AliExpress.com</h5>
<p>正巧老东家AliExpress新首页上线，正好可以拿来做实验品~ 新首页很给力，风格清淡大气，个人感觉混合着亚马逊新版和ebay的味道，这页面一出就给人一种走C一路到底的感觉。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/04/aliexpress_home_compare.png" alt="aliexpress home compare" title="aliexpress_home_compare" width="640" height="744" class="aligncenter size-full wp-image-890" />
</div>
<p>图中，黄色部分是空标签，红色点框是缺少 <code>alt</code> 的图片，蓝色点框则是没有设置高宽的图片——实际上，大部分网站都多少会有一些这种“算不上问题的问题”。但通过注入一段简单的样式，就能很轻易的看出页面的特色。</p>
<p>比如，截图里的旧版，主banner下面只有第二块小banner没有 <code>alt</code>，应该不至于是文案不到位吧，难道亚历克苏斯同学你又调皮了&#8230;&#8230;另外，旧版其它两个缺少 <code>alt</code> 的图片也显而易见了。新版缺少的 <code>alt</code> 则更多，不知是否刻意为之。但撇开微量的行内样式，无论新版还是旧版，整个页面在 debug.css 面前都极为出色。</p>
<h5>Taobao.com</h5>
<p>惯例看一下淘宝的首页，不过页面截图太长，所以只能放个链接：<a href="http://www.swordair.com/blog/wp-content/uploads/2012/04/taobao_css_debug.png">淘宝截图</a></p>
<p>看起来相对是比较清爽的。从红色的1px点线可以看出，虽然类目里的样式相同，但有些却是行内样式，多少可以看出增改类目时留下的痕迹。</p>
<h5>amazon.com &amp; ebay.com</h5>
<p>amazon 和 ebay的结果可能出乎意料，大量的黄色块说明有很多的空标签；隐约的绿色边框表示其使用了废弃的属性——这不难理解，最常见的废弃属性就是 <code>table</code> 的一些老属性，哪里有 <code>table</code>，哪里废弃属性就越可能多。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/04/amazon_ebay_css_debug.png" alt="" title="amazon_ebay_css_debug" width="640" height="630" class="aligncenter size-full wp-image-893" />
</div>
<h5>Baidu &amp; Google</h5>
<p>百度和 Google 的对比也是很有趣，特别是 Google，用了如 <code>center</code> 这样的元素（实际上百度在早几年前也一样是用 <code>center</code> 的）。Google是我所知最喜欢用空标签的了，圆角/箭头/阴影等等，我都曾看到其用过空标签来实现过。所以黄成这样其实也在意料之内。</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/04/baidu_google_css_debug.png" alt="" title="baidu_google_css_debug" width="640" height="237" class="aligncenter size-full wp-image-891" />
</div>
<h5>360buy &amp; 51buy &amp; dangdang &amp; amazon</h5>
<p>除了亚马逊，其实国内的各B2C都相对比较清爽。当当你的广告还能在多一点吗？我擦，截个图要关你丫多少广告啊！！</p>
<div class="img-border">
<img src="http://www.swordair.com/blog/wp-content/uploads/2012/04/360buy_51buy_amazon_dangdang_css_debug.png" alt="" title="360buy_51buy_amazon_dangdang_css_debug" width="640" height="757" class="aligncenter size-full wp-image-892" />
</div>
<h4>总结</h4>
<p>从上面的对比来说，没有什么绝对的结果，用什么代码，遗漏了多少东西似乎构不成足够的理由。有趣的是，在debug.css面前，明显是国内的网站比较干净——那并不是说国内的代码水平有多高，但似乎重视程度有差距。</p>
<p>对于动态加载的图片和链接，<code>alt</code> 之类的可能就不重要了，所以<strong>单单看看样式的结果也并不尽准确</strong>。闲来无事的时候，用这个样式测了下 w3c 的主页，真的几乎可以说无懈可击&#8230;</p>
<p>虽然我尽可能保证代码的准确，但毕竟一人为之，有错漏之处，欢迎指出。</p>
<p>最后我想说，好久不写这么长了，好累&#8230;果然是老了么&#8230;</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>2012/03/21 -- <a href="http://www.swordair.com/blog/2012/03/814/" title="CSS选择器距离无关">CSS选择器距离无关</a></li><li>2012/02/21 -- <a href="http://www.swordair.com/blog/2012/02/800/" title="CSS display: run-in;">CSS display: run-in;</a></li><li>2012/02/17 -- <a href="http://www.swordair.com/blog/2012/02/799/" title="webkit自定义滚动条">webkit自定义滚动条</a></li><li>2012/02/07 -- <a href="http://www.swordair.com/blog/2012/02/721/" title="CSS Hack Table">CSS Hack Table</a></li><li>2012/01/05 -- <a href="http://www.swordair.com/blog/2012/01/747/" title="纯CSS圆角Tab">纯CSS圆角Tab</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/04/889/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>HTML5相对于HTML4的差异更新浅析</title>
		<link>http://www.swordair.com/blog/2012/04/885/</link>
		<comments>http://www.swordair.com/blog/2012/04/885/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 10:05:28 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[Translation]]></category>
		<category><![CDATA[web standards]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=885</guid>
		<description><![CDATA[去年我翻译了 <a rel="external" href="http://dev.w3.org/html5/html4-differences/">HTML5 differences from HTML4</a>，时隔约快一年了，这份工作草案再次更新。而我也开始着手更新自己的翻译稿。

这次的更新量相当大，所以翻译完整更新以及修订需要一些时间，但我会尽力最快地拿出更新稿。今天乘空的时候稍稍对比了一下两者，如果你读过去年5月25日版本，无论是<a rel="external" href="http://www.w3.org/TR/2011/WD-html5-diff-20110525/">英文原文</a>，或者是<a href="http://www.swordair.com/docs/html5-differences-from-html4/">我的翻译稿</a>，那么你就可以从下面了解一些当前的最显而易见的改动。]]></description>
			<content:encoded><![CDATA[<p>去年我翻译了 <a rel="external" href="http://dev.w3.org/html5/html4-differences/">HTML5 differences from HTML4</a>，时隔约快一年了，这份工作草案再次更新。而我也开始着手更新自己的翻译稿。</p>
<p>这次的更新量相当大，所以翻译完整更新以及修订需要一些时间，但我会尽力最快地拿出更新稿。今天乘空的时候稍稍对比了一下两者，如果你读过去年5月25日版本，无论是<a rel="external" href="http://www.w3.org/TR/2011/WD-html5-diff-20110525/">英文原文</a>，或者是<a href="http://www.swordair.com/docs/html5-differences-from-html4/">我的翻译稿</a>，那么你就可以从下面了解一些当前的最显而易见的改动。</p>
<h4>新元素</h4>
<p>WHATWG增加了一个 <code>data</code> 元素，用来把内容标注成机器可以读取的值。举个最简单易懂的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">I have &lt;data value=&quot;8&quot;&gt;eight&lt;/data&gt; apples.</pre></div></div>

<p>一目了然，data只是为机读服务的。这里 <code>data</code> 元素的 <code>value</code> 属性是必须出现的，其值代表了 <code>data</code> 元素中的内容的机读格式。</p>
<h4>新属性</h4>
<p><code>object</code> 元素多了一个新属性 <code>typemustmatch</code>，使得嵌入外部资源更加安全。</p>
<p><code>img</code> 元素多了一个新属性 <code>crossorigin</code>，用以在获取过程中使用CORS(Cross-Origin Resource Sharing)，并在成功后允许图像数据被 <code>canvas</code> API 读取。</p>
<p>增加了全局属性 <code>translate</code>，用来给翻译器给出翻译提示(哪些需要被翻译，哪些则必须保持原样)</p>
<h4>元素变动</h4>
<p>当用户代理不支持由 <code>script</code> 元素调用的脚本语言时，<code>noscript</code> 元素不再被渲染。</p>
<p><code>script</code> 元素现在可以用于脚本或自定义数据块。</p>
<h4>大量的其他更新</h4>
<ul>
<li>大量的属性变动</li>
<li>增加了一整节内容：Content Model Changes</li>
<li>API章节的大量修订</li>
</ul>
<p>这部分非常庞大，基本上需要重译。我暂时还没有足够的空闲时间完整看完。但一旦我完成了这部分内容，也会第一时间放出更新稿。谢谢大家的支持:)</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>2012/02/21 -- <a href="http://www.swordair.com/blog/2012/02/800/" title="CSS display: run-in;">CSS display: run-in;</a></li><li>2011/07/19 -- <a href="http://www.swordair.com/blog/2011/07/672/" title="HTML5 Differences from HTML4 译文">HTML5 Differences from HTML4 译文</a></li><li>2011/03/13 -- <a href="http://www.swordair.com/blog/2011/03/577/" title="Block-level Box &#038; Block Container Box &#038; Block Box">Block-level Box &#038; Block Container Box &#038; Block Box</a></li><li>2010/11/04 -- <a href="http://www.swordair.com/blog/2010/11/492/" title="CSS3 box-shadow 详解(1)">CSS3 box-shadow 详解(1)</a></li><li>2010/08/07 -- <a href="http://www.swordair.com/blog/2010/08/415/" title="CSS定位机制之一：普通流">CSS定位机制之一：普通流</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/04/885/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>再谈box-shadow</title>
		<link>http://www.swordair.com/blog/2012/04/881/</link>
		<comments>http://www.swordair.com/blog/2012/04/881/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 07:12:53 +0000</pubDate>
		<dc:creator>葵中剑</dc:creator>
				<category><![CDATA[Front-end]]></category>
		<category><![CDATA[Note]]></category>
		<category><![CDATA[box-shadow]]></category>
		<category><![CDATA[CSS3]]></category>

		<guid isPermaLink="false">http://www.swordair.com/blog/?p=881</guid>
		<description><![CDATA[早先，我详细地写过2篇关于 <code>box-shadow</code> 的文章: <a href="http://www.swordair.com/blog/2010/11/492">CSS3 box-shadow 详解(1)</a> 以及 <a href="http://www.swordair.com/blog/2010/12/510/">CSS3 box-shadow 详解(2)</a>。但用现在的眼光来看，内容已经有些旧了。趁着这片闲言碎语，对 <code>box-shadow</code> 再做一些补充。

<code>box-shadow</code> 是我最喜欢的CSS3特性之一，它能创建凸显层次的阴影，但却还可以充当很多角色：边框/层叠/渐变/勾线，等等。当前浏览器的支持程度已经非常理想，除了IE8及以下，所有浏览器都已经更新到无前缀的支持——这跟一年前的情况很不同，那时，一些浏览器如firefox实现的 <code>box-shadow</code> 还存在占用空间的bug，Webkit类的模糊算法非常僵硬，随着这一年的发展这一些问题都已被克服。如今存在的问题只有两个，<strong>部分移动版浏览器的不支持</strong>，以及<strong>Opera在多阴影高模糊值时的效率低下</strong>。但相信这些问题也都能尽早解决。]]></description>
			<content:encoded><![CDATA[<p>早先，我详细地写过2篇关于 <code>box-shadow</code> 的文章: <a href="http://www.swordair.com/blog/2010/11/492">CSS3 box-shadow 详解(1)</a> 以及 <a href="http://www.swordair.com/blog/2010/12/510/">CSS3 box-shadow 详解(2)</a>。但用现在的眼光来看，内容已经有些旧了。趁着这片闲言碎语，对 <code>box-shadow</code> 再做一些补充。</p>
<p><code>box-shadow</code> 是我最喜欢的CSS3特性之一，它能创建凸显层次的阴影，但却还可以充当很多角色：边框/层叠/渐变/勾线，等等。当前浏览器的支持程度已经非常理想，除了IE8及以下，所有浏览器都已经更新到无前缀的支持——这跟一年前的情况很不同，那时，一些浏览器如firefox实现的 <code>box-shadow</code> 还存在占用空间的bug，Webkit类的模糊算法非常僵硬，随着这一年的发展这一些问题都已被克服。如今存在的问题只有两个，<strong>部分移动版浏览器的不支持</strong>，以及<strong>Opera在多阴影高模糊值时的效率低下</strong>。但相信这些问题也都能尽早解决。</p>
<p>之前虽然详细讲了 <code>box-shadow</code> 的方方面面，但唯独对IE模拟用其他引用链接一笔带过，现在做一个小补充。众所周知，IE低版本实现 <code>box-shadow</code> 是用滤镜的，这并不是推荐的做法：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="css" style="font-family:monospace;">.box-shadow<span style="color: #00AA00;">&#123;</span>
	-moz-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span> <span style="color: #933;">3px</span> <span style="color: #933;">4px</span> <span style="color: #cc00cc;">#000</span><span style="color: #00AA00;">;</span>
	-webkit-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span> <span style="color: #933;">3px</span> <span style="color: #933;">4px</span> <span style="color: #cc00cc;">#000</span><span style="color: #00AA00;">;</span>
	box-shadow<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span> <span style="color: #933;">3px</span> <span style="color: #933;">4px</span> <span style="color: #cc00cc;">#000</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span><span style="color: #cc00cc;">#fff</span><span style="color: #00AA00;">;</span> <span style="color: #808080; font-style: italic;">/* for IE filter, required */</span>
	-ms-filter<span style="color: #00AA00;">:</span> <span style="color: #ff0000;">&quot;progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000')&quot;</span><span style="color: #00AA00;">;</span> <span style="color: #808080; font-style: italic;">/* For IE 8 */</span>
	filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.Shadow<span style="color: #00AA00;">&#40;</span>Strength<span style="color: #00AA00;">=</span><span style="color: #cc66cc;">4</span><span style="color: #00AA00;">,</span> Direction<span style="color: #00AA00;">=</span><span style="color: #cc66cc;">135</span><span style="color: #00AA00;">,</span> Color<span style="color: #00AA00;">=</span><span style="color: #ff0000;">'#000000'</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span> <span style="color: #808080; font-style: italic;">/* For IE 5.5 - 7 */</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>现在这种代码已经显得太碍眼了，对于IE低版本我更倾向于放任不管：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.box-shadow</span><span style="color: #00AA00;">&#123;</span>box-shadow<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span> <span style="color: #933;">3px</span> <span style="color: #933;">4px</span> <span style="color: #cc00cc;">#000</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>当然，总有需求需要IE8-有阴影，如果身在需求主导的环境下，借滤镜一用也算是无奈之举。使用滤镜的话，给对应box一个背景颜色是必需的，否则你会在box内部以及字体上同时看到丑陋的阴影效果。</p>
<h3  class="related_post_title">Related Post:</h3><ul class="related_post"><li>2012/03/23 -- <a href="http://www.swordair.com/blog/2012/03/872/" title="像Photoshop一样地使用CSS">像Photoshop一样地使用CSS</a></li><li>2010/12/29 -- <a href="http://www.swordair.com/blog/2010/12/510/" title="CSS3 box-shadow 详解(2)">CSS3 box-shadow 详解(2)</a></li><li>2010/11/04 -- <a href="http://www.swordair.com/blog/2010/11/492/" title="CSS3 box-shadow 详解(1)">CSS3 box-shadow 详解(1)</a></li><li>2012/03/27 -- <a href="http://www.swordair.com/blog/2012/03/874/" title="CSS实现字体内阴影">CSS实现字体内阴影</a></li><li>2012/03/12 -- <a href="http://www.swordair.com/blog/2012/03/834/" title="边角阴影渐变">边角阴影渐变</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.swordair.com/blog/2012/04/881/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

