﻿<?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">
<channel>
<title>前端开发 - ITFeed</title>
<link>http://www.itfeed.cn</link>
<description>互联网产品设计开发知名博客聚合</description>
<dc:creator>ITFeed</dc:creator>
<pubDate>Sun, 02 Sep 2012 22:40:20 +0800</pubDate>
<language>en</language>
<item>
<title>HTML5引领下的Web革命</title>
<link>http://www.itfeed.cn/post.asp?id=10464</link>
<description>
<![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 万维网开发人员最近表示新的HTML5标准对网络的演变过程，工作方式和使用途径而言，都是一次非凡的革新。新的标准简化了程序运行方式，协调了各种终端设备和应用程序之间互访的入口，给用户带了让人惊喜的全新功能。然而HTML(超文本标记语言)只是将文本进行部分标记从而让浏览器可以智能读取。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个微不足道标记网页机制为何会产生如此大的影响？针对HTML5的大肆宣传仅仅是一时兴起的狂热吗？那为何计算机专家要如此关注新版本的推出。要证明新标准的价值，难点在于如何向公众展现出HTML5作为单一独立的规范同时，也可以被当做是一套技术集。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 标记性语言技术有效的支持网络软件核心常达20多年，这次的HTML5被广泛认为在新标记技术基础上，也囊括了访问和操作HTML文档的文档对象模型的新标准；定义网页外观和展现风格的级联样式表(CSS)标准；还有JAVA脚本语言JS。HTML5这个术语甚至还包括了一系列特殊应用接口程序(APIs)，例如基于浏览器的图像，地理，存储和视频API。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 同时，HTML5还是W3C联盟开放网络平台(Open Web Platform)的核心，这一平台经过多年的演化发展，已经成为有效支持其内容的标记性语言和相关技术的统称。<span id="more-1502"></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 作为HTML4命令和标准的作者，伊恩 &middot; 雅各布斯表示，在网络健康成长和逐步强大的同时，HTML标准也随之成熟并不断扩张自己的影响范围。&ldquo;在过去的20年，网络已从一个动态文档的展现工具发展成为如今各种应用的共享平台。&rdquo;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 雅各布斯指出，有两股力量推动着这次HTML标准革新。首先各种终端设备的不断出现，以及浏览器的繁复多样，大大增加了开发人员工作的复杂性，使得他们&ldquo;随时随处&rdquo;的工作方式难以继续。第二，网络世界与社交模式的结合，使得，只要你深入其中，就可以获得很多的客户&#8211;有时这一规模甚至可以达到成千上万。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 友好型标准<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 业内一家主攻图形网站设计和营销的公司Ocupop，已经开始在他所有的业务中使用HTML5标准。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ocupop的一位网站开发人员兼使用性设计师马修&middot;麦克维克指出，&ldquo;这套标准下，并非所有推崇点都可以被称之为&ldquo;新&rdquo;。HTML标准之前作为技术使用典范，用来帮助开发者将试图达到的效果或者内容装载如浏览器中，对其实现进行有效的支持。例如，新标准里有一个用于地理定位的JS接口，移动设备上的浏览器可以自如读取GPS数据，而不再需要引入自定义API到相关硬件设备上。&rdquo;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这一改变对于终端用户来说可能并不明显，但对软件开发者而言却意义重大。地理信息对开发人员是完全透明的，开发人员不再需要花费精力去写针对不同浏览器和硬件设备的代码。所有这些，正是一套标准走向完备化所必需的。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 马修&middot;麦克维克说：&ldquo;同样，最新版本的CSS3允许开发者可以直接在浏览器内部实现图画效果，而这个版本之前则需要在外部使用PS制作再将其导入浏览器。比方，我们可以动态实现浏览器标题文字阴影化处理，而整个过程快速而简单。单这一环节就节省了大量的开发时间。&rdquo;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 马修&middot;麦克维克指出，浏览器各大厂商都渴望去尝试web的最新功能，而新的标准无疑成为这一过程的催化剂。厂商们也正努力让自己的研发能力与标准的更新节奏同步。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HTML5中一个新特性&ldquo;本地存储&rdquo;允许客户端保留结构化的会话型数据。我们知道cookies技术只能在客户端保存很少量的数据且需要受到一些网络技术的限制。相比之下，&ldquo;本地存储&rdquo;使得数据存储量进一步扩大，甚至客户端与服务器端的连接不稳定或者无连接的情况下，也丝毫不影响存储性能。并且HTML5支持更加丰富的图形界面，比如，内嵌式的SVG，用户还可以使用基于栅格的布画用JS在网页内完成2D和3D图画效果。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 更严格的规范<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Google的一位软件工程师，伊恩&middot;希克森非常赞同新的规范很大程度上帮助了厂商。希克森同时还是W3C和Web超文本应用技术工作组(WHATWG)的联络官。2004年希克森创建了这个补充性标准组织，由来自苹果，莫拉兹基金和Opera 的优秀技术人员组成。&ldquo;我们对HTML最重大的贡献就是显著提高了标准的规范性&rdquo;。&ldquo;之前对规范的描述很模糊，各个浏览器厂商都认为自己遵守相同的规则和规范，但其实这些浏览器之间并不兼容。现在，对规范做了很多细节化处理，只要厂商严格按照规范来设计浏览器，那这些产品间会建立起良好的兼容性。当然，彻底实现这一切还需要大量的相关工作，但其重要性不容置疑。&rdquo;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 即便与上一版本相比是个飞跃，HTML5也不会是完结篇，不同公司对这套新标准的诠释也不尽相同。对视频压缩技术、媒体流协议和数字版权加密技术，HTML5标准也没有做出统一阐述。2010年之前，各大浏览器制造商都统一使用Adobe Flash作为唯一的视频标准。随后苹果公司发表声明，iPhone和iPad将不再支持Flash技术，转而使用苹果自己的网络技术集，其中就包括HTML5。同时，微软和google也推出了自己的音视频解码器，导致的结果就是这两家的浏览器也不能完全兼容。所以，开发人员不得不提供多种网络技术来全面应对不同浏览器。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 卡内基梅陇大学计算机系教授张晖，作为资深的网络专家，认为&ldquo;HTML5有强大的发展势头，但是迄今还不能百分之百支持所有的浏览器，原因在于它还是没有被广泛正式当做一个教科书般的标准。当然，浏览器厂商都在为此努力。而整个标准化的过程存在的挑战性不只针对视频解码，厂商们心里很清楚HTML5标准地位的确定会给他们自己和顾客带来巨大的好处，但与此同时为了使产品更具竞争力，商家力求创造更多的特色点于其中。&rdquo;张晖提醒道&ldquo;大家都想分得那块最大的蛋糕，但是如果过于贪婪，那么蛋糕最终会毁于一旦。&rdquo;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Conviva的产品主要集中于提高网络视频播放效果，而作为这家公司的创立者之一，张教授对视频解码技术的兴趣不言而喻。他认为视频是最复杂的网络载体信息，解码、媒体流协议和DRM的标准化道路无疑将会漫漫长久。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 来自官方消息称，一切顺利的话在2014年W3C将会把HTML5(限定为超文本标记语言规范)指定为推荐标准。但是伊恩 &middot; 雅各布斯也指出：&ldquo;由于其他独立规范的成熟度不同，这必然会导致他们最终标准化的时期不能达到同步。&rdquo;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; W3C的一位交互领域专家菲利普&middot;勒&middot;加雷表示，&ldquo;不能把HTML5简单看做是一个产品，当然我们永远不能说&lsquo;看，我完成了新的HTML&rdquo;，&ldquo;这套新规范包含了60个API，而且这个数量还在不断上升。例如，最近出现的一个新需求，希望浏览器能完成语音和文本之间的对话。我们会把这点加入到考虑范围中。&rdquo;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当谈到对HTML6的畅想，google的希克森说到：&ldquo;Web尚无法有效支持的功能点可以说无穷尽，HTML就是HTML，去年开始我们就不再关注是5还是6这种问题了。像浏览器一样，HTML规范会不断完善和发展的，直到有一天我们不再使用他，那也是他要退出历史舞台的时刻了。&rdquo;</p>
<div style="margin:15px 0px;line-height:25px;"><strong>原创文章，转载请注明：</strong> 转载自<a href="http://www.yiiyaa.net/">http://www.yiiyaa.net/</a><br/><strong>本文链接地址：</strong> <a href="http://www.yiiyaa.net/1502">http://www.yiiyaa.net/1502</a></div>
<h4  class="related_post_title">【 精彩文章推荐 】</h4><ul class="related_post"><li>2010-10-31 -- <a href="http://www.yiiyaa.net/726" title="JavaScript之继承方式">JavaScript之继承方式</a> (1)</li><li>2011-02-22 -- <a href="http://www.yiiyaa.net/1301" title="20款超赞的高品质滑块！">20款超赞的高品质滑块！</a> (3)</li><li>2010-11-17 -- <a href="http://www.yiiyaa.net/955" title="不让用户思考过多!">不让用户思考过多!</a> (1)</li><li>2011-02-10 -- <a href="http://www.yiiyaa.net/1260" title="2011年5大科技预言：平板电脑昙花一现">2011年5大科技预言：平板电脑昙花一现</a> (2)</li><li>2010-10-30 -- <a href="http://www.yiiyaa.net/723" title="JavaScript之修改对象">JavaScript之修改对象</a> (0)</li><li>2011-04-30 -- <a href="http://www.yiiyaa.net/1350" title="HTML5之表单新功能详解">HTML5之表单新功能详解</a> (5)</li><li>2010-10-29 -- <a href="http://www.yiiyaa.net/711" title="JavaScript之定义类或对象六种方式">JavaScript之定义类或对象六种方式</a> (1)</li><li>2010-11-26 -- <a href="http://www.yiiyaa.net/1066" title="JavaScript之事件处理(监听)函数">JavaScript之事件处理(监听)函数</a> (0)</li></ul>]]>
</description>
<dc:creator>意雅</dc:creator>
<pubDate>Tue, 28 Aug 2012 11:20:15 +0800</pubDate>
</item>
<item>
<title>IE条件注释可以怎么玩</title>
<link>http://www.itfeed.cn/post.asp?id=10452</link>
<description>
<![CDATA[<div class="cut-pic"><img src="http://p5.qhimg.com/t01af61415a85aaf5f0.jpg" alt="IE条件注释可以怎么玩" title="IE条件注释可以怎么玩结" class="alignnone big-img" width="715" height="198"></div>
IE条件注释（Conditional comments）是IE浏览器私有的代码，是一个类似IF判断的语法注释块，IE5之上支持。看似简单的一个私有特性，能玩出多少东东来，本文就慢慢给你道来。。。]]>
</description>
<dc:creator>360UXC</dc:creator>
<pubDate>Fri, 24 Aug 2012 17:07:40 +0800</pubDate>
</item>
<item>
<title>beforeunload丢失率统计</title>
<link>http://www.itfeed.cn/post.asp?id=10436</link>
<description>
<![CDATA[<p align="left">        用户体验研究过程中，我们经常需要使用前端脚本采集用户访问行为相关的数据，例如监听鼠标的点击事件，记下点击的位置及被点击的元素等。一个不可避免问题是，何时将采集到的数据发送到服务器呢？最直接的方案是每次收集到数据后立即发送，但这可能会带来较多的HTTP请求，一方面降低页面的性能，另一方面也增加了打点服务器的压力。另一个方案是先将收集的数据缓存一下，然后按一定规则发送（比如每收集满10条数据发一次，或者每隔5秒钟发一次），其中最终极的方案是所有的数据都缓存起来直到离开页面之前（beforeunload事件触发时）再发送。不过这个终极方案也有自己的问题，比如beforeunload这个事件可靠吗？在这个事件中发送打点的丢失率有多少？近期我们就这些问题做了一个研究，对这个丢失率也有了一个更具体的认识。主要的研究过程如下：</p>
<p align="left">        首先我们需要收集数据，这儿主要有两个数据：页面加载时立即发送一个打点，称为PV打点；监听页面的beforeunload事件，在这个事件触发时再发送一个打点，称为unload打点。显然，如果丢失率为0或非常小的话，PV打点的数目和unload打点的数目应该相等或非常接近。即丢失率的计算公式为：<span style="text-align: center;">丢失率=(PV-unload)/PV*100%</span></p>
<p align="left">        如下图所示：</p>
<p align="left"><a href="http://ued.taobao.com/blog/wp-content/uploads/2012/08/统计流程概述.png"><img class="aligncenter size-full wp-image-6002" title="统计流程概述" src="http://ued.taobao.com/blog/wp-content/uploads/2012/08/统计流程概述.png" alt="统计流程概述" width="483" height="410" /></a></p>
<p align="left">        按这个思路，我们在淘宝页面上进行了抽样埋点，并取得了足够多的PV及unload打点数据。但现实总是不完美的，整理这些数据的过程中，我们发现一些unload数据没有对应的PV数据，也就是说，由于各种各样的原因，不仅绑定beforeunload事件的unload打点有可能丢失，在页面初始化时发送的PV打点也可能丢失，尽管这个概率非常低。于是，我们又为打点添加了一个pvid参数，值为一个随机生成的字符串，每一组PV/unload打点的pvid都是相同的。这样，我们就能通过这个参数过滤出那些完整的PV/unload打点记录，再经过一些适当的整理，我们就得到了可以进行统计的有效数据。</p>
<p align="left">        接下来，根据上面的公式，我们算出了beforeunload打点的总丢失率，约为20.81%，整个过程如下图所示：</p>
<p style="text-align: center;" align="left"><a href="http://ued.taobao.com/blog/wp-content/uploads/2012/08/beforeunload统计流程图.jpg"><img class="size-full wp-image-5994 aligncenter" title="beforeunload统计流程图" src="http://ued.taobao.com/blog/wp-content/uploads/2012/08/beforeunload统计流程图.jpg" alt="beforeunload统计流程图" width="284" height="727" /></a></p>
<p align="left">        使用上面的方法我们连续统计了若干天的数据，发现beforeunload的总体丢失率维持在20%附近。接下来，我们再把这个数据按浏览器进行细分，看各个浏览器下这个丢失率是否有差异。</p>
<p align="left">        首先看一下当前浏览器分布情况：</p>
<p align="left"><a href="http://ued.taobao.com/blog/wp-content/uploads/2012/08/浏览器分布2.png"><img class="aligncenter size-full wp-image-6003" title="浏览器分布" src="http://ued.taobao.com/blog/wp-content/uploads/2012/08/浏览器分布2.png" alt="浏览器分布" width="538" height="405" /></a></p>
<p align="left">        清洗过的日志数据再根据UA字段细分后的结果为：</p>
<p align="left"><a href="http://ued.taobao.com/blog/wp-content/uploads/2012/08/浏览器细分后的丢失率.png"><img class="wp-image-6004 alignnone" title="浏览器细分后的丢失率" src="http://ued.taobao.com/blog/wp-content/uploads/2012/08/浏览器细分后的丢失率.png" alt="浏览器细分后的丢失率" width="554" height="219" /></a></p>
<p align="left">        从上图可以看到，各大浏览器的表现并不一样，其中份额占比最大的IE8在丢失率上表现最好，远低于总体平均水平，而chrome和safari却远高于平均值。各浏览器的丢失率乘以它们各自的权重（市场份额）之后再求和，就得到了总的平均丢失率，在我们的实验中，这个总丢失率约为20%。</p>
<p align="left"><strong>        结论：</strong>使用beforeunload事件打点并不可靠，总丢失率在20%左右，其中各浏览器的表现各不相同；当然在一些丢失率要求不高的采集任务中这个事件还是能派上用场的，比如说统计页面停留时间、页面内容曝光比例等。</p>
<p align="left">        最后需要<strong>特别说明</strong>的是：丢失率与用户浏览器分布情况、所采用的打点方式以及打点服务器响应速度等因素都有关，本结果仅供参考。</p>
<p align="left">        <strong>统计人：</strong>鱼相、季札。</p>
]]>
</description>
<dc:creator>淘宝UED</dc:creator>
<pubDate>Thu, 23 Aug 2012 11:47:30 +0800</pubDate>
</item>
<item>
<title>在外闯荡也不可迷失自我！——浅谈第三方组件的css reset</title>
<link>http://www.itfeed.cn/post.asp?id=10432</link>
<description>
<![CDATA[<p><a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/未标题-2.jpg" rel="lightbox[1497]"><img class="title_image" title="未标题-2" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/未标题-2.jpg" alt="" width="680" height="285" /></a></p>
<p>所谓第三方组件（widget），就是指我们提供给第三方网站使用的小模块，如微博的关注按钮，分享按钮，社交化组件，微博秀等等。当我们的组件放在第三方网站上时，不经意间会继承东道主网站的某些样式。但是，我们的目标是：保证自己组件样式的展现，即便寄人篱下，也不可丢失自己的个性！<span id="more-1497"></span></p>
<p>通常我们会面临如下一些问题。</p>
<p><strong>一、被同样的命名覆盖</strong></p>
<p>我们先来看看某些网站的公用文件的写法：<br />
eg1某网站：<br />
<a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch4D66.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1499" title="Catch4D66" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch4D66.jpg" alt="" width="214" height="28" /></a></p>
<p>clearfix这个命名，恐怕对于大多数的前端工程师都是再熟悉不过的了，这个词基本已经成为清除浮动某种方法的代名词了。当然，这种清除浮动的方法可以用其他命名，这个class也可以用来定其他属性。如果我们的组件恰好的也用了clearfix的命名，那么一定要想办法避免被同样命名的覆盖。在微博的组件中，我们会在所有组件中的class命名上加上我们自己特有的前缀WB_widget， 其余命名：WB_widget_xxxx;虽然看起来这样没有什么节省代码命名上的优势，但是确实可以避免一些简单的class命名重复。当然，如果您偏要修改我们组件的样式，偏偏要定义成和我们这样具有特殊命名的class同名的话，那我们也是拦不住的。</p>
<p><strong>二、继承了多余的属性</strong></p>
<p>再来看看下面几个网站的样式：<br />
eg2某网站：<br />
<a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch1AF6.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1498" title="Catch1AF6" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch1AF6.jpg" alt="" width="183" height="67" /></a></p>
<p>eg3某网站：<br />
<a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch8705.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1503" title="Catch8705" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch8705.jpg" alt="" width="198" height="55" /></a></p>
<p>eg4某网站：<br />
<a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/CatchF5C7.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1505" title="CatchF5C7" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/CatchF5C7.jpg" alt="" width="371" height="151" /></a></p>
<p>eg5某网站：<br />
<a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/CatchB90D.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1504" title="CatchB90D" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/CatchB90D.jpg" alt="" width="245" height="330" /></a></p>
<p>看着上面几个网站的通用写法，这就意味着，如果我们只是简单的定义，那么，我们的文本段落会有边距，我们的链接会有背景色，我们的图片都是块元素单独成一行，我们的文本区域都有着与第三方网站统一的边框，而不是我们定义的颜色……碰到这么多无法称之为样式显示bug的问题，一切都由于我们的组件规范的严谨性。那么如何保证网站对我们用的标签没有特殊定义？这个问题真正思考起来恐怕会得到一个很纠结的答案：除了考虑到我们经常用到的那些css属性之外，我们还要考虑到我们现在爱不释手的css3属性，既然考虑到了css3属性，不可避免的要考虑到各个高级浏览器的兼容问题。<br />
<a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/未标题-4.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1507" title="未标题-4" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/未标题-4.jpg" alt="" width="474" height="154" /></a></p>
<p>纠结之后，恐怕最后得出的结论使我们非常不喜欢的reset周全考虑：</p>
<pre class="brush: php; title: ; notranslate">p { background:transparent;
 border:0;
 bottom:auto;
 clear:none;
 clip:auto;
 color:#333;
 cursor:auto;
 direction:ltr;
 filter:;
 float:none;
 font:normal normal normal 12px/16px &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif;
 height:auto;
 left:auto;
 letter-spacing:normal;
 list-style:none;
 margin:0;
 marks:none;
 max-height:auto;
 max-width:auto;
 min-height:0;
 min-width:0;
 overflow:visible;
 padding:0;
 page:auto;
 position:static;
 quotes:none;
 right:auto;
 -o-set-link-source:none;
 size:auto;
 text-align:left;
 text-decoration:none;
 text-indent:0;
 text-overflow:clip;
 text-shadow:none;
 text-transform:none;
 top:auto;
 vertical-align:baseline;
 visibility:visible;
 white-space:normal;
 width:auto;
 word-spacing:normal;
 word-wrap:normal;
 z-index:auto;
 -webkit-box-shadow:none;
 -moz-box-shadow:none;
 -ms-box-shadow:none;
 -o-box-shadow:none;
 box-shadow:none;
 -webkit-border-radius:0;
 -moz-border-radius:0;
 -ms-border-radius:0;
 -o-border-radius:0;
 border-radius:0;
 -webkit-opacity:1;
 -moz-opacity:1;
 -ms-opacity:1;
 -o-opacity:1;
 opacity:1;
 -webkit-outline:0;
 -moz-outline:0;
 -ms-outline:0;
 -o-outline:0;
 outline:0;
 -webkit-text-size-adjust:none}
</pre>
<p>这么大篇幅的reset，估计也只能说是尽量把常用的考虑进去了；具体还要看使用组件的第三方，网站的样式到底会出现什么样的特殊性。</p>
<p><strong>三、css权重问题</strong></p>
<p>eg6 某网站：<br />
<a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch3984.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1502" title="Catch3984" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch3984.jpg" alt="" width="214" height="24" /></a></p>
<p>我们来回忆一下css写法的权重级别</p>
<p>important &gt; 内联 &gt; ID &gt; 类 &gt; 标签 | 伪类 | 属性选择 &gt; 伪对象 &gt; 继承 &gt; 通配符<br />
<a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch2608.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1501" title="Catch2608" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch2608.jpg" alt="" width="429" height="398" /></a></p>
<p>如果我们的组件是以模块的形式嵌入第三方的网站时，我们通常都以class定义；<br />
思考如何提高我们reset样式的权重，这又是一个很纠结的问题。可能你会说，带着标签定义样式。亲，这个方法确实可行；但是，如果一个网站用id定义了一个公用样式，按着这种权重，恐怕要达到id的同级权重，只能是望尘莫及。可能你会说，那直接用id好了。确实，id的权重数字是很漂亮的，可是id与class的特殊性就在于，id在一个页面中只能出现一次。所以，如果这个组件，在此页面确实只能出现一次，那是再好不过的了。既然是组件，以其小巧灵活为优势，一个页面只出现一次，怎么能够满足我们的需求呢？所以，id的写法也会被否掉。</p>
<p>现在只剩下最让热痛苦的写法了：！important。这个写法确实能保证样式的级别高权重，为了去重写相关样式，覆盖reset中的定义，我们只能不断的用级别最高的定义去覆盖。但是，满篇飘红的样式对于有洁癖的前端工程师来说简直是一种折磨。</p>
<p><a href="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch166F.jpg" rel="lightbox[1497]"><img class="alignnone size-full wp-image-1500" title="Catch166F" src="http://weibodesign-wordpress.stor.sinaapp.com/uploads/2012/08/Catch166F.jpg" alt="" width="563" height="501" /></a></p>
<p>那么，保证css独立的最好办法到底是什么？其实这个办法我们都在用——iframe嵌套。但是此方法，对于需要传递数据的组件不适用。</p>
<p>总而言之，第三方组件想保持独立性一直都是我们在纠结的问题。从第三方的网站出发如此纠结，那我们莫不如从我们的组件出发。<br />
我们可以将组件分为几个很简单的级别：简单的——需要很简单的几个标签及样式就可以完成；这样的组件，我们完全可以只写部分reset的css，定义很少的属性，甚至不定义都不会有大的妨碍。以节省大量的成本。复杂逻辑型——很多小模块组成的组件；就需要多在第三方网站上多下功夫了，努力完善自己组件的公用样式。</p>
<p>说了这么多，组件的样式reset仍然是个偶尔会让我们纠结的事。如果您是第三方网站的站长或者工程师，请记住：不管我们如何管教好我们的样式，重要的是，请您要把我们当做HTML或者XHTML标准下的代码执行，也就是说，切记，要在网站的第一行加上dtd的类型：如<span style="font-family: &#39;Microsoft Yahei&#39;;">&lt;!DOCTYPE HTML&gt;</span>或者其他的类型。</p>
<p>感谢 @青春的猴小野 对组件规范的制定。<br />
如有好的方法，欢迎讨论！</p>
<p><span style="color: #993300;">（<span style="text-decoration: underline;"><a href="http://udc.weibo.com/"><span style="color: #993300; text-decoration: underline;">微博UDC</span></a></span>原创博文，转载请注明出处，欢迎<span style="text-decoration: underline;"><a href="http://www.google.com/ig/add?feedurl=http://udc.weibo.com/feed/"><span style="color: #993300; text-decoration: underline;">订阅</span></a></span> ）</span></p>
]]>
</description>
<dc:creator>微博UDC</dc:creator>
<pubDate>Wed, 22 Aug 2012 14:15:20 +0800</pubDate>
</item>
<item>
<title>CodeIgniter Disallowed Key Characters.</title>
<link>http://www.itfeed.cn/post.asp?id=10423</link>
<description>
<![CDATA[<h2 id="article_nav-0"> CodeIgniter 是什么?</h2>
<ul>
<li>你想要一个小巧的框架。</li>
<li>你需要出色的性能。</li>
<li>你需要广泛兼容标准主机上的各种 PHP 版本和配置。</li>
<li>你想要一个几乎只需 0 配置的框架。</li>
<li>你想要一个不需使用命令行的框架。</li>
<li>你想要一个不需坚守限制性编码规则的框架。</li>
<li>你对 PEAR 这种大规模集成类库不感兴趣。</li>
<li>你不希望被迫学习一门模板语言(虽然可以选择你喜欢的模板解析器)。</li>
<li>你不喜欢复杂，热爱简单。</li>
<li>你需要清晰、完善的文档。</li>
</ul>
<p><a href="http://codeigniter.org.cn/" target="_blank">CodeIgniter</a> 是 <a title="飞鱼" href="http://qilei.org" target="_blank">@飞鱼</a> @给 <a title="余果" href="http://yuguo.us" target="_blank">@余果</a> 又@给我的</p>
<p>&nbsp;</p>
<h2 id="article_nav-1">(庙) miao.in 是基于 CodeIgniter 开发</h2>
<p>改造大概花了个把小时,因为<a href="http://miao.in" target="_blank">(庙)</a>实在是太简单的网站</p>
<p>&nbsp;</p>
<h2 id="article_nav-2">Disallowed Key Characters.</h2>
<p>突然有一天出现了 Disallowed Key Characters. 这个错误,满 Google 都在说,你的 cookie 出现了非法字符</p>
<p>干,老子还没用到 Cookie 呢</p>
<p>打开Chrome调试器发现有个 Cookie 的</p>
<p>Key: 1345466626|7601294|43373|0|0|0</p>
<p>然后用 Intellij IDEA 搜了一下 "Disallowed Key Characters"</p>
<p>在</p>
<blockquote><p>system/core/Input.php line 603</p></blockquote>
<p>写着</p>
<pre><code>if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) { exit(&#39;Disallowed Key Characters.&#39;); }</code></pre>
<p>日哦,身为正则小王子的大猫一看眼泪都流下来</p>
<p>改成了</p>
<p><img title="codeigniter" src="http://cdn.ooxx.me/wp-content/uploads/2012/08/codeigniter.png" alt="" width="763" height="389" /></p>
<p>PS,这"|"不可写到"-"后面,懂的自然懂,不懂照着改</p>
<p>&nbsp;</p>
<h2 id="article_nav-3">那么这个带"|"的 Cookie 哪里来的呢?</h2>
<p>电·信·弹·窗·广·告,我·干·里·良!</p>
<hr />
<p><small>  2012. |
<a href="http://ooxx.me/codeigniter-disallowed-key-characters.orz">Permalink</a> |
<a href="http://ooxx.me/codeigniter-disallowed-key-characters.orz#comments">大战3回合</a> |
Post tags: <a href="http://ooxx.me/tag/bug" rel="tag">bug</a>, <a href="http://ooxx.me/tag/codeigniter" rel="tag">codeigniter</a>, <a href="http://ooxx.me/tag/disallowed-key-characters" rel="tag">Disallowed Key Characters</a> |
<strong><a href="http://miao.in">MediaTemple | (miao) 低调滴华丽主机</a></strong>
</small></p><img src="http://www1.feedsky.com/t1/668097999/bigcat/feedsky/s.gif?r=http://ooxx.me/codeigniter-disallowed-key-characters.orz" border="0" height="0" width="0" style="position:absolute" />]]>
</description>
<dc:creator>大猫的意淫</dc:creator>
<pubDate>Mon, 20 Aug 2012 22:10:51 +0800</pubDate>
</item>
<item>
<title>前端，改变 Front－end makes change</title>
<link>http://www.itfeed.cn/post.asp?id=10399</link>
<description>
<![CDATA[<p>slideshare 杯具了，speakerdeck 火了。好吧我还是用了 slideshare ^!^</p>
<p>部门分享 ⎡前端，改变⎦，一些个人对前端的见解和想法。有兴趣的果断关注下咯。</p>
<blockquote><p>前端是一种介于程序和设计之间的契合，拥有程序严谨逻辑的同时也存在设计的感性，前端是设计师的代码实现更是一门艺术。</p></blockquote>
<p><iframe style="border: 1px solid #CCC; border-width: 1px 1px 0; margin-bottom: 5px;" src="http://www.slideshare.net/slideshow/embed_code/14003245" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="427" height="356"></iframe></p>
<div style="margin-bottom: 5px;"><strong> <a title="Front-end makes change" href="http://www.slideshare.net/keelii/frontend-makes-change" target="_blank">Front-end makes change</a> </strong> from <strong><a href="http://www.slideshare.net/keelii" target="_blank">keelii</a></strong></div>
<p>原文件 (keynote): <a href="http://vdisk.weibo.com/s/aKF_u" target="_blank">http://vdisk.weibo.com/s/aKF_u</a><br />
原文件 (pdf): <a href="http://vdisk.weibo.com/s/aKF_u" target="_blank">http://vdisk.weibo.com/s/aKIBT</a></p>
]]>
</description>
<dc:creator>keelii</dc:creator>
<pubDate>Sat, 18 Aug 2012 08:29:51 +0800</pubDate>
</item>
<item>
<title>第七届D2主题演讲视频资料</title>
<link>http://www.itfeed.cn/post.asp?id=10380</link>
<description>
<![CDATA[<ul>
<li><strong>第三方内容开发最佳实践-(第三方内容开发实战) <em> - | 张立理 (百度) | 权一 (盛大在线) </em></strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NTUxNTky/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NTUxNTky/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NDkzODI0/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NDkzODI0/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>广告投放代码和创意代码持续优化-(第三方内容开发实战) - | 李穆/李牧 (一淘)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0MjM5OTg0/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0MjM5OTg0/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>Qzone前端CPU性能优化（前端性能监控与优化专场） <em> - | 郭润增 (腾讯) </em></strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDMzOTMyMjUy/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDMzOTMyMjUy/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>如何发现前端的性能问题（前端性能监控与优化专场） - | 刘杰/嗷嗷 (淘宝网)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NDUwMzA0/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NDUwMzA0/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>百度前端性能监控与优化实践（前端性能监控与优化专场） - | 李成银 (百度)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0MjQ0MDU2/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0MjQ0MDU2/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>berserkJs（前端性能监控与优化专场） - | 钱宝坤 (新浪微博)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NDg1Njk2/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NDg1Njk2/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>低碳的终端Web开发 - | 李晶/拔赤 (淘宝网) | 王卓/完颜 (一淘-移动UX)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0MjMyMTY0/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0MjMyMTY0/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NTMzMjcy/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NTMzMjcy/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>淘宝开放产品前端实践 - | 周骞/清羽 (淘宝网) | 杨周璇/沉鱼 (淘宝网)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NTU5MjI0/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NTU5MjI0/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NTQ3NjAw/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NTQ3NjAw/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>这些年，我们一起开发过的Node.js - 服务端 JavaScript Web 开发 - | 田永强/朴灵 (淘宝网)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NTE2NDg0/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NTE2NDg0/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>阅读类 Web 应用的前端技术探索 - | 石岩 (豆瓣)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NTA5NDU2/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NTA5NDU2/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>以 Web 的名义，向 App 告白 - | 陈虹如 (腾讯)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDMyNDUzMjk2/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDMyNDUzMjk2/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>百度前端集成解决方案 - | 雷志兴 (百度)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM2MTEwNTA0/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM2MTEwNTA0/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<ul>
<li><strong>编辑器设计思路 —— KindEditor &amp; KISSY Editor &amp; UEditor 大规模组件的模块化开发 - | 战毅 (百度) | 罗龙浩 (土豆网) | 何一鸣/承玉 (淘宝网)</strong></li>
</ul>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NDYzMjk2/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NDYzMjk2/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0MDE4NDY4/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0MDE4NDY4/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://player.youku.com/player.php/sid/XNDM0NTUxODY0/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XNDM0NTUxODY0/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" /></object></p>
]]>
</description>
<dc:creator>D2</dc:creator>
<pubDate>Wed, 15 Aug 2012 17:34:35 +0800</pubDate>
</item>
<item>
<title>inline-block 前世今生</title>
<link>http://www.itfeed.cn/post.asp?id=10379</link>
<description>
<![CDATA[<p>曾几何时，display:inline-block 已经深入「大街小巷」，随处可见 「display:inline-block; *display:inline; *zoom:1; 」这样的代码。如今现代浏览器已经全面支持这个属性值了，上面的代码只是为了兼容 IE6、7 而已。那么你真的了解 inline-block 了吗？本文将带你深入剖析该属性值的前世今生，让你更好的理解和运用 inline-block。（本文约定 display:inline-block 简写为 inline-block）</p>
<p>开篇我们来看几个问题：</p>
<ul>
<li>IE6、7 真的不支持 display:inline-block 吗？</li>
<li>display:inline-block 后的元素为什么会产生水平空隙，这真的是 bug 吗？</li>
<li>如何更好的解决 display:inline-block 元素间产生的水平空隙？</li>
</ul>
<h2>一、inline-block 前世</h2>
<h4><strong>1.认知</strong></h4>
<p>也许有人问你为何要写「 display:inline-block; *display:inline; *zoom:1; 」 来兼容 IE6、7 时，你会立马答道：因为 IE6、7 不支持 display:inline-block 呗!不知道何时起，惯性思维给开发者带来了这样一个可怕的概念。万物都是辩证的，当你写下这些的时候，可曾怀疑过大众观点真的可靠吗？也许你认为这些无关 紧要，实现效果就好。但是如果不能理解每个属性或属性值的根本，你将永远无法全面的了解它，人云亦云只会让你浅尝辄止，止步不前。那么这里就涉及到所谓的 「CSS 学习瓶颈」的问题了，这个问题张鑫旭<a href="http://www.zhangxinxu.com/wordpress/?p=2523" target="_blank">《说说CSS 学习中的瓶颈》</a>一文有详细阐述，虽然部分观点我不是很赞同，但是中心思想还是很值得思考的。文中有几个不错的问题这里也列举出来供大家观摩：</p>
<ol>
<li>line-height:150% 和 line-height:1.5 的区别是？</li>
<li>float 为何会让外部容器高度塌陷？这是 bug？（我的答案在<a title="浮动前世今生，清除浮动综合解决方案" href="http://www.iyunlu.com/view/css-xhtml/55.html" target="_blank">《那些年我们一起清除过的浮动》</a>）</li>
<li>vertical-align 的表现为何在IE7, IE8, IE9 下表现不尽相同？其中的渲染机制是？</li>
</ol>
<p>好了，回到 inline-block 的认知的问题，我的观点是：</p>
<p><strong>IE 从 5.5 开始就已经支持 display:inline-block 了，只是支持的并不是那么完善</strong>。</p>
<p>在 msdn 微软开发者社区，找到了 IE 从5.5 开始支持 inline-block 的证据：</p>
<blockquote style="background: #F8F8F8;"><p>The <strong>inline-block</strong> value is supported starting with Internet Explorer 5.5. You can use this value to give an object a layout without specifying the object&#8217;s height or width.</p></blockquote>
<p>这里明确指出：从 IE5.5 开始支持 inline-block。</p>
<p>链接：<a href="http://msdn.microsoft.com/zh-cn/library/ie/ms530751(v=vs.85).aspx" target="_blank">http://msdn.microsoft.com/zh-cn/library/ie/ms530751(v=vs.85).aspx</a></p>
<p>那么既然 IE5.5 开始就已经支持了 inline-block，为何我们还要写那么一坨 CSS 呢？同时我们知道 IE6、7 中 display:inline-block 是可以触发<a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank"> hasLayout </a>的，触发了 <a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank">hasLayout</a> 的元素表现出来的特征就是一个独立的矩形容器，可以设置宽高而且不受外部元素的影响，类似于现代浏览器中的 Block formatting contexts （块级格式化上下文）的概念。</p>
<p>下面来做一个详细的测试，分别看看 IE6 中 inline 元素和 block 元素的表现：</p>
<p><strong>1）inline 元素 display:inline-block</strong></p>
<p>IE6 中截图如下：</p>
<p><img title="20120809160656" src="http://img04.taobaocdn.com/tps/i4/T1E_DDXihhXXa9b4f4-458-85.png" alt="" /></p>
<blockquote style="background: #F8F8F8;"><p>.dib-inline, .dib-block {<br />
width:100px;<br />
height:30px;<br />
line-height:30px;<br />
text-align:center;<br />
}<br />
.dib-inline {<br />
display:inline-block;<br />
}</p></blockquote>
<p>测试表明：IE6 中 inline 元素只要触发了<a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank"> hasLayout</a> 其表现就类似于 inline-block，这里设置 display:inline-block; 或者 zoom:1; 等其他属性值可以触发 <a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank">hasLayout </a>，表现出来是一样的。</p>
<p><strong></strong><strong><a style="font-size: 22px;" title="测试 IE inline-block 支持情况" href="http://www.iyunlu.com/demo/inline-block-ie/" target="_blank">查看 DEMO</a></strong></p>
<p><strong>2）block 元素 display:inline-block</strong></p>
<p>IE6 中截图如下：</p>
<p><img title="20120809161921" src="http://img02.taobaocdn.com/tps/i2/T1B5rEXXNdXXau2DD4-486-217.png" alt="" width="486" height="217" /></p>
<blockquote style="background: #F8F8F8;"><p>.dib-inline, .dib-block {<br />
width:100px;<br />
height:30px;<br />
line-height:30px;<br />
text-align:center;<br />
}<br />
.dib-block{<br />
display:inline-block;<br />
}</p></blockquote>
<p>测试表明：IE6 中 block 元素即使触发了 hasLayout 也不能具有 inline-block 元素不换行的特性。想要 block 元素支持 inline-block 元素的特性，我们可以这样做：</p>
<blockquote style="background: #F8F8F8;"><p>.dib-block {<br />
display:inline;<br />
zoom:1;<br />
}</p></blockquote>
<p>首先让 block 元素转化为 inline 元素，强制其不换行；然后通过 zoom:1 触发 <a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank">hasLayout</a>，使其可以设置宽高。修复后的 截图如下：</p>
<p><img title="20120809162543" src="http://img03.taobaocdn.com/tps/i3/T1vibEXcheXXbfe2f.-517-91.png" alt="" width="517" height="91" /></p>
<p><strong>3）结合现代浏览器</strong></p>
<p>综上，现代浏览器都支持 display:inline-block ，IE6、7 inline 元素也可以达到同样的效果，IE6、7 block 元素需要设置 display:inline; zoom:1; 它们结合在一起便是：</p>
<blockquote style="background: #F8F8F8;"><p>display:inline-block; /* 现代浏览器 +IE6、7 inline 元素 */<br />
*display:inline; /* IE6、7 block 元素 */<br />
*zoom:1;</p></blockquote>
<p>为了不让支持 CSS2.1 inline-block 的浏览器 重置为 inline，我们针对 IE6、7 做一个 hack。由于现代浏览器也开始支持 zoom 属性，这里只是希望 IE6、7 中生效，所以还是 hack 一下比较合适。至此产生了我们熟悉的兼容各个浏览器的 inline-block 写法。</p>
<p><strong>小结：IE6、7 并不是不支持 inline-block，只是 block 元素需要做一些处理来达到 inline-block 的效果。</strong></p>
<h4><strong>2. 到底什么是 inline-block</strong></h4>
<p>说了很多，或许很多朋友还不是太明白到底什么是 inline-block？W3C 在 CSS2.1 <a href="http://www.w3.org/TR/CSS2/visuren.html#display-prop" target="_blank">The &#8216;display&#8217; property </a>中描述如下：</p>
<blockquote style="background: #F8F8F8;"><p>This value causes an element to generate an inline-level block container. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an atomic inline-level box.</p></blockquote>
<p>大致意思就是：inline-block 后的元素创建了一个行级的块容器，该元素内部（内容）被格式化成一个块元素，同时元素本身则被格式化成一个行内元素。</p>
<p>直白一点的意思就是：inline-block 的元素既具有 block 元素可以设置宽高的特性，同时又具有 inline 元素默认不换行的特性。当然不仅仅是这些特性，比如 inline-block 元素也可以设置 vertical-align 属性。简而言之：</p>
<p><strong>inline-block 后的元素就是一个格式化为行内元素的块容器( Block container )</strong></p>
<p>怎么样？听起来还不错吧！</p>
<h4><strong>3. inline-block 缘从何起？</strong></h4>
<p>前面已经证明了 IE 5.5 开始就支持了 inline-block，那么 IE5.5 是什么时候发布的呢？话说当年网景与 IE 大战，IE5.5 那是何等的风骚……（好吧，此处略去十页）。从<a href="http://zh.wikipedia.org/zh/Internet_Explorer_5" target="_blank">维基百科的资料来</a>看，IE5.5 beta1 的发布时间是：<strong>1999年12月</strong>，最终版本是<strong> 2000年7月</strong>。那么 W3C 标准中是何时才出现 inline-block 这个值的呢？</p>
<p>在 <a href="http://www.w3.org/TR/CSS1/#display">CSS1</a> 规范中，「display」的值仅包括： block | inline | list-item | none 。CSS2.1中才添加了 inline-block 属性值。一丝继续舔着手指，用那苦逼的英语水平终于翻到了这份草案：<a href="http://www.w3.org/TR/2002/WD-CSS21-20020802/visuren.html#display-prop" target="_blank">http://www.w3.org/TR/2002/WD-CSS21-20020802/visuren.html#display-prop</a>， 这份草案的日期是 2002年8月2日，纳尼！！！原来我们纠结了半天的 inline-block ， IE5.5 至少提前两年就提出来了啊！难道是微软给 W3C 提议后，CSS 2.1才加入的？（不过我看到 W3C 官网有一个关于是否增加 inline-block 的投票）好吧这个问题也许有一天 IE 某个开发者写《 IE回忆录》的时候我们才能了解到其中的内幕。如果找到更早关于 inline-block 的 CSS草案，也麻烦告知一丝一声。好吧，如果你还不相信，打微软官方电话问问吧<strong> 800-820-3800</strong>（不是 DHC 哦！）。</p>
<p>原来我们一直讨论的 inline-block 在 IE 6、7中和 CSS2.1 中的（现代浏览器所支持的） inline-block 上压根不是一个东东嘛，IE6、7 中的 inline-block 更像是 IE 的<strong>私有属性值</strong>，他们本身就不具有可比性。简单、绝对的认为 IE6、7 不支持 inline-block 好比一叶障目，看到前面，却看不到后面，太过于片面。诚然，IE6、7 的 <a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank">hasLayout</a> 给我们带来了很多麻烦，但是不得不承认微软的 IE 在网页多语言文本混排上的先进性，尤其是 CJK 文字和西文的混排，超越其他浏览器至少5年。</p>
<p>总结：</p>
<ul>
<li><strong>IE5.5 后开始支持 inline-block， 但是它所支持的 inline-block 不能等同于 CSS2.1 中的 inline-block，因为 IE5.5 比 CSS2.1 更早提出 inline-block 的概念并作为所谓的</strong>「<strong>私有属性值</strong>」<strong>使用，所以二者表现出来的效果是不完全一致。</strong></li>
<li><strong>IE 5.5、6、7 、8（Q）中 block 元素对 inline-block 支持不完整，如果要达到类似的效果，需要先设置为 display:inline，然后使用 zoom:1 </strong><strong>等</strong>触发 <a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank">hasLayout</a>。</li>
<li><strong>IE 5.5、6、7 、8（Q）中 inline 元素欲达到 inline-block 的效果只需直接设置此属性值或使用 zoom:1 等均可。</strong></li>
</ul>
<p>各浏览器对 display 属性的支持情况请参阅：<a href="http://www.w3help.org/zh-cn/causes/RM8001" target="_blank">《各浏览器对 &#8216;display&#8217; 特性值的支持程度不同》</a></p>
<p><img title="inline-block" src="http://img04.taobaocdn.com/tps/i4/T17w2DXoJkXXcGKlgY-552-455.png" alt="" /></p>
<h2>二、inline-block 今生</h2>
<h4><strong>1. display:inline-block 后的元素为什么会产生水平空隙，这真的是 bug 吗？</strong></h4>
<p>这么一个神奇的属性，为何大家一直避而远之呢？这恐怕还得从 inline-block 元素之间产生的水平空隙（间隙）说起吧。</p>
<p><strong><a style="font-size: 22px;" href="http://www.iyunlu.com/demo/inline-block/" target="_blank">参照 DEMO</a></strong></p>
<ul>
<li>现代浏览器中 inline 和 block 元素 display:inline-block 后均会产生水平空隙；<br />
<img title="20120809191739" src="http://img04.taobaocdn.com/tps/i4/T1AobxXlpsXXXtlu.6-451-223.png" alt="" /></li>
<li>IE6、7，IE8（<strong>Q</strong>）模拟 display:inline-block 后分两种情况：<br />
<img title="20120809193036" src="http://img01.taobaocdn.com/tps/i1/T1.EjEXalaXXXxnXr3-411-212.png" alt="" /><br />
IE6、7，IE8（<strong>Q</strong>）中：inline 元素会产生空隙，block 元素不会产生空隙。</li>
</ul>
<p>看看 inline 元素默认的表现情况如何？原来默认就有空隙存在！它们是谁？是空白符（white space）！</p>
<p><img title="untitled" src="http://img02.taobaocdn.com/tps/i2/T1J5bDXk0lXXXhdIga-281-260.png" alt="" /></p>
<p>W3C<a href="http://www.w3.org/TR/html401/struct/text.html#h-9.1" target="_blank"> 9.1 White space </a>中规定以下元素属于空白符（white space）：</p>
<ul>
<li>ASCII 空格 (&amp;#x0020;)</li>
<li>ASCII 制表符 (&amp;#x0009;)</li>
<li>ASCII 换页符 (&amp;#x000C;)</li>
<li>零宽度空格 (&amp;#x200B;)「这个在闭合浮动中也有运用到」</li>
</ul>
<p><a href="http://www.w3.org/TR/html401/struct/text.html#h-9.3.2" target="_blank">9.3.2 Controlling line breaks</a> 中进一步阐述：</p>
<blockquote style="background: #F8F8F8;"><p>A line break is defined to be a carriage return (&amp;#x000D;), a line feed (&amp;#x000A;), or a carriage return/line feed pair. All line breaks constitute <a href="http://www.w3.org/TR/html401/struct/text.html#whitespace">white space.</a></p>
<p>For more information about SGML&#8217;s specification of line breaks, please consult the <a href="http://www.w3.org/TR/html401/appendix/notes.html#notes-line-breaks">notes on line breaks</a> in the appendix.</p></blockquote>
<p>折行被定义为一个回车符（&amp;#x000D;），一个换行符 line feed (&amp;#x000A;)，或者一个回车、换行的组合。所有的折行构成了空白符。</p>
<p>有关 SGML 规范中折行的更多信息，请参阅附录中关于折行的注释。</p>
<p>通常情况下，对于多个连续的空白符（空格，换行符，回车符等），浏览器会将他们合并为一个空白符。CSS 中由 white-space 这个属性来控制：</p>
<p><strong>white-space</strong>：normal | pre | nowrap | pre-wrap | pre-line</p>
<p><strong>默认值</strong>：normal</p>
<ul>
<li>normal：默认处理方式。</li>
<li>pre：用等宽字体显示预先格式化的文本，不合并文字间的空白距离，当文字超出边界时不换行。可查阅 pre 对象</li>
<li>nowrap：强制在同一行内显示所有文本，直到文本结束或者遭遇 br 对象。</li>
<li>pre-wrap：用等宽字体显示预先格式化的文本，不合并文字间的空白距离，当文字碰到边界时发生换行。</li>
<li>pre-line：保持文本的换行，不保留文字间的空白距离，当文字碰到边界时发生换行。</li>
</ul>
<p><img title="20120809200150" src="http://img01.taobaocdn.com/tps/i1/T1ZonDXjdhXXbsqVkO-545-185.png" alt="" width="545" height="185" /></p>
<p>注：IE7及更早浏览器不支持 CSS2.1 新增的 pre-wrap | pre-line。</p>
<p>所以这并不是 inline-block 后产生的 bug，而是因为 inline-block 具有 inline 元素固有的特性。那么为何 IE6、7 block 元素没有产生空隙呢？其实前面也提到了 IE 的 <a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank">hasLayout</a>，具有独立性，所以产生 <a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx" target="_blank">hasLayout</a> 的元素之间表现出来互不影响，这也再次表明 IE6、7 中的 inline-block 不能等同于 CSS2.1 中的 inline-block。如果非要说是有 bug， IE6、7 block 元素 inline-block 后不产生空隙才是 bug。</p>
<p>测试表明删除换行符后，inline 元素间的空隙就「消失」了：</p>
<p><img title="20120809195205" src="http://img03.taobaocdn.com/tps/i3/T1c02yXcRrXXcfLOPm-462-177.png" alt="" /></p>
<h4><strong>2.去掉 inline-block 产生的空隙</strong></h4>
<p>为了让各个浏览器表现一致，更好的还原视觉设计搞，很多时候我们需要去掉 inline-block 产生的空隙。</p>
<p>上一节中我们已经知道产生空隙的根本性原因是：</p>
<p><strong></strong><strong>HTML 中的</strong>换行符、空格符、制表符等产生了空白符，而这些归根结底都是字符，那么它们的大小都是 受 font-size 来控制的，字体大小直接导致 inline 或者 inline-block 后元素之间空隙的大小，把 inline-block 元素间的空隙认为总是某个固定大小是错误的。</p>
<p>用 GIF 动画的形式来表明对应关系：</p>
<p><img title="inline-block-fw" src="http://img01.taobaocdn.com/tps/i1/T1vHvDXdhlXXcyL6DM-583-429.gif" alt="" /></p>
<p>很清楚的看到，当 font-size:0 的时候元素间的空隙都为0了，或许到这里你会感到很欣喜了，原来掌握的根本性原因这么简单就搞定了啊！</p>
<p>然，<strong>理想是丰满的，现实是骨感的。</strong></p>
<p>大部分浏览器是支持 font-size:0 的。很明显，我们要和 IE 6、7 这两个妖孽进行一番战斗。</p>
<p><strong>font-size:0 的支持情况</strong></p>
<p>1）Chrome</p>
<p>低版本的 chrome 浏览器为了不让文字过小不利于阅读，默认是不支持 font-size:0 的，还好我们有 -webkit-text-size-adjust 这个私有属性来控制，当设为 none 时就支持字体大小为 0 了。我已经记不清楚 chrome 从哪个版本开始支持 font-size:0 了，反正我用 chrome 19 是支持了（有知道的朋友，烦请告诉一丝一声，最好有官方更新说明）。但是，<strong>-webkit-text-size-adjust:none; 会直接导致页面文字无法缩放，这对于用户来说显然是不友好的</strong>。所以-webkit-text-size-adjust:none; 一定要慎用，确保使用的地方没有大面积的文字。</p>
<p>-webkit-text-size-adjust:none 的使用场景实例参阅：<a href="http://vip.etao.com/?spm=1002.1.0.20">http://vip.etao.com/</a></p>
<p><img title="20120810130431" src="http://img03.taobaocdn.com/tps/i3/T1W2fuXdFvXXcTzcPn-194-67.png" alt="" /></p>
<p>2）Safari</p>
<p>Safari 5 依旧不支持 font-size:0 ，不过相信这些浏览器厂商都意识到了这个问题，在 Mac 平台最新的 Safari 6 已经很好的支持 font-size:0 了。</p>
<p>3）Firefox，Opera</p>
<p>经测试，Firefox12，Opera 10 ，这次表现不错，支持 font-size:0 。</p>
<p>4）IE</p>
<ul>
<li>IE8 以上支持 font-size:0;</li>
<li>IE6、7 inline 元素 inline-block 后设置 font-size:0 始终有 1px 的空隙。</li>
</ul>
<p>是不是一下子又开始头疼了？没关系，让我们请出<strong> letter-spacing</strong> 和<strong> word-spacing</strong> 二位大神。既然空白符也是字符，那么二位大神肯定是可以搞定它们的。</p>
<ul>
<li><strong>letter-spacing : </strong><strong>normal</strong> | <em>length</em> （检索或设置对象中的文字之间的间隔）</li>
<li><strong>word-spacing : </strong><strong>normal</strong> | <em>length</em>（检索或设置对象中的单词之间插入的空隔）</li>
</ul>
<p>normal： 默认间隔<br />
length： 用长度值指定间隔，允许为负值。</p>
<p>还等什么，我们赶紧试试吧：</p>
<p><strong><a style="font-size: 22px;" href="http://www.iyunlu.com/demo/inline-block/" target="_blank">参照 DEMO</a></strong></p>
<ul>
<li>第一步：使用 font-size:0经测试发现，chrome、firefox、IE8+、opera，inline 或 block 元素都没有空隙了；<br />
<strong></strong><strong>Safari 5.1.7 由于不支持 font-size:0 ，仍然存在空隙；<br />
</strong><br />
<img title="20120810110115" src="http://img01.taobaocdn.com/tps/i1/T1vMDEXdVdXXaUzt.H-435-208.png" alt="" /><br />
IE6、7、8（Q），inline 元素 inline-block 后始终存在 1px 左右的空隙。<img title="20120810105828" src="http://img02.taobaocdn.com/tps/i2/T1hhvEXeVdXXaW9Fn3-411-208.png" alt="" /></li>
<li>第二步：处理 Safari 不支持 font-size:0 的问题上面已经指出 letter-spacing 是支持负值的，那么这个负值到底取多少合适呢？经过测试得出的结论是：<strong>inline-block 产生的空隙与父级元素继承或者设定的 font-family、font-size 有关，通常情况下，12px 大小的 tahoma 字体，inline-block 后元素间产生的空隙（间隙）大约是 5px；<br />
</strong>各个字体详细情况请参阅<a href="http://www.iyunlu.com/view/css-xhtml/58.html" target="_blank">《inline-block空隙&#8211;letter-spacing与字体大小/字体关系数据表》</a><strong></strong><strong>。</strong>Firefox 中 letter-spacing 负值的绝对值大于空隙大小后，会导致元素整体位置向右偏移；<img title="inline-block-pianyi-fw" src="http://img03.taobaocdn.com/tps/i3/T1jKnDXltkXXbXypr2-589-273.gif" alt="" /><br />
<strong>Safari 中 letter-spacing 负值的绝对值大于空隙大小后，内部会发生重叠。</strong><img title="20120810113236" src="http://img02.taobaocdn.com/tps/i2/T1HCDEXdtbXXbq_JE9-345-170.png" alt="" /></li>
<li>第三步：修复 IE6、7 中始终存在的 1px 空隙<br />
既然 letter-spacing 已经无能为力了，那就试试 word-spacing 吧，直接设置 word-spacing:-1px。这里需要注意的是，letter-spacing 和 word-spacing 同时使用可能导致冲突，所以我们需要在 IE6、7 中 hack 掉 letter-spacing。最终代码如下：</li>
</ul>
<blockquote style="background: #F8F8F8;"><p>font-size:0;/* 所有浏览器 */<br />
letter-spacing:-5px;/* Safari 等不支持字体大小为 0 的浏览器 */<br />
*letter-spacing:normal;<br />
word-spacing:-1px;/* IE6、7 */</p></blockquote>
<ul>
<li>第四步：子元素重置回正常值<br />
上述所有操作都是在父元素设置的，那么子元素都会继承这些属性，字体大小为0了，子元素就什么都看不到了，这并不是我们想要的。 同时字符和单词间距我们也要把它重置为默认值。「font-size: 12px; letter-spacing: normal; word-spacing: normal;」</li>
<li>最后：inline-block 更好的复用<br />
或许你会担心每次我都要去看字体和空隙之间大小的关系吗？其实不然，通常情况下，全局字体都已经在 body 中指定了，根据全局字体设置合适的 letter-spacing 负值即可。如此一来，我们便可以放心大胆的使用 inline-block 了，结合 OOCSS 的思想，可以抽离出两个复用的类，在需要设置 inline-block 元素的父级元素上定义一个<strong>「.dib-wrap」</strong>，该元素自身定义为<strong>「.dib」</strong>。这里还有一个问题需要注意的是：由于 inline-block 具有 inline 元素的特性，在垂直方向上很多时候我们并不希望元素以<strong></strong><strong>「vertical-align:baseline」</strong>方式来呈现，所以在<strong>「.dib-wrap」</strong>中统一重置为<strong>「vertical-align:top」</strong>即可。</li>
</ul>
<h4><strong>3. 去除 inline-block 空隙终极解决方案</strong></h4>
<blockquote style="background: #F8F8F8;"><p>.dib {<br />
display: inline-block;<br />
*display:inline;<br />
*zoom:1;<br />
}<br />
.dib-wrap {<br />
font-size:0;/* 所有浏览器 */<br />
letter-spacing:-Npx;/* Safari 等不支持字体大小为 0 的浏览器 N 根据父级字体调节*/<br />
*letter-spacing:normal;<br />
word-spacing:-1px;/* IE6、7 */<br />
}<br />
.dib-wrap .dib{<br />
font-size: 12px;<br />
letter-spacing: normal;<br />
word-spacing: normal;<br />
vertical-align: top;<br />
}</p></blockquote>
<p>其实在<a href="http://yui.yahooapis.com/3.5.1/build/cssgrids/grids.css" target="_blank"> YUI 3 </a>中也全面运用了 inline-block 作为基础布局，<a href="http://yui.yahooapis.com/3.5.1/build/cssgrids/grids.css" target="_blank">YUI 3</a> 是这样解决的：</p>
<blockquote style="background: #F8F8F8;"><p>.yui3-g {<br />
letter-spacing: -0.31em; /* webkit: collapse white-space between units */<br />
*letter-spacing: normal; /* reset IE &lt; 8 */<br />
word-spacing: -0.43em; /* IE &lt; 8 &amp;&amp; gecko: collapse white-space between units */<br />
}</p>
<p>.yui3-u {<br />
display: inline-block;<br />
zoom: 1; *display: inline; /* IE &lt; 8: fake inline-block */<br />
letter-spacing: normal;<br />
word-spacing: normal;<br />
vertical-align: top;<br />
}</p></blockquote>
<p>显然，这里纯粹使用了 letter-spacing 和 word-spacing 来控制元素间的空隙，局限性极大，-0.31em 和 -0.43em 只是因为 YUI 3 全局<a href="http://yui.yahooapis.com/3.6.0/build/cssfonts/cssfonts.css" target="_blank"> cssfonts.css </a>里设置是：「body { font:13px/1.231 arial,helvetica,clean,sans-serif; }」。</p>
<p>当然，如果你坚持使用把 html 写在一行的方式来达到去除 inline-block 空隙的目的，我只能说：<strong>一切以</strong><strong>牺牲</strong><strong>结构来兼容表现的行为都是耍流氓</strong>！所以探讨此种方式去除空隙也将是无意义的，不在本文和作者考虑范围之内。</p>
<h4><strong>4. 结局——本文产生的一些观点如下：</strong></h4>
<ul>
<li><strong>IE5.5 后开始支持 inline-block，</strong><strong> 比 CSS2.1 更早提出 inline-block 的概念并作为所谓的</strong>「<strong>私有属性值</strong>」<strong>使用。</strong><strong>但是它所支持的 inline-block 不能等同于 CSS2.1 中的 inline-block</strong><strong>，</strong><strong>IE 5.5、6、7 、8（Q）中 block 元素对 inline-block 支持不完整，</strong><strong></strong><strong>因此二者表现出来的效果是不完全一致。</strong></li>
<li><strong></strong><strong>产生 inline-block 空隙的根本性原因是：HTML 中的换行符、空格符、制表符等合并为空白符，字体大小不为 0 的情况下，空白符自然占据一定的宽度，因此产生了元素间的空隙。</strong></li>
<li><strong>慎用 -webkit-text-size-adjust:none，它将会导致页面无法通过缩放来改变字体大小。</strong></li>
</ul>
<h2>三、inline-block 未来</h2>
<p>如今，Mac 平台下的 Safari 6 已经支持 font-size:0 了，相信很快 Windows 平台的 Safari 如果发布 5.X 的更新，也会支持字体为 font-size:0 了。等到 IE6、7 灭亡之后，世界就真真儿的美妙了！最后说一点：<strong>inline-block 与 float 也是无法直接比较的，请不要再讨论 inline-block 和 float 哪个更好的话题了。</strong>inline-block 从 IE5.5 一路走来，存在即是合理，以后有时间在总结一下 inline-block 与 float 的使用场景的区别。</p>
<p>在不改变 CSS 定位机制的前提下，inline-block 应该是首选，而不是以「奇淫技巧」存在的。有感打油诗一首：</p>
<p style="text-align: center;">网事如烟<br />
CSS 红尘里<br />
inline-block 知多少<br />
你在这头<br />
inline-block 在那头<br />
用与不用<br />
它就在那里<br />
不悲不喜</p>
<p>PS：</p>
<ol>
<li>为了更好的排版，本文使用繁体中文引号 「」代替简体中文小蝌蚪引号；</li>
<li>中英文混排的时候英文首尾各加一个空格；</li>
<li>以后文章有需要的时候也都将使用 gif 动画配合说明。</li>
</ol>
<h2>测试环境</h2>
<table>
<tbody>
<tr>
<th>操作系统版本:</th>
<td> Windows 7 企业版 6.1（内部版本 7600）</td>
</tr>
<tr>
<th>浏览器版本:</th>
<td>IE6<br />
IE9<br />
Firefox 14.0.1<br />
Chrome 19.0.1084.46<br />
Safari 5.1.7(7534.57.2)<br />
Opera 12.50</td>
</tr>
<tr>
<th>最后更新时间:</th>
<td> 2012-8-15</td>
</tr>
</tbody>
</table>
<p style="text-align: right;">一丝<br />
2012-8-10 于杭州</p>
]]>
</description>
<dc:creator>淘宝UED</dc:creator>
<pubDate>Wed, 15 Aug 2012 19:23:32 +0800</pubDate>
</item>
<item>
<title>HTML大纲算法对结构的影响</title>
<link>http://www.itfeed.cn/post.asp?id=10368</link>
<description>
<![CDATA[<p><img alt="HTML大纲算法对结构的影响" class="alignnone size-full wp-image-2941" height="250" src="http://cued.xunlei.com/wp-content/uploads/2012/08/outliner-b.jpg" width="650" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p style="padding: 5px 0">HTML5已经出来好长时间了，越来越多人希望并且开始把HTML5应用到平时的工作、个站中。大家对section、article、aside、nav等新标签的使用也越来越上手，也许是自我感觉良好的上手。不从多个方面去认识理解这些标签，可能反而让自己落入了更混乱的境地。HTML的大纲算法(outlining algorithm)就是一个很重要的切入点。</p>
<p style="padding: 5px 0">先看两个大纲：</p>
<p style="padding: 5px 0"><img alt="" class="aligncenter size-full wp-image-2883" height="547" src="http://cued.xunlei.com/wp-content/uploads/2012/08/outliner-1.jpg" width="650" /></p>
<p style="padding: 5px 0"><img alt="" class="aligncenter size-full wp-image-2883" height="554" src="http://cued.xunlei.com/wp-content/uploads/2012/08/outliner-2.jpg" width="650" /></p>
<p style="padding: 5px 0">这两个都是我早期的作品了。当时还觉得自己的结构写的不错，特别是第二个，还用上了HTML5标签，以为自己就踏进这个新世界了。看过HTML大纲算法之后，检测了一下这些页面，真的是惨不忍睹。第一个各种混乱标题不说，&ldquo;主创阵容&rdquo;居然从属于&ldquo;用户评论&rdquo;？第二个也不好发言了，那么多未命名的是什么东西？不过总是要踩在伤痛的历史上才能往前进。</p>
<p style="padding: 5px 0">再来看几个其他人重构的页面大纲：</p>
<p style="padding: 5px 0"><img alt="" class="aligncenter size-full wp-image-2883" height="546" src="http://cued.xunlei.com/wp-content/uploads/2012/08/outliner-3.jpg" width="650" /></p>
<p style="padding: 5px 0"><img alt="" class="aligncenter size-full wp-image-2883" height="434" src="http://cued.xunlei.com/wp-content/uploads/2012/08/outliner-4.jpg" width="650" /></p>
<p style="padding: 5px 0"><img alt="" class="aligncenter size-full wp-image-2883" height="536" src="http://cued.xunlei.com/wp-content/uploads/2012/08/outliner-5.jpg" width="650" /></p>
<p style="padding: 5px 0">想象你是一个有点视力障碍的用户，需要依靠屏幕阅读器来浏览这些网页，阅读器会按照层级来给你解读这个网页，你觉得上面那个网页更容易让你获得所需要的资讯呢？也许对比完大家更想知道大纲算法到底是个怎么样的东西了吧？</p>
<h4 style="padding: 15px 0 5px 0;font-size: 130%;font-weight: bold">什么是HTML大纲算法？</h4>
<p style="padding: 5px 0">大纲算法允许用户代理(user agent)从一个web页面生成一个信息结构目录，让用户对页面有一个快速的概览。类似书籍、PDF、帮助文档等，都有一个清晰的目录结构，用户能方便的定位所需内容。一个良好结构的大纲，不仅是对于搜索引擎的优化，更是为借助于屏幕阅读器浏览网页的盲人（或弱视力）用户提供了巨大的帮助。</p>
<p style="padding: 5px 0">帮助文档的目录结构：</p>
<p style="padding: 5px 0"><img alt="" class="aligncenter size-full wp-image-2883" height="220" src="http://cued.xunlei.com/wp-content/uploads/2012/08/outliner.jpg" width="226" /></p>
<p style="padding: 5px 0">每个页面都有大纲，先从一个简单的例子来了解web页面大纲吧。假设要做一个电影介绍页面，主题是8月电影推介，页面结构也许如下：</p>
<pre>1.8月电影推介
  1.国内电影
    1.《四大名捕》
    2.《搜索》
  2.国外电影
    1.《冰川时代4》
    2.《在劫难逃》
</pre>
<p style="padding: 5px 0">HTML4或者之前，我们都是采用hn（h1~h6）来生成大纲的。HTML5引入了section、article、aside、nav等新的节点元素(sectioning content)，添加了一些新的规则，后面会详细阐述。</p>
<h4 style="padding: 15px 0 5px 0;font-size: 130%;font-weight: bold">hn生成的大纲</h4>
<p style="padding: 5px 0">也许HTML4的结构会这样写：</p>
<pre>&lt;div&gt;
  &lt;h1&gt;8月电影推介&lt;/h1&gt;

  &lt;h2&gt;国内电影&lt;/h2&gt;
  &lt;h3&gt;《四大名捕》&lt;/h3&gt;
  &lt;p&gt;四大名捕讲的是..&lt;/p&gt;
  &lt;h3&gt;《搜索》&lt;/h3&gt;
  &lt;p&gt;搜索讲的是..&lt;/p&gt;

  &lt;h2&gt;国外电影&lt;/h2&gt;
  &lt;h3&gt;《冰川时代4》&lt;/h3&gt;
  &lt;p&gt;冰川时代4讲的是..&lt;/p&gt;
  &lt;h3&gt;《在劫难逃》&lt;/h3&gt;
  &lt;p&gt;在劫难逃讲的是..&lt;/p&gt;

  &lt;p&gt;以上内容由迅雷看看提供&lt;/p&gt;
&lt;div&gt;
</pre>
<p style="padding: 5px 0">可以看出，网页大纲由标题的层级来生成。</p>
<p style="padding: 5px 0">如果想要查看这段代码的大纲，可以试试Geoffrey Sneddon做的大纲工具<a href="http://gsnedders.html5.org/outliner/" target="_blank" title="查看大纲的牛逼工具"><span style="color: #FF0000">Outliner</span></a><span style="color: #FF0000">（强烈推荐）</span>，上传文件和输入片段代码都可以。如果想要查看在线网页的大纲，可以给浏览器安装插件：chrome：HTML5 Outliner<span style="color: #FF0000">（推荐）</span>/ Web Devoloper，firefox：Web Devoloper；opera：HTML5 Outliner。<span style="text-decoration: underline">（HTML5 Outliner里中文会显示乱码，建议换成英文测试。浏览器插件可以显示中文）</span></p>
<p style="padding: 5px 0">每个标题都会生成一个隐性节点(implicit section)，紧随其后的相对层级低的标题会成为它的子节点，层级相同或者更高的标题则会关闭这个节点并生成新的节点。可以测试一下下面的代码：</p>
<pre>&lt;h3&gt;《四大名捕》&lt;/h3&gt;
&lt;p&gt;四大名捕讲的是..&lt;/p&gt;
&lt;h3&gt;《搜索》&lt;/h3&gt;
&lt;p&gt;搜索讲的是..&lt;/p&gt;
</pre>
<p style="padding: 5px 0">或者：</p>
<pre>&lt;h3&gt;《搜索》&lt;/h3&gt;
&lt;p&gt;搜索讲的是..&lt;/p&gt;
&lt;h2&gt;国外电影&lt;/h2&gt;
</pre>
<h4 style="padding: 15px 0 5px 0;font-size: 130%;font-weight: bold">节点元素生成的大纲</h4>
<p style="padding: 5px 0">也许HTML5的结构会这样写：</p>
<pre>&lt;div&gt;
  &lt;h6&gt;8月电影推介&lt;/h6&gt;

  &lt;section&gt;
    &lt;h1&gt;国内电影&lt;/h1&gt;
    &lt;article&gt;
      &lt;h1&gt;《四大名捕》&lt;/h1&gt;
      &lt;p&gt;四大名捕讲的是..&lt;/p&gt;
    &lt;/article&gt;
    &lt;article&gt;
      &lt;h3&gt;《搜索》&lt;/h3&gt;
      &lt;p&gt;搜索讲的是..&lt;/p&gt;
    &lt;/article&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h5&gt;国外电影&lt;/h5&gt;
    &lt;article&gt;
      &lt;h6&gt;《冰川时代4》&lt;/h6&gt;
      &lt;p&gt;冰川时代4讲的是..&lt;/p&gt;
    &lt;/article&gt;
    &lt;article&gt;
      &lt;h1&gt;《在劫难逃》&lt;/h1&gt;
      &lt;p&gt;在劫难逃讲的是..&lt;/p&gt;
    &lt;/article&gt;
  &lt;/section&gt;

  &lt;p&gt;以上内容由迅雷看看提供&lt;/p&gt;
&lt;div&gt;
</pre>
<p style="padding: 5px 0"><span style="text-decoration: underline">（可以先注意一下上面这段代码的各个hn）</span>把代码复制到<a href="http://gsnedders.html5.org/outliner/" target="_blank" title="查看大纲的牛逼工具">Outliner</a>工具去查看，很惊讶的发现，生成的大纲跟层级写的很漂亮的HTML4一样。为什么hn的层级在这里没有表现出来？</p>
<p style="padding: 5px 0">原因是此时大纲是由节点元素生成的，而非标题元素。HTML5的新标签section、article、aside、nav会生成显性节点(explicit sections)，每个显性节点内部又有它自己的标题结构（当然也符合HTML4、HTML5大纲算法）。这也就是为什么HTML5允许多个h1存在的原因，不过，在全部浏览器、屏幕阅读器都完美支持HTML5之前，建议还是需要同时考虑标题结构，优雅降级。所以上面的结构可以改成这样：</p>
<pre>&lt;div&gt;
  &lt;h1&gt;8月电影推介&lt;/h1&gt;

  &lt;section&gt;
    &lt;h2&gt;国内电影&lt;/h2&gt;
    &lt;article&gt;
      &lt;h3&gt;《四大名捕》&lt;/h3&gt;
      &lt;p&gt;四大名捕讲的是..&lt;/p&gt;
    &lt;/article&gt;
    &lt;article&gt;
      &lt;h3&gt;《搜索》&lt;/h3&gt;
      &lt;p&gt;搜索讲的是..&lt;/p&gt;
    &lt;/article&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h2&gt;国外电影&lt;/h2&gt;
    &lt;article&gt;
      &lt;h3&gt;《冰川时代4》&lt;/h3&gt;
      &lt;p&gt;冰川时代4讲的是..&lt;/p&gt;
    &lt;/article&gt;
    &lt;article&gt;
      &lt;h3&gt;《在劫难逃》&lt;/h3&gt;
      &lt;p&gt;在劫难逃讲的是..&lt;/p&gt;
    &lt;/article&gt;
  &lt;/section&gt;

  &lt;p&gt;以上内容由迅雷看看提供&lt;/p&gt;
&lt;div&gt;
</pre>
<p style="padding: 5px 0">这里有另外一个问题值得注意，就是&ldquo;以上内容由迅雷看看提供&rdquo;这段话指的是上面的哪部分内容？在HTML4结构里，这段话是从属于隐性节点&ldquo;《在劫难逃》&rdquo;的，但明显不对。HTML5大纲算法就很好地解决了这个问题。</p>
<h4 style="padding: 15px 0 5px 0;font-size: 130%;font-weight: bold">hn和节点元素同时生成大纲</h4>
<p style="padding: 5px 0">如果页面里既有隐性节点（h1~h6）又有显性节点（section等），大纲又会如何生成呢？只要记住一点：显性节点能包含隐性节点，反之则不行。</p>
<pre>&lt;h1&gt;8月电影推介&lt;/h1&gt;
&lt;section&gt;
  &lt;h2&gt;国内电影&lt;/h2&gt;
  &lt;h3&gt;《四大名捕》&lt;/h3&gt;
  &lt;p&gt;四大名捕讲的是..&lt;/p&gt;
  &lt;h3&gt;《搜索》&lt;/h3&gt;
  &lt;p&gt;搜索讲的是..&lt;/p&gt;
&lt;/section&gt;
</pre>
<p>（代码1）</p>
<p style="padding: 5px 0">这段代码的大纲会是：</p>
<pre>1.8月电影推介
  1.国内电影
    1.《四大名捕》
    2.《搜索》
</pre>
<p style="padding: 5px 0">&nbsp;</p>
<pre>&lt;h1&gt;8月电影推介&lt;/h1&gt;
&lt;h2&gt;国内电影&lt;/h2&gt;
&lt;article&gt;
  &lt;h3&gt;《四大名捕》&lt;/h3&gt;
  &lt;p&gt;四大名捕讲的是..&lt;/p&gt;
&lt;/article&gt;
&lt;article&gt;
  &lt;h3&gt;《搜索》&lt;/h3&gt;
  &lt;p&gt;搜索讲的是..&lt;/p&gt;
&lt;/article&gt;
</pre>
<p style="padding: 5px 0">然而这段代码的大纲会是：</p>
<pre>1.8月电影推介
  1.国内电影
  2.《四大名捕》
  3.《搜索》
</pre>
<p style="padding: 5px 0">由标题元素生成的隐性节点遇上由节点元素生成的显性节点就会关闭并生成下一个同级节点。</p>
<h4 style="padding: 15px 0 5px 0;font-size: 130%;font-weight: bold">未命名节点(untitled sections)</h4>
<p style="padding: 5px 0">HTML5新节点元素除了section、article还有aside、nav，我们也来使用一下。</p>
<pre>&lt;nav&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;首页&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;专题&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;关于&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/nav&gt;
&lt;h1&gt;8月电影推介&lt;/h1&gt;
&lt;section&gt;
  &lt;h2&gt;国内电影&lt;/h2&gt;
&lt;/section&gt;
&lt;section&gt;
  &lt;h2&gt;国外电影&lt;/h2&gt;
&lt;/section&gt;
</pre>
<p style="padding: 5px 0">复制到outliner会发现， nav标签会产生一个untitled section，因为nav里并没有给予任何标题元素。这不是错误也不会被认为是不好的HTML5结构。但是section、article还是建议给予适当的标题。如果不确定可以给予什么标题，也许使用div更适合，不要忘了我们还有div啊。</p>
<h4 style="padding: 15px 0 5px 0;font-size: 130%;font-weight: bold">根节点</h4>
<p style="padding: 5px 0">前面提到一个重要的原则：显性节点能包含隐性节点，反之则不行。也许你会注意代码1生成的大纲：</p>
<pre>1.8月电影推介
  1.国内电影
    1.《四大名捕》
    2.《搜索》
</pre>
<p style="padding: 5px 0">标题元素h1（&ldquo;8月电影推介&rdquo;）下紧跟着的节点元素section（&ldquo;国内电影&rdquo;），变成了它的一个子节点。隐性节点不是不能包含显性节点么？这时候就需要认识一下根节点了。</p>
<p style="padding: 5px 0">根节点可以生成自己的大纲，它的标题和节点对祖先的大纲没有任何影响（而且不会出现在祖先大纲里）。目前有六个根节点：</p>
<p>1.body</p>
<p>2.blockquote</p>
<p>3.details</p>
<p>4.fieldset</p>
<p>5.figure</p>
<p>6.td</p>
<p style="padding: 5px 0">可以测试一下：</p>
<pre>&lt;h1&gt;我是老大 I&#39;m the big brother&lt;/h1&gt;
&lt;blockquote&gt;
  &lt;section&gt;
    &lt;h1&gt;我是blockquote里的老大，待会你看不到我了 I&#39;m the big brother in blockquote,you&#39;ll not find me in the outliner&lt;/h1&gt;
  &lt;/section&gt;
&lt;/blockquote&gt;
&lt;h2&gt;我是老二 I&#39;m the younger&lt;/h2&gt;
</pre>
<p style="padding: 5px 0">定义文档里说明了：节点元素是离它最近的祖先根节点或节点元素的子节点。代码1里的标题元素h1（&ldquo;8月电影推介&rdquo;）是body的标题，节点元素section（&ldquo;国内电影&rdquo;）是body的子节点。</p>
<p style="padding: 5px 0">还有一个很重要的：文档的标题是文档中第一个且非节点元素里的标题元素。测试一下下面的代码就很明了了：</p>
<pre>&lt;section&gt;
  &lt;h1&gt;我很想成为文档的标题可惜不能 I want to be the title but I couldn&#39;t&lt;/h1&gt;
&lt;/section&gt;
&lt;h6&gt;虽然我层级最小可是我是第一个出现的 I&#39;m h6 but I come first&lt;/h6&gt;
&lt;h1&gt;最大也没用顺序我还是在老6下面 I&#39;m h1 but I come after h6&lt;/h1&gt;
</pre>
<p style="padding: 5px 0">过程中我还遇到过另一个让我迷惑的：</p>
<pre>&lt;section&gt;
  &lt;h1&gt;我很想成为文档的标题可惜不能 I want to be the title but I couldn&#39;t&lt;/h1&gt;
&lt;/section&gt;
&lt;section&gt;
  &lt;h2&gt;我也很想成为文档的标题可惜不能 Me either:(&lt;/h2&gt;
&lt;/section&gt;
&lt;footer&gt;
  &lt;h3&gt;我是footer可是为什么我成为了文档标题啊 I&#39;m footer but why I become the title??&lt;/h3&gt;
&lt;/footer&gt;
</pre>
<p style="padding: 5px 0">原因很简单，header和footer不是节点元素。</p>
<h4 style="padding: 15px 0 5px 0;font-size: 130%;font-weight: bold">hgroup</h4>
<p style="padding: 5px 0">hgroup很好理解也很好用，它的作用就是帮你添加副标题而不影响文档大纲，大纲中只会出现层级最高的标题，无论出现顺序。</p>
<pre>&lt;hgroup&gt;
  &lt;h3&gt;我是副标题，我很重要但我不会出现在大纲中 I&#39;m your loved second title,I&#39;m useful and I won&#39;t appear in the outliner&lt;/h3&gt;
  &lt;h2&gt;我是大标题，我是故意跑到下面来的 I&#39;m the highest level of hn in the group,no matter where I am,I will be part of ouliner&lt;/h2&gt;
&lt;/hgroup&gt;
</pre>
<h4 style="padding: 15px 0 5px 0;font-size: 130%;font-weight: bold">总结</h4>
<p style="padding: 5px 0">到写完这篇文章为止，好像还没有哪个浏览器是完美支持HTML5大纲算法的。但这不影响我们对HTML5大纲算法的学习，就像我们现在在努力使用HTML5+CSS3一样。理解了HTML5大纲算法，不仅对于新标签的使用有更进一步的认识，而且对于最根本的页面结构有更优化的理解，就算只是标题元素生成的大纲，也能拥有完美的层级结构，这也是语义化的一个标志。</p>
<p style="padding: 5px 0">特别感谢一下大安仔，是他提醒我要注意这个问题的。</p>
]]>
</description>
<dc:creator>迅雷cued</dc:creator>
<pubDate>Tue, 14 Aug 2012 15:56:09 +0800</pubDate>
</item>
<item>
<title>深入理解JavaScript定时机制</title>
<link>http://www.itfeed.cn/post.asp?id=10366</link>
<description>
<![CDATA[<p>JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">alert</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&#39;</span><span style="color: Red;">你好!</span><span style="color: #8b0000;">&#39;</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">, </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">setInterval</span><span style="color: Olive;">(</span><span style="color: Blue;">callbackFunction</span><span style="color: Gray;">, </span><span style="color: Maroon;">100</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li></ol></div>
<p>认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaScript API文档明确定义第二个参数意义为隔多少毫秒后,回调方法就会被执行. 这里设成0毫秒,理所当然就立即被执行了.<br />
同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不疑!</p>
<p>但随着JavaScript应用开发经验不断的增加和丰富,有一天你发现了一段怪异的代码而百思不得其解:</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">div</span><span style="color: Gray;">.</span><span style="color: Blue;">onclick</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">getElementById</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&#39;</span><span style="color: Red;">inputField</span><span style="color: #8b0000;">&#39;</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">focus</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">, </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li></ol></div>
<p>既然是0毫秒后执行,那么还用setTimeout干什么, 此刻, 坚定的信念已开始动摇.<br />
<span id="more-1054"></span><br />
直到最后某一天 , 你不小心写了一段糟糕的代码:</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">while</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Green;">true</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">, </span><span style="color: Maroon;">100</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">()</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">alert</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&#39;</span><span style="color: Red;">你好!</span><span style="color: #8b0000;">&#39;</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">, </span><span style="color: Maroon;">200</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">setInterval</span><span style="color: Olive;">(</span><span style="color: Blue;">callbackFunction</span><span style="color: Gray;">, </span><span style="color: Maroon;">200</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li></ol></div>
<p>第一行代码进入了死循环,但不久你就会发现,第二,第三行并不是预料中的事情,alert问候未见出现,callbacKFunction也杳无音讯!</p>
<p>这时你彻底迷惘了,这种情景是难以接受的,因为改变长久以来既定的认知去接受新思想的过程是痛苦的,但情事实摆在眼前,对JavaScript真理的探求并不会因为痛苦而停止,下面让我们来展开JavaScript线程和定时器探索之旅!</p>
<p>拔开云雾见月明</p>
<p>出现上面所有误区的最主要一个原因是:潜意识中认为,JavaScript引擎有多个线程在执行,JavaScript的定时器回调函数是异步执行的.</p>
<p>而事实上的,JavaScript使用了障眼法,在多数时候骗过了我们的眼睛,这里背光得澄清一个事实:</p>
<p>JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序.</p>
<p>JavaScript引擎用单线程运行也是有意义的,单线程不必理会线程同步这些复杂的问题,问题得到简化.</p>
<p>那么单线程的JavaScript引擎是怎么配合浏览器内核处理这些定时器和响应浏览器事件的呢?<br />
下面结合浏览器内核处理方式简单说明.</p>
<p>浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假如某一浏览器内核的实现至少有三个常驻线程:javascript引擎线程,界面渲染线程,浏览器事件触发线程,除些以外,也有一些执行完就终止的线程,如Http请求线程,这些异步线程都会产生不同的异步事件,下面通过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通信的.虽然每个浏览器内核实现细节不同,但这其中的调用原理都是大同小异.</p>
<p><img src="http://leotheme.cn/wp-content/uploads/2012/08/21502VQ4-0.jpg" alt="" title="21502VQ4-0" width="674" height="368" class="alignright size-full wp-image-1058" /></p>
<p>Js线程图示</p>
<p>由图可看出,浏览器中的JavaScript引擎是基于事件驱动的,这里的事件可看作是浏览器派给它的各种任务,这些任务可以源自JavaScript引擎当前执行的代码块,如调用setTimeout添加一个任务,也可来自浏览器内核的其它线程,如界面元素鼠标点击事件,定时触发器时间到达通知,异步请求状态变更通知等.从代码角度看来任务实体就是各种回调函数,JavaScript引擎一直等待着任务队列中任务的到来.由于单线程关系,这些任务得进行排队,一个接着一个被引擎处理.</p>
<p>上图t1-t2..tn表示不同的时间点,tn下面对应的小方块代表该时间点的任务,假设现在是t1时刻,引擎运行在t1对应的任务方块代码内,在这个时间点内,我们来描述一下浏览器内核其它线程的状态.</p>
<p>t1时刻:</p>
<p>GUI渲染线程:</p>
<p>该线程负责渲染浏览器界面HTML元素,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行.本文虽然重点解释JavaScript定时机制,但这时有必要说说渲染线程,因为该线程与JavaScript引擎线程是互斥的,这容易理解,因为JavaScript脚本是可操纵DOM元素,在修改这些元素属性同时渲染界面,那么渲染线程前后获得的元素数据就可能不一致了.</p>
<p>在JavaScript引擎运行脚本期间,浏览器渲染线程都是处于挂起状态的,也就是说被&#8221;冻结&#8221;了.</p>
<p>所以,在脚本中执行对界面进行更新操作,如添加结点,删除结点或改变结点的外观等更新并不会立即体现出来,这些操作将保存在一个队列中,待JavaScript引擎空闲时才有机会渲染出来.</p>
<p>GUI事件触发线程:</p>
<p>JavaScript脚本的执行不影响html元素事件的触发,在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成一个鼠标点击事件,由图可知,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标点击事件正在等待处理.</p>
<p>定时触发线程:</p>
<p>注意这里的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就计不了时,它必须依赖外部来计时并触发定时,所以队列中的定时事件也是异步事件.</p>
<p>由图可知,在这t1的时间段内,继鼠标点击事件触发后,先前已设置的setTimeout定时也到达了,此刻对JavaScript引擎来说,定时触发线程产生了一个异步定时事件并放到任务队列中, 该事件被排到点击事件回调之后,等待处理.<br />
同理, 还是在t1时间段内,接下来某个setInterval定时器也被添加了,由于是间隔定时,在t1段内连续被触发了两次,这两个事件被排到队尾等待处理.</p>
<p>可见,假如时间段t1非常长,远大于setInterval的定时间隔,那么定时触发线程就会源源不断的产生异步定时事件并放到任务队列尾而不管它们是否已被处理,但一旦t1和最先的定时事件前面的任务已处理完,这些排列中的定时事件就依次不间断的被执行,这是因为,对于JavaScript引擎来说,在处理队列中的各任务处理方式都是一样的,只是处理的次序不同而已.</p>
<p>t1过后,也就是说当前处理的任务已返回,JavaScript引擎会检查任务队列,发现当前队列非空,就取出t2下面对应的任务执行,其它时间依此类推,由此看来:</p>
<p>如果队列非空,引擎就从队列头取出一个任务,直到该任务处理完,即返回后引擎接着运行下一个任务,在任务没返回前队列中的其它任务是没法被执行的.</p>
<p>相信您现在已经很清楚JavaScript是否可多线程,也了解理解JavaScript定时器运行机制了,下面我们来对一些案例进行分析:</p>
<p>案例1:setTimeout与setInterval</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">()</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">/* 代码块... */</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Blue;">arguments</span><span style="color: Gray;">.</span><span style="color: Blue;">callee</span><span style="color: Gray;">, </span><span style="color: Maroon;">10</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">, </span><span style="color: Maroon;">10</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">setInterval</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">/*代码块... */</span></li>
<li><span style="color: Olive;">}</span><span style="color: Gray;">, </span><span style="color: Maroon;">10</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li></ol></div>
<p>这两段代码看一起效果一样,其实非也,第一段中回调函数内的setTimeout是JavaScript引擎执行后再设置新的setTimeout定时, 假定上一个回调处理完到下一个回调开始处理为一个时间间隔,理论两个setTimeout回调执行时间间隔>=10ms .第二段自setInterval设置定时后,定时触发线程就会源源不断的每隔十秒产生异步定时事件并放到任务队列尾,理论上两个setInterval回调执行时间间隔<=10.</p>
<p>案例2:ajax异步请求是否真的异步?</p>
<p>很多同学朋友搞不清楚,既然说JavaScript是单线程运行的,那么XMLHttpRequest在连接后是否真的异步?<br />
其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即还是单线程运行onreadystatechange所设置的函数.</p>
<p>来源：<a href="http://www.luidea.com/Jquery/2011319.html">集思网</a></p>
]]>
</description>
<dc:creator>Await</dc:creator>
<pubDate>Tue, 14 Aug 2012 10:47:29 +0800</pubDate>
</item>
</channel>
</rss>