<?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>Alibaba.com UED &#187; Web Developer</title>
	<atom:link href="http://www.aliued.com/category/web-developer/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.aliued.com</link>
	<description>Alibaba.com User experience design team</description>
	<lastBuildDate>Wed, 04 Jan 2012 02:30:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>YUI3 的事件模拟机制</title>
		<link>http://www.aliued.com/2012/01/04/491/</link>
		<comments>http://www.aliued.com/2012/01/04/491/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 02:30:21 +0000</pubDate>
		<dc:creator>mark.chenfl</dc:creator>
				<category><![CDATA[Web Developer]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=491</guid>
		<description><![CDATA[来自许诺的分享 在YUI2中，我们没有官方的时间模拟机制，但是YUI3带给了我们这个便利，使我们可以通过模拟来对代码进行最直接的重用： 我们可以很方便的模拟用户的以下行为： click dblclick ... ]]></description>
			<content:encoded><![CDATA[<p>来自许诺的分享</p>
<p>在YUI2中，我们没有官方的时间模拟机制，但是YUI3带给了我们这个便利，使我们可以通过模拟来对代码进行最直接的重用：</p>
<div>我们可以很方便的模拟用户的以下行为：</div>
<div>
<ul>
<li><code>click</code></li>
<li><code>dblclick</code></li>
<li><code>mousedown</code></li>
<li><code>mouseup</code></li>
<li><code>mouseover</code></li>
<li><code>mouseout</code></li>
<li><code>mousemove</code></li>
</ul>
<div>
<div>
<ul>
<li><span style="font-family: monospace;"><code>keyup</code></span></li>
<li><span style="font-family: monospace;"><code>keydown</code></span></li>
<li><span style="font-family: monospace;"><code>keypress</code></span></li>
</ul>
<div>
<ul>
<li><span style="font-family: monospace;"><code>blur</code></span></li>
<li><span style="font-family: monospace;"><code>change</code></span></li>
<li><span style="font-family: monospace;"><code>focus</code></span></li>
<li><span style="font-family: monospace;"><code>resize</code></span></li>
<li><span style="font-family: monospace;"><code>scroll</code></span></li>
<li><span style="font-family: monospace;"><code>select</code></span></li>
</ul>
<div><span style="font-family: monospace;"><br />
</span></div>
</div>
</div>
<pre><span style="font-family: monospace;">一个简单的例子：</span></pre>
<pre><span style="font-family: monospace;">YUI().use('node-event-simulate', function(Y) { </span></pre>
<pre><span style="font-family: monospace;">     <strong><span style="color: #ff4635;">Y</span></strong><strong><span style="color: #ff4635;">.one("body").simulate("click");}</span></strong></span></pre>
<pre><span style="font-family: monospace;">);</span></pre>
<pre><span style="font-family: monospace;">这样就模拟点击了body的click事件。</span></pre>
<pre><span style="font-family: monospace;">当然你还可以附加其它按键，例如模拟shift键同时按下点击效果。</span></pre>
<div>
<pre><span style="font-family: monospace;">Y.one("body").simulate("click", <strong><span style="color: #ff4635;">{ shiftKey: true </span></strong><strong><span style="color: #ff4635;">}</span></strong>);</span></pre>
<pre><span style="font-family: monospace;">同理alt键也是如此</span></pre>
<div>
<pre><span style="font-family: monospace;">node.simulate("click", {<span style="color: #ff0000;"> altKey: true</span>} );</span></pre>
<pre><span style="font-family: monospace;">更方便的是你可以指定源</span></pre>
<div>
<pre><span style="font-family: monospace;">node.simulate("mouseout", { <span style="color: #ff4635;">relatedTarget</span><span style="color: #ff4635;">: document.</span><span style="color: #ff4635;">body</span> });</span></pre>
<pre><span style="font-family: monospace;">还有坐标</span></pre>
<div>
<pre><span style="font-family: monospace;">node.simulate("mousedown", { <span style="color: #ff0000;">clientX</span><span style="color: #ff0000;">: 100, clientY: 100</span> });</span></pre>
<pre><span style="font-family: monospace;">对于ui层面的改变它也同样敏感</span></pre>
<div>
<pre><span style="font-family: monospace;">
<pre class="brush:js">YUI().use('node-event-simulate', function(Y) {
  var node = Y.one("#myInput");
  // 模拟节点选择改变
  node.simulate("change");
  // 模拟节点被选中
  node.simulate("select");
}
);</pre>
<p></span></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2012/01/04/491/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YUI3新特性学习</title>
		<link>http://www.aliued.com/2011/12/24/481/</link>
		<comments>http://www.aliued.com/2011/12/24/481/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 02:05:07 +0000</pubDate>
		<dc:creator>mark.chenfl</dc:creator>
				<category><![CDATA[Web Developer]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=481</guid>
		<description><![CDATA[来自陈漫凯的分享 更轻量 － 出色的颗粒化模块，子模块划分； － 延迟加载； － 强调代码重用（公共基类、插件、扩展）； 更易用 － 统一的API； － 便利（each, bind, queue, 支持链式）； 更... ]]></description>
			<content:encoded><![CDATA[<p>来自陈漫凯的分享</p>
<p><span style="font-family: 微软雅黑;">更轻量</span></p>
<p><span style="font-family: 微软雅黑;"> － 出色的颗粒化模块，子模块划分；</span></p>
<p><span style="font-family: 微软雅黑;"> － 延迟加载；</span></p>
<p><span style="font-family: 微软雅黑;"> － 强调代码重用（公共基类、插件、扩展）；</span></p>
<p><span style="font-family: 微软雅黑;">更易用</span></p>
<p><span style="font-family: 微软雅黑;"> － 统一的API；</span></p>
<p><span style="font-family: 微软雅黑;"> － 便利（each, bind, queue, 支持链式）；</span></p>
<p><span style="font-family: 微软雅黑;">更快捷</span></p>
<p><span style="font-family: 微软雅黑;"> － 重构node, event, selector等，解决很多核心痛点；</span></p>
<p><span style="font-family: 微软雅黑;"> － 依赖性处理；</span></p>
<p><span style="font-family: 微软雅黑;"> </span></p>
<p><strong><span style="font-family: 微软雅黑;">Hello YUI</span></strong></p>
<p><span style="font-family: 微软雅黑;">初识YUI3.x，最先发现的一个变化就是，原先YAHOO的命名空间被改为YUI，这样命名的修改，就不用在为了使用这个开源的框架而非要搞得代码里到处都是YAHOO公司的名字，但更好的一点是，可以借助不同的变量名让YUI3和旧版的YUI共存而不至于冲突。</span></p>
<p><span style="font-family: 微软雅黑;"> </span></p>
<p><strong><span style="font-family: 微软雅黑;">沙箱(Sandboxing)</span></strong></p>
<p><span style="font-family: 微软雅黑;">这是YUI3.x的一个显著特点，它可以在页面中创建一个多重开发环境。每一个YUI实例会自包含的，保护和限制。 </span></p>
<div>
<pre>
<pre class="brush:js">YUI().use('node', 'event', function(Y) {
      // ready
});</pre>
</pre>
</div>
<p><span style="font-family: 微软雅黑;">在这里，YUI()执行并返回一个use方法执行后的库的实例。use方法至少有两个参数是必须，库组件名称和加载完毕后执行的回调函数。 上面的例子中，会加载名字为’node’和’event’的库组件，最后一个参数是回调函数，YUI()执行后的包含所加载的库组件的实例会以参数Y传给这个回调函数。</span></p>
<p><span style="font-family: 微软雅黑;">相对于YUI2.x的只有YAHOO一个全局变量，沙箱的这种多重开发环境的好处还是很明显的。</span></p>
<div>
<pre>
<pre class="brush:js">YAHOO.widget.HelloWorld = doSomething; // 开发者A的代码
...
YAHOO.widget.HelloWorld = doOtherthing; // 开发者B的代码</pre>
</pre>
</div>
<p><span style="font-family: 微软雅黑;">如上，在YUI2.x中，YAHOO作为全局变量，多人开发的时候，将会出现B的代码覆盖A代码的情况，而且这种情况不是使用闭包所能解决的。而YUI3.x的沙箱，提供每个实例可独立开发：</span></p>
<div>
<pre>
<pre class="brush:js">YUI().use('node', function(Y) {
      Y.HelloWorld = doSomething; // 开发者A的代码
});
YUI().use('anim', function(Y) {
      Y.HelloWorld = doOtherthing; // 开发者B的代码
});</pre>
</pre>
</div>
<p><span style="font-family: 微软雅黑;">沙箱使得代码更安全，而且，每一个实例的YUI3.x版本不同也没有关系。</span></p>
<p><span style="font-family: 微软雅黑;">YUI().use()的另外一个特点是每个实例的依赖，可以按需加载。这样不但可以节省带宽，而且也使得更加力度的颗粒化模块变得更有意义。而且，加载的所依赖的js文件是延迟加载的，加快了页面渲染的速度。</span></p>
<p><a href="http://www.aliued.com/wp-content/uploads/2012/01/Image1.jpg"><img class="alignnone size-full wp-image-483" title="Image" src="http://www.aliued.com/wp-content/uploads/2012/01/Image1.jpg" alt="" width="553" height="306" /></a></p>
<p><span style="font-family: 微软雅黑;">测试显示，延迟加载使得页面在更短的时间内渲染完成。</span></p>
<p><span style="font-family: 微软雅黑;">但同时，因为依赖进来的包，都是独立的文件，每引入一个文件，就创建一个&lt;script&gt;标签去请求js文件，这样大大的增加了HTTP请求的数量。</span></p>
<p><span style="font-family: 微软雅黑;"> </span></p>
<p><strong><span style="font-family: 微软雅黑;">颗粒化模块</span></strong></p>
<p><span style="font-family: 微软雅黑;">YUI2.x每个模块庞大的体积让不少人望而兴叹。比如有时候要使用日历里面的基础功能，你不得不把整个日历组件导人，整整75K的代码，你实际用到的仅仅是基础功能，这也是很多公司没有使用YUI的原因之一。YUI3.x做了大调整，对每个模块都进行了更细颗粒度的划分。比如，DOM模块，划分为了base, screen, style, selector-css2, selector-css3, selector-native等几个小模块，这样，我们可以根据需要选择所需的模块，对于我们控制页面的载入的数据量有很大帮助。</span></p>
<p><span style="font-family: 微软雅黑;">但更细的划分模块，带来的弊端就是，代码文件增多，维护成本变大。</span></p>
<p><span style="font-family: 微软雅黑;"> </span></p>
<p><strong><span style="font-family: 微软雅黑;">选择器(Selector)</span></strong></p>
<p><span style="font-family: 微软雅黑;">YUI2.9就已经引入了选择器引擎，但由于它在整个YUI2.x中出现得比较晚，所以，在很多基于旧版本的YUI项目中，还是用传统的元素匹配技术。</span></p>
<p><span style="font-family: 微软雅黑;">而在YUI3.x中，选择器已经成为了一种标准支持。</span></p>
<div>
<pre>
<pre class="brush:js">Y.one('#demo');
Y.all('.demo');
Y.all('.demo').filter([filter]);
Y.all('#demo li');</pre>
</pre>
</div>
<p><span style="font-family: 微软雅黑;">如果需要用到css选择器，需要把selector-css2.js和selector-css3.js引入。但从性能的角度上讲，我还是觉得没有必要去用那么复杂的选择器。</span></p>
<p><span style="font-family: 微软雅黑;"> </span></p>
<p><strong><span style="font-family: 微软雅黑;">链式调用</span></strong></p>
<p><span style="font-family: 微软雅黑;">跟jQuery一样，YUI3.x也开始支持链式调用，对于一些没有逻辑返回值的方法，YUI3.x都支持链式调用。</span></p>
<div>
<pre>
<pre class="brush:js">Y.one('#demo').set('innerHTML', 'Hello World!').addClass('hight-light');</pre>
</pre>
</div>
<p><span style="font-family: 微软雅黑;">链式调用并非YUI3.x的主打亮点，但的确带来了书写的便利性，但同时，对于向来严谨的YUI，链式一定程度上会带坏现有代码风格。使用YUI开发的人，至少要在链式调用使用程度上达到一定的共识。</span></p>
<p><span style="font-family: 微软雅黑;"> </span></p>
<p><strong><span style="font-family: 微软雅黑;">Nodes</span></strong></p>
<p><span style="font-family: 微软雅黑;">由于各个浏览器对DOM标准的支持不同，YUI Node对底层的DOM节点进行封装，并强化其功能，为创建、操作和获取DOM节点对象（集合）提供了丰富的方法。封装后的YUI Node和浏览器HTMLElement对象对比：</span></p>
<p><span style="font-family: 微软雅黑;"><a href="http://www.aliued.com/wp-content/uploads/2012/01/Image2.jpg"><img class="alignnone size-full wp-image-484" title="Image2" src="http://www.aliued.com/wp-content/uploads/2012/01/Image2.jpg" alt="" width="398" height="286" /></a></span></p>
<p><span style="font-family: 微软雅黑;">封装后，获取到的不在是一个浏览器DOM对象，所以对YUI Node对象的熟悉的访问和修改，必须通过getter和setter来操作。</span></p>
<div>
<pre>
<pre class="brush:js">var el = Y.one('#demo');
alert(el.id); // undefined
alert(el.get('id')); // 'demo'</pre>
</pre>
</div>
<p><span style="font-family: 微软雅黑;"> </span></p>
<p><strong><span style="font-family: 微软雅黑;">小结</span></strong></p>
<p><span style="font-family: 微软雅黑;">正如我们所看到的，YUI3.x相对于早前版本，完全是一个新的产物。通过新的语法，我们使用到的是，更轻量，更易用，更快捷的库。YUI2.x是一种工具集，而YUI3.x更像是一种架构，框架或者说解决方案。</span></p>
<p><span style="font-family: 微软雅黑;"> </span></p>
<p><script type="text/javascript">// <![CDATA[
标签去请求js文件，这样大大的增加了HTTP请求的数量。</p>
<p>颗粒化模块
YUI2.x每个模块庞大的体积让不少人望而兴叹。比如有时候要使用日历里面的基础功能，你不得不把整个日历组件导人，整整75K的代码，你实际用到的仅仅是基础功能，这也是很多公司没有使用YUI的原因之一。YUI3.x做了大调整，对每个模块都进行了更细颗粒度的划分。比如，DOM模块，划分为了base, screen, style, selector-css2, selector-css3, selector-native等几个小模块，这样，我们可以根据需要选择所需的模块，对于我们控制页面的载入的数据量有很大帮助。
但更细的划分模块，带来的弊端就是，代码文件增多，维护成本变大。</p>
<p>选择器(Selector)
YUI2.9就已经引入了选择器引擎，但由于它在整个YUI2.x中出现得比较晚，所以，在很多基于旧版本的YUI项目中，还是用传统的元素匹配技术。
而在YUI3.x中，选择器已经成为了一种标准支持。
Y.one('#demo');
Y.all('.demo');
Y.all('.demo').filter([filter]);
Y.all('#demo li');
如果需要用到css选择器，需要把selector-css2.js和selector-css3.js引入。但从性能的角度上讲，我还是觉得没有必要去用那么复杂的选择器。</p>
<p>链式调用
跟jQuery一样，YUI3.x也开始支持链式调用，对于一些没有逻辑返回值的方法，YUI3.x都支持链式调用。
Y.one('#demo').set('innerHTML', 'Hello World!').addClass('hight-light');
链式调用并非YUI3.x的主打亮点，但的确带来了书写的便利性，但同时，对于向来严谨的YUI，链式一定程度上会带坏现有代码风格。使用YUI开发的人，至少要在链式调用使用程度上达到一定的共识。</p>
<p>Nodes
由于各个浏览器对DOM标准的支持不同，YUI Node对底层的DOM节点进行封装，并强化其功能，为创建、操作和获取DOM节点对象（集合）提供了丰富的方法。封装后的YUI Node和浏览器HTMLElement对象对比：</p>
<p>封装后，获取到的不在是一个浏览器DOM对象，所以对YUI Node对象的熟悉的访问和修改，必须通过getter和setter来操作。
var el = Y.one('#demo');
alert(el.id); // undefined
alert(el.get('id')); // 'demo'</p>
<p>小结
正如我们所看到的，YUI3.x相对于早前版本，完全是一个新的产物。通过新的语法，我们使用到的是，更轻量，更易用，更快捷的库。YUI2.x是一种工具集，而YUI3.x更像是一种架构，框架或者说解决方案。
// ]]&gt;</script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2011/12/24/481/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>深入研究WINDOW.EVENT对象</title>
		<link>http://www.aliued.com/2011/11/29/462/</link>
		<comments>http://www.aliued.com/2011/11/29/462/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 01:29:17 +0000</pubDate>
		<dc:creator>mark.chenfl</dc:creator>
				<category><![CDATA[Web Developer]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=462</guid>
		<description><![CDATA[本周的豆知识分享就来深入研究一下window.event对象。请先看看下边的代码片断。 &#60;button id=”btn”&#62;Click!&#60;/button&#62; &#60;script type=”text/javascript”&#62; // &#60;![CDATA[ document.getElementById('btn').onc... ]]></description>
			<content:encoded><![CDATA[<div>
<p>本周的豆知识分享就来深入研究一下window.event对象。请先看看下边的代码片断。</p>
<pre class="brush:js">&lt;button id=”btn”&gt;Click!&lt;/button&gt;
&lt;script type=”text/javascript”&gt;
// &lt;![CDATA[
    document.getElementById('btn').onclick = function (e) {
        if (typeof e == 'undefined') e = window.event;
        var target = (typeof e.target == 'undefined' ? e.srcElement : e.target);
        alert(target);
    }
// ]]&gt;
&lt;/script&gt;</pre>
<div>上边是一种事件处理函数的常见写法，并且很好地处理了跨浏览器兼容问题。因此，变量target在不同浏览器下都正确地指向了被点击的button元素。但是我把代码稍微改成下边这种样子后..</div>
<div>
<pre class="brush:js">&lt;button id=”btn”&gt;Click!&lt;/button&gt;
&lt;script type=”text/javascript”&gt;
// &lt;![CDATA[
document.getElementById('btn').onclick = function (e) {
if (typeof e == 'undefined') e = window.event;
setTimeout(function () {
var target = (typeof e.target == 'undefined' ? e.srcElement : e.target);
alert(target);
}, 1000);
}
// ]]&gt;
&lt;/script&gt;</pre>
</div>
<div>我写了一个匿名函数，并让它在1秒后执行。由于我构造了一个闭包，1秒后执行的匿名函数也应该能正确地访问到变量e，而变量target也应该正确地指向button元素。然后我用比较流行的浏览器测试了一下上边的代码，最新版本的Firefox、Chrome和Opera下一切都如同预期，可是在IE系列（6、7、8）下，我只得到了一个JS错误——找不到成员。好吧，我需要分析一下原因了。因为这段代码只在IE下有问题，而且经过一些试验后我也排除了闭包引起问题的可能性，因此我把上边的代码简化成如下这种样子，以便突出问题的本质。</div>
<div>
<pre class="brush:js">&lt;button id=”btn”&gt;Click!&lt;/button&gt;
&lt;script type=”text/javascript”&gt;
// &lt;![CDATA[
document.getElementById('btn').onclick = function () {
setTimeout(function () {
alert(window.event.srcElement);
}, 1000);
}
// ]]&gt;
&lt;/script&gt;</pre>
<p>不辜负期望，以上代码同样产生了JS错误。然后我把alert(window.event.srcElement);改成了alert(window.event)，这次终于没有错误了，而弹出的消息框里的内容是null。然后我又去翻了翻MSDN Library，看到了下边这段描述：</p>
<blockquote><p>The event object is available only during an event—that is, you can use it in event handlers but not in other code.</p></blockquote>
<p>也就是说，与其它浏览器在事件触发之后为每个事件创建一个单独的Event对象相对，IE的所有事件公用一个Event对象，也就是window.event。因此为了避免冲突，针对某个事件的window.event对象只在该事件的事件处理函数的执行过程中有效，一旦事件处理函数执行完了，window.event就被IE设置为null了。</p>
<p>到此为止，似乎问题的原因已经很明了了。但是细心的同学也许会反驳，IE其实也是为每个被触发的事件创建一个单独的Event对象，只不过每次都通过window.event来引用新生成的对象。因此我写了下边这段代码来验证这种观点。</p>
<pre class="brush:js">&lt;button id=”btn”&gt;Click!&lt;/button&gt;
&lt;script type=”text/javascript”&gt;
// &lt;![CDATA[
var lastEventObj = null;
document.getElementById('btn').onclick = function () {
if (lastEventObj == null)
lastEventObj = window.event.srcElement;
else
alert(lastEventObj === window.event.srcElement);
}
// ]]&gt;
&lt;/script&gt;</pre>
<p>按钮在第一次被点击时，该事件的Event对象被lastEventObj变量所引用。因此就算在按钮第二次被点击时window.event被设置为新的Event对象的引用，仍然可以使用lastEventObj变量来访问到第一次点击事件时的Event对象。如果IE在每次事件被触发时都创建一个新的Event对象，那么lastEventObj === window.event.srcElement应该返回false。如果IE为所有事件公用一个Event对象，只是在每次事件触发时重新设置该对象的属性的话，lastEventObj === window.event.srcElement应该返回true。经过测试，返回值是false。</p>
<p>问题开始变得有些诡异了。既然每次事件被触发时的Event对象都是不同的，在本文的第二段代码里边，的确是在变量e中保存了对Event对象的引用的。即使事件处理函数执行完毕后window.event被设置为null，在1秒后自动执行的匿名函数中仍然应该可以使用变量e来访问先前的Event对象，但是为什么会产生JS错误呢？问题的原因在这时再此变得扑朔迷离了。我做了一些试验后得到了一些惊人的结论，以下我直接列举出一些事实。</p>
<p><strong>1、window.event对象不是真正的JavaScript 对象。</strong></p>
<p>按照ECMAScript规范，JavaScript中只应该存在有两种数据类型——值类型和对象。而一切对象都应该衍生于Object对象，因此Object.prototype中定义的方法，例如toString，应该在一切对象上都可以调用。那么我们来看看下边的代码：</p>
<pre class="brush:js">&lt;button id=”btn”&gt;Click!&lt;/button&gt;
&lt;script type=”text/javascript”&gt;
// &lt;![CDATA[
document.getElementById('btn').onclick = function () {
alert(typeof window.event.toString);
}
// ]]&gt;
&lt;/script&gt;</pre>
<p>点击按钮后，弹出的消息框里竟然显示的是undefined。由此可见，任何标准的JavaScript对象应该包含的成员却在window.event对象上消失了。既然window.event已经不是一个标准的JavaScript对象了，所以如果有什么理所当然的事情在window.event上变得不对劲了也不要感到特别惊奇。</p>
<p><strong>2、实际上，IE还是为所有事件公用一个Event对象。</strong></p>
<p>我们直接使用下边的代码来说明问题。</p>
<pre class="brush:js">&lt;button id=”btn1″&gt;Click1!&lt;/button&gt;
&lt;button id=”btn2″&gt;Click2!&lt;/button&gt;
&lt;script type=”text/javascript”&gt;
// &lt;![CDATA[
var btn1EventObj = null;
document.getElementById('btn1').onclick = function () {
btn1EventObj = window.event;
alert(btn1EventObj.srcElement.id);
}
document.getElementById('btn2').onclick = function () {
alert(btn1EventObj === window.event);
alert(btn1EventObj.srcElement === window.event.srcElement);
alert(btn1EventObj.srcElement.id);
}
// ]]&gt;
&lt;/script&gt;</pre>
<p>这次我们有了两个按钮，每个按钮都绑定了一个事件处理函数。我们先点击btn1按钮，该点击事件的Event对象的引用在btn1事件处理函数中被保存在了全局变量btn1EventObj中。然后我们试着用btn1EventObj变量来访问btn1的id属性，很好，弹出的消息框中的确显示的btn1。</p>
<p>接下来我们点击btn2按钮，在btn2的事件处理函数中我们做了一些测试。测试btn1EventObj === window.event时，不出所料，返回了false。看来window.event已经变成了另外一个Event对象的引用。然后我们再测试btn1EventObj.srcElement === window.event.srcElement，居然返回了true。等号左边的本来应该是按钮btn1，而右边应该是按钮btn2，现在它们居然相等了。然后我们再看看btn1EventObj.srcElement.id，结果它的值变成了btn2了。事情变得明了了，对象btn1EventObj与对象window.event之间的关系可以用下边的图来表示。</p>
<p><a href="http://www.aliued.com/wp-content/uploads/2011/11/image001.gif"><img class="alignnone size-full wp-image-463" title="image001" src="http://www.aliued.com/wp-content/uploads/2011/11/image001.gif" alt="" width="443" height="333" /></a></p>
</div>
<div>
<p>IE确实为每个事件创建了一个单独的Event对象，而window.event在事件处理函数的执行过程中也总是指向最新创建的Event对象。问题是每个Event对象的属性却共享的同一个属性值。在这个例子中，当按钮btn2被点击后，共享的属性值srcElement被更新为了按钮btn2。因此通过btn1EventObj.srcElement访问到的属性值也就被改变了。</p>
<p><strong>3、被共享的Event对象属性值也只在事件处理函数的执行过程中才有效</strong></p>
<p>在事件处理函数执行完毕后，并不仅仅是window.event被设置为null这么简单。可以看看如下代码：</p>
<pre class="brush:js">&lt;button id=”btn”&gt;Click!&lt;/button&gt;
&lt;script type=”text/javascript”&gt;
// &lt;![CDATA[
var eventObj = null;
document.getElementById('btn').onclick = function () {
eventObj = window.event;
setTimeout(function () {
alert(typeof eventObj.srcElement);
}, 1000);
}
// ]]&gt;
&lt;/script&gt;</pre>
<div>猜猜最后弹出的消息框里的是什么？居然是unknown。微软自家的JScript文档里的有如下定义：</div>
<div>There are six possible values that typeof returns: “number,” “string,” “boolean,” “object,” “function,” and “undefined.”</div>
<div>所以这个unknown代表着事件处理函数执行后，srcElement属性所指向的属性值已经变成了未知的什么什么了。不仅仅是srcElement属性，诸如clientX、altKey等Event对象的其它属性在事件处理函数执行完毕后也是如此。夜深人静一个人写周报的我面对如此灵异的事实也不仅感觉到背脊有丝丝凉意。但是如果我们如果像下边的代码这样，在事件处理函数的执行过程中把属性值保存在其它的变量中，则被保存的属性值在事件处理函数执行后依然可以访问到。</div>
<div>
<pre class="brush:js">&lt;button id=”btn”&gt;Click!&lt;/button&gt;
&lt;script type=”text/javascript”&gt;
// &lt;![CDATA[
var target = null;
document.getElementById('btn').onclick = function () {
target = window.event.srcElement;
setTimeout(function () {
alert(target.id);
}, 1000);
}
// ]]&gt;
&lt;/script&gt;</pre>
<p>由此可以，srcElement属性的属性值在这段代码中表现出了值类型的性质，因为事件处理函数执行完毕后，即使IE把公用的属性值设置为了未知的什么什么后，保存在变量target中的属性值并没有受到印象。至于为什么通过Event对象的属性来访问属性值时属性值表现出了对象类型的性质，这个就只有IE的开发人员知道了。</p>
<p>以上是本周分享的有关window.event的灵异事件录。虽然到最后还是以“只有IE开发人员才知道”这种半途而废的文字收尾了，但是至少我们可以得出一些有用的结论来帮助我们在今后写代码的过程中回避类似问题：</p>
<p><strong>1、在IE中，不要在事件处理函数的执行过程以外的地方来访问Event对象及其属性。</strong></p>
<p><strong>2、如果非要访问，请在事件处理函数的执行过程中用闭包等方式把Event对象的属性的属性值保存在其它变量中。</strong></p>
<p><strong><br />
</strong></p>
<p style="text-align: right;"><strong>注：此文版权属于 邓楠乔</strong></p>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2011/11/29/462/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>COMMENT IN HTML</title>
		<link>http://www.aliued.com/2011/10/08/451/</link>
		<comments>http://www.aliued.com/2011/10/08/451/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 03:16:53 +0000</pubDate>
		<dc:creator>mark.chenfl</dc:creator>
				<category><![CDATA[Web Developer]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=451</guid>
		<description><![CDATA[按照W3C的定义，HTML中的注释以&#60;!–开头，以–&#62;结尾，但是真相并不仅仅如此。HTML是由SGML（标准通用标记语言）衍生而来，而在SGML中注释的定义如下： 一个注释以&#60;!开头，以&#62;结尾... ]]></description>
			<content:encoded><![CDATA[<p>按照W3C的定义，HTML中的注释以&lt;!–开头，以–&gt;结尾，但是真相并不仅仅如此。HTML是由SGML（标准通用标记语言）衍生而来，而在SGML中注释的定义如下：</p>
<p>一个注释以&lt;!开头，以&gt;结尾。注释中可以包含零个或多个注释块，每个注释块以–开头，并以–结尾。并且，注释块之间可以包含空格。</p>
<p>因此，以下注释都是正确的：</p>
<pre>&lt;!--Hello--&gt; &lt;!--Hello-- --World--&gt; &lt;!----&gt; &lt;!&gt;</pre>
<p>用正则表达式来表示的话，/&lt;!(–[^-]*–)?(\s*–[^-]*–)*&gt;/能够匹配的注释都是正确的。因此，下边这种诡异的注释虽然是一个正确的SGML注释，但是按照W3C的定义来说就不正确了。</p>
<pre>&lt;!--Hello----&gt;World--&gt;</pre>
<p>反过来，下边两种注释是正确的W3C注释，但是却不是正确的SGML注释，因为包裹注释块的–没有配对。</p>
<pre>&lt;!---- &gt;--&gt; &lt;!------&gt;</pre>
<p>然后问题就来了。Firefox按照SGML的标准来解释注释的。而IE、Chrome、Opera按照W3C的标准来解释注释。所以&lt;!–Hello—-&gt;World–&gt;这种注释在Firefox下正常，但是在其它浏览器下会把World–&gt;显示在页面里。反过来，&lt;!——&gt;在其它浏览器里正常，但是Firefox下会把&lt;!——&gt;显示在页面里，因为Firefox认为这不是一个注释。另外，对于&lt;!—- &gt;–&gt;来说，Firefox会认为&lt;!—- &gt;才是注释，把后边的–&gt;显示出来，IE和Chrome下这个是一个正确的注释，而Opera会“智能”地认为&lt;!—- &gt;–&gt;中间的空格是不小心多出来的，所以“好心”地把空格去掉后，把不适注释部分的–&gt;给显示出来。</p>
<p>由于注释中间的中划线在各种浏览器中的表现如此不一致，因此为了避免种种意想不到的惊喜，最直接的做法就是避免在注释中包含中划线。</p>
<p>有的同学或许要问，这个或许是一个不错的知识，可是和我们的日常开发有什么关系呢？那么请看下边这段html：<br />
<code>&lt;!--&lt;a href="http://www.alibaba.com/products/used_cars/--1217----------------6-5574,.html"&gt;Sedan &lt;span&gt;(79727)&lt;/span&gt;&lt;/a&gt;--&gt;</code><br />
在我们的网站里这种链接很常见，而且href的value是模板变量生成的。因此，如果我们在模板里这么写：</p>
<pre>&lt;!--&lt;a href="${Url}"&gt;${Name}&lt;span&gt;(${num})&lt;/span&gt;&lt;/a&gt;--&gt;</pre>
<p>可能觉得不会有问题，但是最后生成的页面在Firefox下就会把注释部分显示成下边这样：</p>
<pre>Sedan (79727)--&gt;</pre>
<p>这个例子作为理由来讲的确很不充分，毕竟没有谁会用HTML注释来删掉页面里不需要的内容，但是说不定以后的什么时候这些关于注释的知识会在各位的工作中派上用场，这就是豆知识。</p>
<p>PS：如果有同学对HTML注释特别感兴趣，可以继续阅读本文的参考文献：</p>
<p>http://www.howtocreate.co.uk/SGMLComments.html</p>
<p>http://htmlhelp.com/reference/wilbur/misc/comment.html</p>
<div>
<h4>Last Modified on <strong>Tuesday July 19th 2011 09:52:51 AM</strong>, Post Revisions:</h4>
<p>This post has not been revised since publication.</p>
</div>
<p style="text-align: right;">注：此文版权属于 <strong>邓楠乔</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2011/10/08/451/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>简单介绍各种浏览器中的本地存储方法</title>
		<link>http://www.aliued.com/2011/09/15/443/</link>
		<comments>http://www.aliued.com/2011/09/15/443/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 03:14:07 +0000</pubDate>
		<dc:creator>mark.chenfl</dc:creator>
				<category><![CDATA[Web Developer]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=443</guid>
		<description><![CDATA[这片文章只对本地存储方法做介绍，若要查看本地存储组件使用方法的介绍请稍等。 本地数据持久化（或者也叫做浏览器本地存储）是一种在浏览器中长久保存数据的方法，在刷新页面，同域... ]]></description>
			<content:encoded><![CDATA[<p>这片文章只对本地存储方法做介绍，若要查看本地存储组件使用方法的介绍请稍等。</p>
<p>本地数据持久化（或者也叫做浏览器本地存储）是一种在浏览器中长久保存数据的方法，在刷新页面，同域名内页面跳转之后仍然可以将数据保留，例如用户的偏好设置、记录已填表单项等，可以减少服务器存储压力，节省网络传输带宽，加快响应速度。目前通用、可靠的跨平台和跨浏览器的数据持久化方案只有cookie，但不幸的是，使用cookie来存储持久化的数据会遇到下列这几个问题：</p>
<p>大小：cookie的大小被限制在大约4K左右，IE6下每个域名下cookie中名值对上限是20个，超出则随机丢弃；其他浏览器一般限制在50个。<br />
占用带宽：cookie信息会被附加在每一个http请求上被来回传送<br />
复杂度：对cookie的操作（解析或增删改）需要成本。<br />
针对这些问题，现代浏览器已经实现了一种不需要依赖cookie的本地数据持久化的方法 ，这些方法相比起cookie都很简单易用，能过存储足够多的数据，并且可以不被附加在http请求上消耗网络带宽。但不幸的是，每一个浏览器的实现方案都不相同并且互不兼容，目前就有下面这四种迥异的本地数据数据持久化方案：</p>
<p>globalstorage：FireFox 2.0+,  IE 8 + (https://developer.mozilla.org/en/Storage)<br />
localstoarage:  HTML5标准 (http://dev.w3.org/html5/webstorage/)<br />
openDatabase: Safari 3.1+ (http://webkit.org/misc/DatabaseExample.html)<br />
userdata behavior: IE 5.5+ (http://msdn.microsoft.com/en-us/library/ms531424(v=vs.85).aspx)<br />
另外，使用下面这些浏览器插件同样可以实现本地数据持久化：</p>
<p>Adobe Flash<br />
Google Gear<br />
依赖插件实现本地数据持久化会带来一个很明显的问题，就是那些没有安装这些插件的用户将被抛弃，并且你的应用将会被捆绑在一个特定的软件提供商身上（例如Adobe）。Google Gear这个技术在还没有被广泛部署就被Google抛弃了。Flash的装机率虽高，但也有自己的问题，例如：</p>
<p>许多用户阻止了浏览器中的flash或者需要一个单击操作才能够激活flash，这就使得flash很不适合用来作为一个透明的本地数据持久化解决方案<br />
Flash在较新的64位机器上是出了名的不稳定<br />
一些公司处于安全原因阻止了一切flash内容<br />
不管怎么说，如果我们再算上Flash和Gear，这就意味着已经有至少6种互不兼容的方案可以实现本地数据持久化。</p>
<p>不同的存储方法有各自不同的大小限制，你可以不必关心用户使用的是哪种存储方法，但你需要了解一下他们所支持的存储容量的最小值，然后根据你所需要存储的数据大小作出决策。除了cookie，其他几种类型都可以支持我们在本地存储足够多的数据。</p>
<p>Cookie：4k<br />
gears：未知<br />
flash：至少100k，超出一个阈值(?)时需要用户的“允许”。<br />
globalstorage：5M<br />
userdata(IE) ：64k<br />
localstorage：理论上为5M（http://dev.w3.org/html5/webstorage/#disk-space）<br />
openDatabase：默认200k[来源请求]<br />
最后需要注意的是，本地数据持久化均有域的限制，也就是不能超出当前的域进行数据的读写操作。</p>
<p>TODO：</p>
<p>本地数据持久化是否可以控制过期时间(expired date)？<br />
持久化到了本地的数据存在了硬盘的什么地方？<br />
参考文献：</p>
<p>persist-js ReadMe (http://pablotron.org/software/persist-js/ )<br />
Last Modified on Wednesday May 25th 2011 04:31:23 PM, Post Revisions:<br />
This post has not been revised since publication.</p>
<p style="text-align: right;">注：此文版权属于 <strong>刘爽</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2011/09/15/443/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DNS优化的原理和方法</title>
		<link>http://www.aliued.com/2011/08/11/427/</link>
		<comments>http://www.aliued.com/2011/08/11/427/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 08:33:22 +0000</pubDate>
		<dc:creator>mark.chenfl</dc:creator>
				<category><![CDATA[Web Developer]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=427</guid>
		<description><![CDATA[Yahoo和Google都有自己的建设高性能网站最佳实践, 我不做赘述, 需要了解的自行查阅资料: Yahoo的: Best Practices for Speeding Up Your Web Site Google的: Web Performance Best Practices 上面的最佳实践条例其实也就... ]]></description>
			<content:encoded><![CDATA[<p><span style="font-family: 'Courier New';">Yahoo和Google都有自己的建设高性能网站最佳实践, 我不做赘述, 需要了解的自行查阅资料:</span></p>
<p><span style="font-family: 'Courier New';">Yahoo的: </span><a href="http://developer.yahoo.com/performance/rules.html" target="_blank"><span style="font-family: 'Courier New';">Best Practices for Speeding Up Your Web Site</span></a></p>
<p><span style="font-family: 'Courier New';">Google的: </span><a href="http://code.google.com/speed/page-speed/docs/rules_intro.html" target="_blank"><span style="font-family: 'Courier New';">Web Performance Best Practices</span></a></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">上面的最佳实践条例其实也就是我们常在</span><a href="http://developer.yahoo.com/yslow" target="_blank"><span style="font-family: 'Courier New';">YSlow</span></a><span style="font-family: 'Courier New';">和</span><a href="http://code.google.com/speed/page-speed/" target="_blank"><span style="font-family: 'Courier New';">PageSpeed</span></a><span style="font-family: 'Courier New';">这两个Firefox的add-ons中看到的网站检测结果的参考标准.</span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">而整个WPO其实是对浏览器(browser)的加载(load)和解析(parse)过程中的一些消耗行为进行优化, 而load和parse在整个浏览器工作过程中又互相纠结互相作用. </span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">在这篇文字中讨论的更多是FE们能够伸手处理或者通过达成共识的方法来进行快速推动Tech们协助的一些事情.</span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">OK, 我们慢慢把浏览器的工作过程掰细了看吧.</span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">首先, 我们先整一个浏览器如何找到一个网站的简易工作原理 &#8211; <strong>DNS查询</strong>:</span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';"><a href="http://www.aliued.com/wp-content/uploads/2011/11/browser_dns_lookup1.png"><img class="alignnone size-full wp-image-430" title="browser_dns_lookup" src="http://www.aliued.com/wp-content/uploads/2011/11/browser_dns_lookup1.png" alt="" width="438" height="372" /></a></span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">首先当用户在浏览器的地址栏中敲入了网站的网址 ( 比如: alibaba.com ) ,这时浏览器会首先通过访问的域名来定位到IP (DNS) 从而找到去哪里获取资源, 这时, 浏览器会依次进行如下查找:</span></p>
<p><span style="font-family: 'Courier New';"><strong>1. 浏览器缓存 </strong>: </span></p>
<blockquote><p><span style="font-family: 'Courier New';">浏览器首先会在自己的缓存中查找有没有对应的域名 &#8211; IP匹配, 如果好运的话, 这里就可以直接尝试去访问资源了, 如果运气平平则往下走吧.</span></p></blockquote>
<p><span style="font-family: 'Courier New';"><strong>2. 系统缓存 </strong>: </span></p>
<blockquote><p><span style="font-family: 'Courier New';">浏览器缓存中没有命中, 浏览器会告诉操作系统:&#8221;嘿, 我在我自己口袋里没找到, 可能丢了, 我得去你那看看&#8221;, 然后, 一个系统进程(?)调取系统中的DNS缓存进行查询, 重复上一条的运气判断&#8230;</span></p></blockquote>
<p><span style="font-family: 'Courier New';"><strong>3. 路由器缓存</strong> : </span></p>
<blockquote><p><span style="font-family: 'Courier New';">走到这, 运气还真不太好啊, 操作系统也没辙了, 那怎么办呢, 向路由去要要看吧&#8230; 重复运气判断&#8230;</span></p></blockquote>
<p><span style="font-family: 'Courier New';"><strong>4. ISP DNS缓存 </strong>: </span></p>
<blockquote><p><span style="font-family: 'Courier New';">好吧, 真不知道说运气好还是运气不好了, 不废话, 去ISP (网络提供商) 的DNS缓存服务器中寻找了, 一般情况下, 在ISP端的缓存中都能找到相应的缓存记录了, 不该这么背了, 或者&#8230; 您的ISP有够菜&#8230;</span></p></blockquote>
<p><span style="font-family: 'Courier New';"><strong>5. 递归搜索</strong>&#8230; </span></p>
<blockquote><p><span style="font-family: 'Courier New';">最无奈的情况发生了, 在前面都没有办法命中的DNS缓存的情况下, ISP的DNS服务器开始从root域名服务器开始进行递归, 顺序是从.com顶级域名服务器到alibaba的域名服务器, 再没找到&#8230;好吧, 您认为您要去的网站真的公开存在么&#8230;?</span></p></blockquote>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">要强调的是, 不只是对网站第一次的域名访问需要做这样一次查询工作, 在对页面中的资源引用的域名解析时一样会有这样的一系列工作. 最明显的就是启用全新域名来做静态资源存储服务时, 基本上上述的1 &#8211; 5个步骤都得走上几遍. 才能让新域名在各DNS缓存服务器上留下记录.</span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">在这个话题上, 关于DNS的类似系统级的解决方案不是FE能够控制得了的, 我们q可以在涉及到DNS时有些小Tips来从中做些事情.</span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">好吧, 第一项.DNS相关的优化:</span></p>
<p><span style="font-family: 'Courier New';"><strong>常规实践</strong> : DNS解析的复杂性决定了不当的使用多域名获取资源会造成不必要的性能开销. 在WPO中, 很多优化工作是很艺术的, 在DNS和HTTP这两方面优化是就可以看到这个神奇的艺术性:</span></p>
<p><span style="font-family: 'Courier New';">DNS的优化, 当然是尽可能少的造成DNS查询开销, 而在HTTP优化的策略中有一项优化措施是避免单域名下连接数的缺陷来进行资源多通道下载, 实施的细节会在 <strong><span style="color: #ff0000;">&lt;HTTP优化的原理和方法&gt;</span></strong> 中详细介绍, 在这里只是简单的提一下, 静态资源多域名服务可以绕过浏览器单域名载入资源时并行连接数的限制, DNS优化需要我们尽可能少的域名解析, HTTP优化时需要我们适当的使用多域名服务, 那怎么样让两个优化实践都能够比较好的实施呢? <span style="color: #ff0000;">[todo]</span></span></p>
<p><span style="font-family: 'Courier New';"> </span><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';"><strong>优雅降级</strong> : 在某些现代浏览器 ( Google Chrome, Firefox 3.5+ ) 中, 已经能够支持DNS的预取了, 怎么个预取呢? 就是在浏览器加载网页时, 对网页中的&lt;link&gt;或者&lt;a&gt;的href属性中的域名进行后台的预解析(上文中的 1- 5步), 并且将解析结果缓存在浏览器端, 当用户在真正点击链接时, 省去在当下的DNS解析消耗, 把这个消耗过程转嫁到用户无法感知的浏览过程中去.</span></p>
<p><span style="font-family: 'Courier New';"> </span></p>
<p><span style="font-family: 'Courier New';">第一, 现代浏览器已经支持且默认打开了DNS Prefetch的功能. 当然也可以通过浏览器的配置来管理该功能:</span></p>
<blockquote><p><span style="font-family: 'Courier New';">用Firefox3.5+可以这样: 浏览器默认就打开了HTTP协议下的DNS预取功能, 默认关闭HTTPS协议下的DNS预取功能, 可通过 about:config 的 <code>network.dns.disablePrefetch</code> 和 <code>network.dns.disablePrefetchFromHTTPS </code><code>两个选项来控制两种协议下的预取功能.</code></span></p>
<p><code>Chrome管理DNS Prefetch方法暂时缺少.</code></p></blockquote>
<p><code>第二, </code><code>可以通过用meta信息来告知浏览器, 我这页面要做DNS预取: </code></p>
<blockquote><p><code>&lt;meta http-equiv="x-dns-prefetch-control</code><code>" content="on" /&gt;</code></p></blockquote>
<p><code>第三,可以</code><code>使用link标签来强制对DNS做预取: </code></p>
<blockquote><p><code>&lt;link rel="dns-prefetch" href="<a href="http://www.alibaba.com/">http://www.alibaba.com/</a>" /&gt;</code></p>
<p><code><span style="font-family: 'Courier New';"> </span></code></p></blockquote>
<p><code><span style="color: #ff0000;"> </span></code></p>
<p><code><span style="color: #ff0000;">[todo DEMO]</span></code></p>
<p><code>扩展阅读:</code></p>
<blockquote><p><a href="https://developer.mozilla.org/En/Controlling_DNS_prefetching" target="_blank"><span style="font-family: 'Courier New';">Controlling DNS prefetching in Firefox</span></a></p>
<p><a href="http://bitsup.blogspot.com/2008/11/dns-prefetching-for-firefox.html" target="_blank"><span style="font-family: 'Courier New';">DNS Prefetching for Firefox (blog post)</span></a></p>
<p><a href="http://dev.chromium.org/developers/design-documents/dns-prefetching" target="_blank"><span style="font-family: 'Courier New';">DNS Prefetching in Chrome</span></a></p>
<p><code><a href="http://www.aqee.net/2010/06/08/how-html-5-link-prefetching-can-make-your-site-load-faster-with-one-line-of-code/" target="_blank">link prefetching in HTML5</a></code></p></blockquote>
<p><span style="color: #ff0000;">另, <span style="color: #000000;">小康(lazyKang)同学</span>发现一个神奇的现象:</span></p>
<p><span style="color: #ff0000;">在一次无缓存访问中,  在一个并行下载通道内, 就算是同域名的情况, 也会造成DNS并行解析的消耗&#8230;</span></p>
<p><span style="color: #ff0000;"><a href="http://www.aliued.com/wp-content/uploads/2011/11/c7ea5a50f319e87a700f086650f58beb_thumb.jpg"><img class="alignnone size-full wp-image-429" title="c7ea5a50f319e87a700f086650f58beb_thumb" src="http://www.aliued.com/wp-content/uploads/2011/11/c7ea5a50f319e87a700f086650f58beb_thumb.jpg" alt="" width="591" height="184" /></a></span></p>
<p><span style="color: #ff0000;">DNS预解析一次, 应该就能避免这样的问题, 空了做个DEMO试试看.</span></p>
<p style="text-align: right;">注：此文版权属于 <strong>赵振宇</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2011/08/11/427/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5设计原则</title>
		<link>http://www.aliued.com/2011/07/26/402/</link>
		<comments>http://www.aliued.com/2011/07/26/402/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 08:26:49 +0000</pubDate>
		<dc:creator>mark.chenfl</dc:creator>
				<category><![CDATA[Web Developer]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=402</guid>
		<description><![CDATA[&#8220;Be conservative in what you send; be liberal in what you accept.   &#8211;The Robustness principle&#8221; &#8220;对于自己输出要严格; 对于他人的输入要灵活.  &#8211;鲁棒性原则&#8221; 一切从鲁棒性原则说起, 把鲁... ]]></description>
			<content:encoded><![CDATA[<p>&#8220;Be conservative in what you send; be liberal in what you accept.   &#8211;The Robustness principle&#8221;</p>
<p>&#8220;对于自己输出要严格; 对于他人的输入要灵活.  &#8211;鲁棒性原则&#8221;</p>
<p>一切从鲁棒性原则说起, 把鲁棒性原则放在第一位, 是为了:</p>
<p>1. 让大家带着鲁棒性原则的思考来听这次分享.</p>
<p>2. 鲁棒性原则是促成HTML5的设计原则主线.</p>
<p>3. 鲁棒性的引申义可以上升到为人处世中去.</p>
<p><strong>一. XHTML2 &amp; HTML5之间不得不说的故事</strong></p>
<p>HTML Tag的文档作为HTML诞生的见证, 但是HTML Tag这份文档并不是官方的规范.</p>
<p>真正的官方HTML规范是从HTML2开始的, HTML2继承了HTML Tag的成果, <strong>继往开来, 承前启后</strong>, 而非另立门户, 从头开始.</p>
<p>但是小悲剧的是, HTML2的标准出台的时候恰好是浏览器大战的年代,  浏览器厂商各行其道, 无视标准的存在, 而W3C也在这个时期也不停的将一些浏览器私有特性转换成标准的一部分. (Cowpaths)</p>
<p>97年 &#8211; 99年, 浏览器大战如火如荼, HTML标准也经历了从3.2 &#8211; 4.0 &#8211; 4.01的版本变迁, 非常的迅猛, 但是到了HTML4.01是, W3C的头也许是被敲坏了, 认为:&#8221;好了, HTML就这样了, HTML4.01是HTML的最后一个版本了, 我们也用不着HTML工作组了.&#8221;</p>
<p>而事实上W3C并没有停止开发这门语言, 只不过他们对HTML失去了兴趣, 在HTML4.01后, 他们提出了xHTML1.0,虽然听起来完全不同，但是xHTML1.0与HTML4.01其实都是一样的，唯一不同的，就是xHTML1.0要求使用XML语法。也就是说我们现在习以为常的：所有标签必须小写，所有属性必须小写，所有属性值都必须加引号，所有标签必须闭合…</p>
<p>从规范本身的内容看,实际是相同的, 不同之处就是编码风格, 因为对浏览器来说, 读取符合HTML4.01,HTML3.2或者xHTML1.0规范的网页都没有问题, 对于浏览器来说,都会生成相同的DOM树,只不过xHTML1.0严格的编码风格让人们比较偏好.</p>
<p>到了2000年,Web标准项目的活动如火如荼, 开发人员对那些个私有特性都忍无可忍, 大家都在骂浏览器厂商:”他妈的支持个标准真有这么难吗?!”. 正巧那个时候CSS有了长足的发展,而且与xHTML1.0的结合也很紧密, CSS + xHTML1.0基本上就成了”最佳实践”.而xHTML的那种优雅的书写风格在专业人士的带领下, 成为了业界最被认可接受的风格了.</p>
<p>在xHTML1.0之后紧跟着出来的是xHTML1.1,我印象很深刻的是:当时还在用Editplus, 去官网找了个xHTML1.1的template, 结果…</p>
<p>xHTML1.1和xHTML1.0不仅仅是版本号加了0.1这样的差异, 1.1居然是要求必须把文档标记成XML? 而当时最先进的IE无法处理接收到XML文档类型的文档, 这这太崩溃了.而真正使人不想把文档标注成XML的原因是, 如果你在文档中哪怕是只写错了一点点, 比如&amp;没有编码成&amp;amp;那整个页面的渲染结果就是黄屏了,没戏了,这个页面中有一个错误,你丫别想看这个网页了. “如果解析器渠道错误,那就停止解析”是的.这就是XML文档的错误处理机制.</p>
<p>依稀记得xHTML2的坟还没长草, 而促使他死亡的原因就是鲁棒性原则.<br />
1.程序员们不会去支持他,因为XML的错误处理机制和xHTML2故意而为的不向后兼容.<br />
2.浏览器厂商不回去支持他,因为浏览器必须要保证向后兼容.</p>
<p>当然并不是说这样的规范不好, 恰恰相反, 从理论角度他是个非常好的规范, 是个非常好的格式, 但仅限于理论角度, 问题就是他并不实际.</p>
<p>可以说鲁棒性原则是杀死xHTML2.0的战略性理论武器. 而且让他死的非常瞑目.</p>
<p>好吧, 回到当初和xHTML2.0并驾齐驱的HTML5.</p>
<p>HTML5并不是直接由W3C制定的,就在大伙认为HTML应该在HTML4.01时结束生命时, 有那么一伙人认为”也许HTML应该更加长寿一些,只要我们对他稍加扩展,只要我们把放在xHTML的时间和精力拿出一部分，就可以提升下HTML中的表单，让HTML更加接近编程语言，就可以让他更上一层楼”</p>
<p>于是，在2004年Opera的伊恩.希克森提出了一个扩展和改进HTML的建议,他建议新任务和xHTML2并行,但在已有的HTML基础上开展工作,目标是对HTML进行扩展.W3C的投票结果是NO,因为HTML已死,xHTML2才是未来.</p>
<p>于是,Opera,Apple等浏览器厂商以及一些成员说, 那好吧不指望他们了,我们自己也能做好这件事,我们脱离W3C.他们成立了WHATWG.而在接下去的一段时间内,WHATWG的工作效率非常高， 并且在短时间得出了一些成果， 因为他们的工作组成员理由浏览器厂商，因为他们不仅可以说加就加，而可以实现，大家不断地提出一些好点子并且逐一做到了浏览器中。 反观W3C的xHTML2没有什么实质性的进展，特别是从实现的角度来看，用原地踏步形容都不足为过。</p>
<p>戏剧性的事情又发生了， 2006年蒂姆.伯纳斯-李写了一篇博客,说:你们知道吗?我们错了,我们错在企图一夜之间就让web跨入XML时代,我们的想法太不切实际了,是的,也许我们应该重建HTML工作组了.</p>
<p>So,2007年故事就真的这样发展了,W3C组建了HTML5工作组, 这个工作组面临的第一个问题是:我们重头开始做呢,还是在04年成立的那个啥WHATWG工作组的既有成果上开始工作? 答案显而易见,他们又一次投票同意了在WHATWG基础上继续工作.ok, W3C和WHATWG有并肩作战了.</p>
<p>那第二个问题就成了这两个工作组之间的关系,W3C这个工作组的主编是由谁来干呢?是不是让WHATWG的伊恩希克森(google)来?又一次投票,同意了这个提案.</p>
<p>这就变成了2个工作组都有一份自己的规范,而且看起来基本上一样,那到底那份是真正的规范呢?实际上这两个标准还是会分道扬镳,W3C最重要制定一个具体的规范,这个规范最终会成为一个working draft,然后就定格了,而WHATWG呢?他们在不断的迭代,即便是现在HTMl5都不能涵盖他们的目标,他们是正在开发一项简单的HTML或者web技术.</p>
<p>这两个工作组的流程截然相反,因为他们的理念完全不同.</p>
<p>WHATWG可以说是一种独裁的工作机制。我刚才说了，伊恩·希克森是编辑。他会听取各方意见，在所有成员各抒己见，充分陈述自己的观点之后，他批准自己认为正确的意见。</p>
<p>W3C是一种民主的工作机制。所有成员都可以发表意见，而且每个人都有投票表决的权利。这个流程的关键在于投票表决</p>
<p>WHATWG的工作机制让人很不舒服,而W3C的工作机制让人听起来很舒服,但实际情况是WHATWG工作的非常顺畅,主要归功于伊恩·希克森。他的的确确是一个非常称职的编辑。他在听取各方意见时，始终可以做到丝毫不带个人感情色彩。W3C的工作机制很公平，而实际上却非常容易在某些流程或环节上卡壳，造成工作停滞不前，一件事情要达成决议往往需要花费很长时间。</p>
<p>两个截然不同的工作组之所以能够同心同德，主要原因是HTML5的设计思想。因为他们从一开始就确定了设计HTML5所要坚持的原则。结果，我们不仅看到了一份规范，也就是W3C站点上公布的那份文档，即HTML5语言规范，还在W3C站点上看到了另一份文档，也就是HTML设计原理。</p>
<p><strong>二.HTML5设计原则</strong></p>
<p>设计原则, 是一种信念, 一种原则, 一种概念, 是设计原则涉及的人群行动的动力.</p>
<p>不管是W3C在制定规范, 还是通用在制造汽车, 还是我们在编写软件, 甚至是大牛们在创造编程语言, 设计原则也许就是贯穿整件事情的一条主脉, 任何矛盾与挫折都可以用他去衡量.</p>
<p>例如离我们最近的Alibaba公司的设计原则就可以认为是: 让天下没有难做的生意.</p>
<p>再例如Jquery的设计原则是: write less, do more.</p>
<p>说到这里, 我就想起来我们应该问问自己:</p>
<div>1.我们的工业化设计原则是什么?</div>
<div>2.我们的框架的设计原则是什么?</div>
<div><strong>a. avoid needless complexity</strong></div>
<div>
<p>避免不必要的复杂性</p>
<p>举个栗子:</p>
<pre>
<pre class="brush:xml">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8" /&gt;
&lt;link rel="stylesheet" type="text/css" href=""/&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;</pre>
</pre>
<pre>
<pre class="brush:xml">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8" /&gt;
&lt;link rel="stylesheet" type="text/css" href=""/&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;</pre>
</pre>
</div>
<div>
<pre>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" dir="ltr"&gt;
&lt;meta http-equiv="content-type" content="text/html; charset=utf-8" /&gt;
&lt;link rel="stylesheet" type="text/css" href=""/&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;</pre>
</pre>
</div>
<div>上面3端代码片段分别代表着XHTML1, HTML4.01, XHTML1.1的文档类型申明和字符编码申明以及引入JavaScript和CSS时要书写的内容. 好吧, 谁能把这几段默写出来? 大概有人会说:&#8221;你疯了吗? 为什么不用模板生成呢?&#8221;</div>
<div>好吧, 让我们来看一看HTML5的这部分内容:</div>
<div>
<pre>
<pre class="brush:xml">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;meta charset="utf-8" /&gt;
&lt;link rel="stylesheet" href="" /&gt;
&lt;script src=""&gt;&lt;/script&gt;</pre>
</pre>
</div>
<div>
<p>仅此而已。好了，就连我也能过目不忘了。我用不着把这几个字符记在记事本里了。我得说，在我第一次看到这个doctype的时候——我当然以为这是一个HTML文档的doctype——被它吓了一跳：“是不是还少一个数字5啊？”我心里想：“这个doctype想告诉浏览器什么呢？就说这个文档是HTML吗？难道这是有史以来唯一一个HTML版本吗，这件事我得首先搞清楚，HTML今后永远不会再有新版本了吗？”好一副唯我独尊的架式！我错了，因为这个doctype并没有这个意思。为此，必须先搞清楚为什么文档一开头就要写doctype。它不是写给浏览器看的。Doctype是写给验证器看的。也就是说，我之所以要在文档一开头写那行XHTML 1.0的doctype，是为了告诉验证器，让验证器按照该doctype来验证我的文档。</p>
<p>浏览器反倒无所谓了。假设我写的是HTML 3.2文档，文档开头写的是HTML 3.2的doctype。而在文档中某个地方，我使用了HTML 4.01中才出现的一个元素。浏览器会怎么处理这种情况？它会因为这个元素出现在比doctype声明的HTML版本更晚的规范中，就不解释呈现该元素吗？不会，当然不会！它照样会解释呈现该元素，别忘了伯斯塔尔法则，别忘了健壮性。浏览器在接收的时候必须要开放。因此，它不会检查任何格式类型，而验证器会，验证器才关心格式类型。这才是存在doctype的真正原因。</p>
<p>而按照HTML5的另一个设计原理，它必须向前向后兼容，兼容未来的HTML版本——不管是HTML6、HTML7，还是其他什么——都要与当前的HTML版本，HTML5，兼容。因此，把一个版本号放在doctype里面没有多大的意义，即使对验器证也一样。</p>
<p>刚才，我说doctype不是为浏览器写的，这样说大多数情况下没有问题。在有一种情况下，你使用的doctype会影响到浏览器，相信在座诸位也都知道。但在这种情况下，Doctype并非真正用得其所，而只是为了达到某种特殊的目的才使用doctype。当初微软在引入CSS的时候，走在了标准的前头，他们率先在浏览器中支持CSS，也推出了自己的盒模型——后来标准发布了，但标准中使用了不一样的盒模型。他们怎么办？他们想支持标准，但也想向后兼容自己过去推出的编码方式。他们怎么知道网页作者想使用标准，还是想使用他们过去的方式？</p>
<p>于是，他们想出了一个非常巧妙的主意。那就是利用doctype，利用有效的doctype来触发标准模式，而不是兼容模型（quiks mode）。这个主意非常巧妙。我们今天也都是这样在做，在我们向文档中加入doctype时，就相当于声明了“我想使用标准模式”，但这并不是发明doctype的本意。这只是为了达到特殊的目的在利用doctype。</p>
<p>这是在Internet Explorer中触发标准模式的最少字符数目。我认为这也说明了HTML5规范的本质：它不追求理论上的完美。HTML5所体现的不是“噢，给作者一个简短好记的doctype不好吗？”，没错，简短好记是很好，但如果这个好记的doctype无法适应现有的浏览器，还不如把它忘了更好。因此，这个平衡把握得非常好，不仅理论上看是个好主意——简短好记的doctype，而且实践中同样也是个好主意——仍然可以触发标准模式。应该说，Doctype是一个非常典型的例子。</p>
<p>简短好记。我能背下来。</p>
<p>同样，这样写也是有效的。它不仅适用于最新版本的浏览器，只要是今天还有人在用的浏览器都同样有效。为什么？因为在我们把这些meta元素输入浏览器时，浏览器会这样解释它：“元数据（meta）点点点点点，字符集（charset）utf-8。”这就是浏览器在解释那行字符串时真正看到的内容。它必须看到这些内容，根据就是伯斯塔尔法则，对不对？</p>
<p>我多次提到鲁棒性原则，但总有人不理解。我们换一种说法，浏览器会想“好，我觉得作者是想要指定一个字符集……看，没错，utf-8。”这些都是规范里明文规定的。如今，不仅那个斜杠可以省了，而且总共只要写meta charset=”utf-8″就行了。</p>
<p>关于省略不必要的复杂性，或者说避免不必要的复杂性的例子还有不少。但关键是既能避免不必要的复杂性，还不会妨碍在现有浏览器中使用。比如说，在HTML5中，如果我使用link元素链接到一个样式表，我说了rel=”stylesheet”，然后再说type=”text/css”，那就是重复自己了。对浏览器而言，我就是在重复自己。浏览器用不着同时看到这两个属性。浏览器只要看到rel=”stylesheet”就够了，因为它可以猜出来你要链接的是一个CSS样式表。所以就不用再指定type属性了。你不是已经说了这是一个样式表了嘛；不用再说第二次了。当然，愿意的话，你可以再说；如果你想包含type属性，请便。</p>
<p>同样地，如果你使用了script元素，你说type=”text/javascript”，浏览器差不多就知道是怎么回事了。对Web开发而言，你还使用其他的脚本语言吗？如果你真想用其他脚本语言，没人会阻拦你。但我要奉劝你一句，任何浏览器都不会支持你。</p>
<p>愿意的话，你可以添加一个type属性。不过，也可以什么都不写，浏览器自然会假设你在使用JavaScript。避免-不必要的-复杂性。</p>
<p><strong>b. Support existing content</strong></p>
<p><strong><br />
</strong></p>
<p>支持已有的内容</p>
<p>显然，我们都会考虑让Web的未来发展得更好，但他们则必须考虑过去。别忘了W3C这个工作组中有很多人代表的是浏览器厂商，他们肯定是要考虑支持已有内容的。</p>
<p>再来看几段代码:</p>
<pre>
<pre class="brush:xml">&lt;img src="foo" alt="bar" /&gt;&lt;p class="foo"&gt;Hello World&lt;/p&gt;

&lt;img src="foo" alt="bar"&gt;&lt;p class="foo"&gt;Hello World

&lt;IMG SRC="foo" ALT="bar"&gt;&lt;P CLASS="foo"&gt;Hello World&lt;/P&gt;

&lt;img src=foo alt=bar&gt;&lt;p class=foo&gt;Hello World&lt;/p&gt;</pre>
</pre>
<p>这几段代码有问题吗? 没有, 是的, 完全没有问题!</p>
<p>因为我们讨论的只是编码风格或者写作风格，跟哪种语法正确无关.</p>
<p>在JavaScript，你可以在每条语句末尾加上分号，但不是必需的，因为JavaScript会自动插入分号.</p>
<p>当然这并不阻碍我们用XHTML的语法规范来规约大家书写辨识度高的文档, 当然也可以借由lint工具来为我们验证整个文档的正确性.</p>
<p>我个人认为，不仅对团队来说，就算是你自己写代码，也要坚持一种语法风格。从浏览器解析的角度讲，不存在哪种语法比另一种更好的问题，但我认为，作为专业人士，我们必须能够自信地讲“这就是我的编码风格。”然而，我不认为语言里应该内置这种开关。你可以使用lint工具来统一编码风格。现在就来说说lint工具。大家可以登录htmllint.com，在其中运行你的HTML5文档，它会帮你检查属性值是否加了引号，元素是否小写，你还可以通过勾选复选框来设置其他检查项。</p>
<p><strong>c. solve real problems</strong></p>
<p>解决现实的问题</p>
<p>这看起来有点像再说废话, 谁不是为了解决问题在做事情的呢?</p>
<p>而这条设计原理才是真正要解决今天的人们所面临的现实问题、令人头疼的问题。</p>
<p>好吧, 继续看代码:</p>
<pre>
<pre class="brush:xml">&lt;h2&gt;Heading text&lt;/h2&gt;
&lt;p&gt;Paragraph text.&lt;/p&gt;</pre>
</pre>
<p>现在我们需要给这两个文本都加上一个链接, 那我们的做法会是什么? 给h2和p分别加上一个a标签？ 或许，也有聪明的同学会用a标签来整个包住h2和p，就像：</p>
<div>
<pre>
<pre class="brush:xml">&lt;a href="somewhere"&gt;
	&lt;h2&gt;Heading text&lt;/h2&gt;
	&lt;p&gt;Paragraph text.&lt;/p&gt;
&lt;/a&gt;</pre>
</pre>
</div>
<p>这样写有错吗？没错吧？只不过是种不太好的习惯, 并且通不过严格的校验.</p>
<p>但是这样的应用场景肯定存在的, 那为什么不能这样写呢?</p>
<p>这种写法其实早就已经存在于浏览器中了，因为早就有人这样写了，当然以前这样写是不合乎规范的。所以，说HTML5解决现实的问题，其本质还是“你都这样写了很多年了吧？现在我们把标准改了，允许你这样写了。”</p>
<p><strong>d. pave the cowpaths</strong></p>
<p>求真务实</p>
<p>Cowpath： 把一群牛放在地里，然后看牛喜欢怎么走，然后根据牛群踩过的痕迹来铺一条给牛走的路。</p>
<p>很有趣的比喻吧, 说的就是把一些既然存在的东西变得更加标准一些. 接上地气的标准才是能够被执行的标准.</p>
<p>举个栗子:</p>
<p>WHATWG对抽样对大量网站进行了分析, 得出了这样的一个结论:</p>
<p>id=&#8221;header&#8221;, id=&#8221;footer&#8221;, id=&#8221;content&#8221;, id=&#8221;navigation&#8221;, id=&#8221;sidebar&#8221; 这样的命名方式非常常见, 那好吧, 那我就给你们一些这样的标签!</p>
<p>&lt;section&gt;,&lt;article&gt;,&lt;aside&gt;,&lt;nav&gt;,&lt;header&gt;,&lt;footer&gt;,&lt;details&gt;,&lt;figure&gt;</p>
<p>看代码:</p>
<pre>
<pre class="brush:xml">&lt;body&gt;
	&lt;div id="header"&gt;&lt;/div&gt;
	&lt;div id="navigation"&gt;&lt;/div&gt;
	&lt;div id="main"&gt;&lt;/div&gt;
	&lt;div id="sidebar"&gt;&lt;/div&gt;
	&lt;div id="footer"&gt;&lt;/div&gt;
&lt;/body&gt;</pre>
</pre>
</div>
<p>变!</p>
<pre>
<pre class="brush:xml">&lt;body&gt;
	&lt;header&gt;&lt;/header&gt;
	&lt;nav&gt;&lt;/nav&gt;
	&lt;div id="main"&gt;&lt;/div&gt;
	&lt;aside&gt;&lt;/aside&gt;
	&lt;footer&gt;&lt;/footer&gt;
&lt;/body&gt;</pre>
</pre>
<p>怎么样? 像模像样了吧?</p>
<p>再看:</p>
<pre>
<pre class="brush:xml">&lt;div class="item"&gt;
	&lt;h2&gt;&lt;/h2&gt;
	&lt;div  class="meta"&gt;&lt;/div&gt;
	&lt;div  class="content"&gt;&lt;/div&gt;
	&lt;div  class="link"&gt;&lt;/div&gt;
&lt;/div&gt;</pre>
</pre>
<p>再变!</p>
<pre>
<pre class="brush:xml">&lt;section class="item"&gt;
	&lt;header&gt;&lt;h2&gt;&lt;/h2&gt;&lt;/header&gt;
	&lt;footer class="meta"&gt;&lt;/ footer &gt;
	&lt;div class="content"&gt;&lt;/div&gt;
	&lt;nav class="link"&gt;&lt;/nav&gt;
&lt;/section&gt;</pre>
</pre>
<p>虽然在这个文档中，我们用这些新元素来替换的是id，但在我个人看来，将它们作为类的替代品更有价值。为什么这么说呢？因为这些元素在一个页面中不止可以使用一次，而是可以使用多次。没错，你可以为文档添加一个头部（header），再添加一个脚部（footer）；但文档中的每个分区（section）照样也都可以有一个头部和一个脚部。而每个分区里还可以嵌套另一个分区，被嵌套的分区仍然可以有自己的头部和脚部，是这样吧？</p>
<p>这四个新元素：section、article、aside和nav，之所以说它们强大，原因在于它们代表了一种新的内容模型，一种HTML中前所未有的内容模型——给内容分区。迄今为止，我们一直都在用div来组织页面中的内容，但与其他类似的元素一样，div本身并没有语义。但section、article、aside和nav实际上是在明确地告诉你——这一块就像文档中的另一个文档一样。位于这些元素中的任何内容，都可以拥有自己的概要、标题，自己的脚部。</p>
<p>其中最为通用的section，可以说是与内容最相关的一个。而article则是一种特殊的section。aside呢，是一种特殊的section。最后，nav也是一种特殊的section。</p>
<p>最重要的是它们的语义；跟位置没有关系。</p>
<p>这里，请注意，最重要的还不是我用几个新元素替换了原来的div加类，而是我把原来的H2换成了H1——震撼吧，我看到有人发抖了。我碰到过不少职业的Web开发人员，多年来他们一直认为规范里说一个文档中只能有一个H1。还有一些自诩为万能的SEO秘诀同样说要这样。很多SEO的技巧其实是很教条的。所谓教条，意思就是不相信数据。过去，这种教条表现为“不行，页面中包含两个以上的H1，你就会死掉的。”在HTML5中，只要你建立一个新的内容块，不管用section、article、aside、nav，还是别的元素，都可以在其中使用H1，而不必担心这个块里的标题在整个页面中应该排在什么级别；H2、H3，都没有问题。</p>
<p>这个变化太厉害了。想一想吧，这个变化对内容管理是革命性的。因为现在，你可以把每个内容分区想象一个独立的、能够从页面中拿出来的部分。此时，根据上下文不同，这个独立部分中的H1，在整个页面中没准会扮演H2或H3的角色——取决于它在文档中出现的位置。面对这个突如其来的变化，也许有人的脑子会暂时转不过弯来。不要紧，但我可以告诉你，我认为这才是HTML5中这些新语义标记的真正价值所在。换句话说，我们现在有了独立的元素了，这些元素中的标题级别可以重新定义。</p>
<p><strong>e. degrade gracefully</strong></p>
<p>优雅降级</p>
<p>HTML5中设计了这么些新玩意：</p>
<pre class="brush:xml">input type="number"
input type="search“
input type="range"
input type="email"
input type="date"
input type="url"</pre>
<p>很有趣, 但是浏览器不认识, 怎么办呢?</p>
<p>最关键的问题在于浏览器在看到这些新type值时会如何处理。现有的浏览器，不是将来的浏览器，现有的浏览器是无法理解这些新type值的。但在它们看到自己不理解的type值时，会将type的值解释为text。</p>
<p>无论你写的是input type=”foo”还是input type=”bar”，现有的任何浏览器都会说：“嗯，也许作者的意思是text。”因而，你从现在开始就可以使用这些新值，而且你也可以放心，那些不理解它们的浏览器会把新值看成type=”text”，而这真是一个浏览器实践平稳退化原理的好例子。</p>
<p>比如说，你现在输入了type=”number”。假设你需要一个输入数值的文本框。那么你可以把这个input的type属性设置为number，然后理解它的浏览器就会呈现一个可爱的小控件，像带小箭头图标的微调控件之类的。对吧？而在不理解它的浏览器中，你会看到一个文本框，一个你再熟悉不过的文本框。既然如此，为什么不能说输入type=”number”就会得到一个带小箭头图标的微调控件呢？</p>
<p>当然，你还可以设置最小和最大值属性，它们同样可以平稳退化。这是问题的关键。</p>
<p>HTML5还为输入元素增加了新的属性，比如placeholder（占位符）。有人不知道这个属性的用处吗，没有吧？没错，就是用于在文本框中预先放一些文本。不对，不是标签（label）——占位符和标签完全不是一回事。占位符就是文本框可以接受的示例内容，一般颜色是灰色的。只要你一点击文本框，它就消失了。如果你把已经输入的内容全部删除，然后单击了文本框外部，它又会出现。</p>
<p>使用JavaScript编写一些代码当然也可以实现这个功能，但HTML5只用一个placeholder属性就帮我们解决了问题。</p>
<p>当然，对于不支持这个属性的浏览器，你还是可以使用JavaScript来实现占位符功能。通过JavaScript来测试浏览器支不支持该属性也非常简单。如果支持，后退一步，把路让开，乐享其成即可。如果不支持，可以再让你的JavaScript来模拟这个功能。</p>
<p>再来看一个比较极端的优雅降级方案:</p>
<pre>
<pre class="brush:xml">&lt;video&gt;
 	&lt;source src="movie.mp4"&gt;
 	 &lt;source src="movie.ogv"&gt;
 	 &lt;source src="movie.webm"&gt;
 	 &lt;object data="movie.swf"&gt;
 	 	 &lt;a href="movie.mp4"&gt;download&lt;/a&gt;
 	 &lt;/object&gt;
&lt;/video&gt;</pre>
</pre>
<p>很NB吧&#8230;</p>
<p><strong>f. Priority of  constituencies</strong></p>
<p>最终用户优先</p>
<p>事先声明, 这是条很哲学的设计原则, 没有代码可以看.</p>
<p>它的意义就是: 一旦遇到冲突，最终用户优先，其次是作者，其次是实现者，其次标准制定者，最后才是理论上的完满。</p>
<p>在有人建议了某个特性，而HTML5工作组为此争论不下时，如果有浏览器厂商说“我们不会支持这个特性，不会在我们的浏览器中实现这个特性”，那么这个特性就不会写进规范。因为即使是把特性写进规范，如果没有厂商实现，规范不过是一纸空文，对不对？实现者可以拒绝实现规范。</p>
<p>嗯, 要学会辩证的去看这些问题, 别钻牛角尖就好.</p>
<p>最后附上PPT, 花了老子半天时间整的20页啊!!!</p>
<p><a href="http://f2e.aliui.com/wp-content/uploads/2011/04/HTML5-设计原则.pptx">HTML5 设计原则</a></p>
<p>还有这次分享的出处, Jeremy老板在W3C Tech上的分享的PPT(PDF)</p>
<p><a href="http://f2e.aliui.com/wp-content/uploads/2011/04/Jeremy-DesignOfHTML5.pdf">Jeremy-DesignOfHTML5</a></p>
<p>还有感谢新总分享的翻译版Design of HTML5, 这篇文章在我编PPT时很给力:<br />
<a href="http://f2e.aliui.com/?p=245">JEREMY KEITH在 FRONTEERS 2010 上的主题演讲</a></p>
<p>以及他的原文出处,感谢为之漫笔(李松峰):<br />
<a href="http://www.cn-cuckoo.com/2010/10/21/the-design-of-html5-2151.html">JEREMY KEITH在 FRONTEERS 2010 上的主题演讲</a></p>
<p style="text-align: right;">注：此文版权属于 <strong>赵振宇</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2011/07/26/402/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>阿里巴巴国际站UED博学堂</title>
		<link>http://www.aliued.com/2010/06/23/325/</link>
		<comments>http://www.aliued.com/2010/06/23/325/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 12:06:54 +0000</pubDate>
		<dc:creator>行骏</dc:creator>
				<category><![CDATA[Web Developer]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=325</guid>
		<description><![CDATA[博学乃学识渊博，知道的多，了解的广。堂乃我们之集体。博学堂以提高我们整体的知识为目标开展活动。博学堂为前端开发者和网站设计者提供了一个交流分享的平台。一起分享代码的乐趣... ]]></description>
			<content:encoded><![CDATA[<p><a><img class="alignnone size-full wp-image-326" title="aliUED博学堂" src="http://www.aliued.com/wp-content/uploads/2010/06/2008317133917607_2.jpg" alt="aliUED博学堂" width="533" height="533" /></a></p>
<p>博学乃学识渊博，知道的多，了解的广。堂乃我们之集体。<strong>博学堂</strong>以提高我们整体的知识为目标开展活动。<strong>博学堂</strong>为前端开发者和网站设计者提供了一个交流分享的平台。一起分享代码的乐趣，总结项目的成长，展望新技术的发展。</p>
<p><strong>博学堂</strong>是国际站UED内部的分享平台。专注于知识分享、工作交流、成果推广等领域，致力于构建自由、开放、互助的分享环境。只要你敢喷，我们就给你提供舞台！ 自愿参与，广泛的话题，充足的时间，充分的自由！</p>
<p>简单列举了曾经的分享主题：<br />
<strong>1. </strong><strong>JIRA</strong><strong>系统应用</strong><strong>：</strong>Jira系统是优秀的项目管理与工作流跟踪软件，目前已经在UED全面部署应用。</p>
<p><strong>2. </strong><strong>JS</strong><strong>开发心得：</strong>主要分享在大图预览与智能联想开发过程中的编程思路、难点解决方案。内容涉及： 图片缩放及拖拽预览解决方案； 模块化编程的应用思路； 探讨如何保证复用性的同时，使程序具备一定的扩展性。</p>
<p><strong>3. </strong><strong>异步上传组件：</strong>异步上传组件的设计思路及其布署方案。<br />
<img class="size-full wp-image-327" title="异步上传组件" src="http://www.aliued.com/wp-content/uploads/2010/06/zsS8snPtKvB9w_iGBrqIE4g2yJ.jpg" alt="异步上传组件" width="500" /></p>
<p><strong>4. </strong><strong>大图预览及其组件设计，内容有：</strong>A 封装用prototype JS，甚至iframe都动态生成;B 只有放大超出区域才启用拖动，且拖动限定范围;C 拖动启用半透明预览/虚线框定位平滑过渡效果;D 放大缩小加入动画效果;E 长按平滑放大/缩小效果实现,增量增加比例;F 放大比例条</p>
<p><strong>5. </strong><strong>UED</strong><strong>在项目中的流程框架</strong></p>
<p><strong>6. </strong><strong>前端利器之 Fiddler</strong></p>
<p><strong>7. </strong><strong>Unicorn</strong><strong>基于High Performance Web Sites的最佳实践</strong></p>
<p><strong>8. </strong><strong>UED</strong><strong>图片格式，压缩处理</strong></p>
<p><strong>9. </strong><strong>阿里巴巴国际站前端核心框架结构讨论会</strong></p>
<p><strong>10. </strong><strong>WordPress</strong><strong>分享等</strong></p>
<p><strong>以上更多的只是简单的和不完全的列举，博学堂为阿里巴巴国际站UED积累了很多宝贵的资料和分享，接下来希望这样的交流能够有更多的人参与进来，并且可以分享到更多的人。</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2010/06/23/325/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>第4届D2前端技术论坛开始报名</title>
		<link>http://www.aliued.com/2009/12/05/322/</link>
		<comments>http://www.aliued.com/2009/12/05/322/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 09:26:58 +0000</pubDate>
		<dc:creator>Lucars</dc:creator>
				<category><![CDATA[Web Developer]]></category>
		<category><![CDATA[D2]]></category>
		<category><![CDATA[前端技术]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=322</guid>
		<description><![CDATA[2005年前端工程师的职位开始在中国出现，2007年第一届D2前端技术论坛在杭州举行，从此D2伴随着中国的前端一起成长，从此越来越多的互联网产品的背后有着职业前端工程师坚定的身影。 在D2... ]]></description>
			<content:encoded><![CDATA[<p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding: 0px;">2005年前端工程师的职位开始在中国出现，2007年第一届D2前端技术论坛在杭州举行，从此D2伴随着中国的前端一起成长，从此越来越多的互联网产品的背后有着职业前端工程师坚定的身影。</p>
<p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding: 0px;">在D2上我们曾交流过某项具体的前端技术，也曾探讨过团队协作的方式，那些美妙的话题都深入到我们频繁敲键盘的指尖。回首我们过去四年的坚持和梦想，现在是时候分享我们的积累和成果了。当架构、安全、性能等等在前端的领域扎根的时候，我们自己也在悄然发生质变，而推动这些变化的人和事正是D2想告诉你的。</p>
<ul style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 30px; list-style-type: none; list-style-position: initial; list-style-image: initial; padding: 0px;">
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">本届主题</strong>：<a style="text-decoration: underline; color: #0064b1;" href="http://www.d2forum.org/d2/4/">蜕变·成长</a></li>
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">论坛时间</strong>：2009年12月19日(星期六)</li>
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">论坛地点</strong>：杭州市滨江区网商路699号, 阿里巴巴B2B园区 <span style="font-size: 12px;">（<a style="text-decoration: underline; color: #456b95;" href="http://hangzhou.edushi.com/?oid=29529">地图</a>）</span></li>
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">举办单位</strong>：<a style="text-decoration: underline; color: #456b95;" href="http://www.alibaba.com/">阿里巴巴</a></li>
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">特别致谢</strong>：<a style="text-decoration: underline; color: #0064b1;" href="http://www.csdn.net/">CSDN</a>、<a style="text-decoration: underline; color: #456b95;" href="http://www.javaeye.com/">JavaEye</a>、<a style="text-decoration: underline; color: #0064b1;" href="http://www.g-fox.cn/">谋智网络</a>、<a style="text-decoration: underline; color: #0064b1;" href="http://www.baidu.com/">百度</a>、<a style="text-decoration: underline; color: #456b95;" href="http://www.douban.com/">豆瓣</a>、<a style="text-decoration: underline; color: #0064b1;" href="http://www.hzbook.com/ps/">华章图书</a>、<a style="text-decoration: underline; color: #456b95;" href="http://www.koubei.com/">口碑网</a>、<br />
<a style="text-decoration: underline; color: #0064b1;" href="http://www.blueidea.com/">蓝色理想</a>、<a style="text-decoration: underline; color: #0064b1;" href="http://www.qq.com/">腾讯网</a>、<a style="text-decoration: underline; color: #0064b1;" href="http://www.turingbook.com/">图灵教育</a>、<a style="text-decoration: underline; color: #456b95;" href="http://www.taobao.com/">淘宝网</a>、<a style="text-decoration: underline; color: #0064b1;" href="http://www.alipay.com/">支付宝</a>。</li>
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">官网地址</strong>：<a style="text-decoration: underline; color: #0064b1;" href="http://www.d2forum.org/d2/4/">d2forum.org</a></li>
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">推广视频</strong>：<a style="text-decoration: underline; color: #0064b1;" href="http://v.youku.com/v_show/id_XMTM2NDI0MDU2.html">http://v.youku.com/v_show/id_XMTM2NDI0MDU2.html</a></li>
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">报名地址</strong>：<a style="text-decoration: underline; color: #0064b1;" href="http://www.d2forum.org/d2/4/sign_up.html">http://www.d2forum.org/d2/4/sign_up.html</a><span style="font-size: 12px;">（截止时间：2009.12.14 0:0:0）</span></li>
<li style="list-style-type: disc; padding: 0px; margin: 0px;"><strong style="font-weight: bold;">日程安排</strong>：<br />
<table id="table-d2" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-size: 12px; border-top-width: 1px; border-right-width: initial; border-bottom-width: initial; border-left-width: 1px; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-top-color: #cccccc; border-right-color: initial; border-bottom-color: initial; border-left-color: #cccccc;" border="0">
<thead>
<tr>
<th style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: #f3f3f3; background-position: initial initial; padding: 5px; margin: 0px;" width="100" scope="col">时间</th>
<th style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: #f3f3f3; background-position: initial initial; padding: 5px; margin: 0px;" width="270" scope="col">主题</th>
<th style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: #f3f3f3; background-position: initial initial; padding: 5px; margin: 0px;" scope="col">嘉宾</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">08:45 – 09:15</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">入场</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;"></td>
</tr>
<tr>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">09:15 – 10:15</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">《模板语言与大前端》</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;"><a style="text-decoration: underline; color: #0064b1;" href="http://www.d2forum.org/2009/05/04/d2_fourth_guest_intro_jindawei/">金大为（百度）</a></td>
</tr>
<tr>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">10:30 – 11:30</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">《从YUI2到YUI3看前端的演变》</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;"><a style="text-decoration: underline; color: #456b95;" href="http://www.d2forum.org/2009/04/30/d2_fourth_guest_intro_zhangkejun/">张克军（豆瓣）</a></td>
</tr>
<tr>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">11:30 – 13:00</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">午饭/休息/参观（阿里巴巴免费提供午餐）</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;"></td>
</tr>
<tr>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">13:00 – 14:00</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">《SilverlightQQ项目实践——Silverlight架构思考》</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;"><a style="text-decoration: underline; color: #456b95;" href="http://www.d2forum.org/2009/04/16/d2_fourth_guest_intro_zyk/">甄焱鲲（腾讯）</a></td>
</tr>
<tr>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">14:15 – 15:15</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">《前端安全概览及防范》</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;"><a style="text-decoration: underline; color: #0064b1;" href="http://www.d2forum.org/2009/05/09/d2_fourth_guest_intro_mingcheng/">吕峰军（淘宝）</a></td>
</tr>
<tr>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">15:30 – 16:30</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">《前端性能优化与自动化》</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;"><a style="text-decoration: underline; color: #456b95;" href="http://www.d2forum.org/2009/12/03/d2_fourth_guest_intro_yanxuekun/">鄢学鵾（口碑）</a></td>
</tr>
<tr>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">16:30 – 18:00</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;">交流互动</td>
<td style="border-top-width: initial; border-right-width: 1px; border-bottom-width: 1px; border-left-width: initial; border-top-style: none; border-right-style: solid; border-bottom-style: solid; border-left-style: none; border-top-color: initial; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: initial; padding: 5px; margin: 0px;"></td>
</tr>
</tbody>
</table>
<p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding: 0px;">注意：以上安排可能会根据具体情况进行一些补充与修改。</p>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2009/12/05/322/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>产品列表到底应该怎么做?</title>
		<link>http://www.aliued.com/2008/12/18/143/</link>
		<comments>http://www.aliued.com/2008/12/18/143/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 11:39:56 +0000</pubDate>
		<dc:creator>Lucars</dc:creator>
				<category><![CDATA[Web Developer]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[清除浮动]]></category>
		<category><![CDATA[自适应高度]]></category>
		<category><![CDATA[语义]]></category>

		<guid isPermaLink="false">http://www.aliued.com/?p=143</guid>
		<description><![CDATA[最近随着狂风计划的席卷，我也终于开始橱窗产品位列表展示的编码工作，这只是一个改进项目，因此有原代码可供参考。但是当我打开原代码模板的时候便愣住了，一个4 × n的矩阵为了执行d... ]]></description>
			<content:encoded><![CDATA[<p>最近随着狂风计划的席卷，我也终于开始橱窗产品位列表展示的编码工作，这只是一个改进项目，因此有原代码可供参考。但是当我打开原代码模板的时候便愣住了，一个4 × n的矩阵为了执行div + CSS的标准而放弃使用非常牛B的table布局，这本无可厚非，可是由于“某原因”（后文会陈述）却让本来很有优势的div布局失去了原有的优势，在我反复思考这个问题的时候怎样都觉得table布局能比现在的这个更加合适。那么这个非常霹雳的布局是怎么样的呢？请见下图：</p>
<div id="attachment_144" class="wp-caption alignnone" style="width: 510px"><a href="http://www.aliued.com/wp-content/uploads/2008/12/productlist01.png"><img class="size-full wp-image-144 " title="产品列表结构图" src="http://www.aliued.com/wp-content/uploads/2008/12/productlist01.png" alt="产品列表结构图（png太牛B了只有18K）" width="500" height="468" /></a><p class="wp-caption-text">产品列表结构图（png太牛B了只有18K）</p></div>
<p>我想绝大多数UEDer都不会使用如上布局来实现这个模块，首先想到的当然是使用DIV[productItem]做4 × n次的循环，然而这个布局却使用程序控制每四个DIV[productItem]给它们套一个DIV[productListRow]。可能很多人都已经发现了，这个布局有一个先天性的不足，也就是前文提到的“某原因”，那就是<strong>由于产品简介的长度不同导致每个DIV[productItem]的高度不同</strong>，因此需要在每行列表后面都清除浮动以让浏览器可以做出正确排列。那么解决办法也就出来了，很简单，有如下几个：</p>
<p>1、最方便、最有效、性价比最高的方法就是我们当然可以知道最长长度的产品名称和产品简介，因此我们分别取这两个值排满的最高高度来作为DIV[productItem]即可，但是这个方法却有致命的缺点导致所有UEDer都不会这么做得，那就是当出现有人不填写产品简介或者产品简介填写得非常少的时候便会出现大段的空白严重影响观看阅读。</p>
<p>2、那就这样把，咱把“产品简介”给拿掉吧，然后使用方法1便可以完美解决问题了。这个想法非常牛B，可是它太牛B了，我绝对不敢这样操刀直接把这么重要的内容给砍掉（也许有人觉得这些内容并不重要，但是这不是这篇文章所要讨论的东西）。我对曾经抱有次想法表示遗憾和羞愧。</p>
<p>3、<strong>为什么不使用table布局呢？</strong>天哪我觉得这简直就是最完美的办法了，table一出八马难追的。能够自适应高度的table在这个应用上拥有绝对的优势啊，如果前端开发工程师们可以放下一点架子在html上使用它原本应该使用的结构该是多么美好的事情，我直到在写这篇博客的时候依然觉得使用table解决问题又快又省力还很有快感哦~（其实原代码中的div布局就是抄袭了table的“思想理念”了）</p>
<p>但是作为一个在非常牛B的UED团队的还是菜鸟的我为了要做出非常牛B的事情也为了团队的面子，怎样也不能使用上面三种投机取巧的办法来敷衍这个现实的问题吧，因此就有了这篇博客最重要的内容。</p>
<p><strong><span style="text-decoration: underline;">第一次尝试：</span></strong></p>
<p>首先我们还是来考虑考虑到底使用什么标签来写这个列表吧，所谓back 2 base嘛。重新分析列表中最重要的元素有且仅有：标题、图片、简介。显然标题是最重要的，作为一个product的title存在，而图片和简介都是用来描述标题的内容，因此第一个想到的标签就是dl，这样便有了以下布局（抱歉还没有时间整一个代码输入）：</p>
<blockquote><p>&lt;dl&gt;<br />
&lt;dt&gt;[name]&lt;/dt&gt;<br />
&lt;dd&gt;&lt;div&gt;[photo]&lt;/div&gt;&lt;div&gt;[intro]&lt;/div&gt;&lt;/dd&gt;<br />
&lt;/dl&gt;</p></blockquote>
<p>对dt和dd都做float:left，dt做一个margin-top:100px来定位到图片和简介中间，dd做一个margin-left:-25%来定位到和dt相同的x坐标（由于无法输入代码就不贴css了）这样的html是我认为最贴切的，根据现在流行的html语义化定义这样的布局太合适不过了。当然css中还是存在非常多的困难，而前面所说的“某原因”也并没有得到解决，反而更甚了，因为把标题和简介流拆开后，标题过长便会和简介的文字叠加根本无法阅读！然而经过几秒钟的思考后认为这玩意儿的解决已经超出了我的范围了。当然，有人可能会说把标题和图片换一个不就可以了么？是的，没错，但是如果这样的话使用dl标签还有什么意义呢？可能有意义吧，就是标题和简介都是为了说明这张图片而存在的，但是真的可以这么想吗？还有待实验去证明，这里就不讨论了。</p>
<p><strong><span style="text-decoration: underline;">第二次尝试：</span></strong></p>
<p>如上所述，dl的存在就没意义了，那就算了吧，退而求其次使用ul（<strong>请在砸我鸡蛋前念着我还死了那么多脑细胞在这个上面的份上轻点儿吧</strong>），无序列表虽然不如定义列表来得语义那么强烈，但至少它还是和列表吧，至少不是一个division吧。ul的布局相比较就简单多了，看上去也只是把div标签换成了li而已，那么html结构如下：</p>
<blockquote><p>&lt;ul&gt;<br />
&lt;li&gt;&lt;div&gt;[photo]&lt;/div&gt;<br />
&lt;div&gt;[name]&lt;/div&gt;<br />
&lt;div&gt;[intro]&lt;/div&gt;<br />
&lt;/li&gt;<br />
&lt;/ul&gt;</p></blockquote>
<p>到这个时候终于要直面本文第四次提到的“某原因”了，如何解决li浮动后高度不同导致的矩阵错位问题？最先进入脑子的想法就是记得很久很久以前看到过一篇关于div自适应高度的文章，于是就在google翻找，当时没有收藏真是太失误了。在google搜索自适应高度那是相当多呀，但是有<a title="A List Apart: Articles: In Search of the Holy Grail" href="http://www.alistapart.com/articles/holygrail" target="_blank">一篇文章是不得不借鉴</a>的，但是这篇文章并不是适应于我们的案例，很显然它更适用于两栏或者三栏布局，而我们至少有四栏甚至五栏。自此还有什么办法可以让多列布局自适应高度呢？（请不要跟我提关于<a title="Equal Height Columns - revisited - In search of the One True Layout" href="http://www.positioniseverything.net/articles/onetruelayout/equalheight" target="_blank">巨大的padding与负margin这件事</a>）伪装的自适应对于需要货真价实产品的我们是没有用的……至此思维告一段落，我需要回到源头来，最开始的出发点在哪里？如果只是为了清除浮动的话？使用最简单的方法？</p>
<p>带着上面的问题，便渐渐有了解决方案，不可避免的，我可能需要借助后台工程师的力量了，我在每4个li之后的那个li上加上<a title="CSS clear 属性" href="http://www.w3school.com.cn/css/pr_class_clear.asp" target="_blank">clear:left属性</a>，以清除左边的浮动来防止它因为前面li的高度不够而导致的错位，从它之后的li就应该会乖乖地跟在它的后面了。这个想法很美好，但是很天真，可能我确实在FF等标准浏览器下面获得了预想中的效果（没有想到实现起来那么简单，正在开心中），突然发现又是那该死的IE！！！那个加了clear属性的li确实正常显示了，但是在它之后的那些继续原来它应该范的错误，没有起到清除整行浮动的作用。我懊恼了~通过漫长的研究至今已经找到了一个语义和样式都比较平衡的点却无法在IE中得以实现，怎么办？</p>
<p>第一个想法就是使用hack技术（虽然UEDer们都不推崇，但是为了维护之前的成果，老子发飙了），问题就是如何做hack。先看这样的例子，如果我每4个li后面都插一个&lt;li style=”clear:both;float:none;”&gt;&lt;/li&gt;的话，不管在IE下还是在FF下都可以完美地完成任务，但是这个方案有一个致命的缺陷，就是对原有html语义的破坏，凭什么好好的列表突然就多出一个空li来？那么能不能在不影响原来语义的情况下，在FF依然使用它应该使用的clear:left方式的情况下来针对IE进行hack呢？非常幸运的是IE给我们提供了条件注释工具<a title="CSS - Conditional comments" href="http://www.quirksmode.org/css/condcom.html" target="_blank">&lt;!–[if IE]&gt;&lt;![endif]–&gt;</a>（我想一旦开始使用这个东西之后一定会非常依赖它的），因此html结构就变成了这样：</p>
<blockquote><p>&lt;li&gt;[productItem]&lt;/li&gt;<br />
&lt;!–[if IE]&gt;&lt;li class=”clearForIE”&gt;&lt;/li&gt;&lt;![endif]–&gt;<br />
&lt;li class=”clearForFF”&gt;[productItem]&lt;/li&gt;</p></blockquote>
<p>希望这样能够看得懂。至此为了尽力表述完整语义的目的就达到了，因为所有的浏览器、搜索引擎和用户都会把那段IE的hack作为一个普通的注释来看待（这里也包括IE自己，这是一段条件注释，那还是注释），因此产品列表的li就没有被中途无故打断，更不会像最早的div版本每四个是一个division。到这里研究工作就算完成了（关于这个IE特有的hack的可能的严重后果木有给予考虑。。。），不过还有一些额外的思考。</p>
<p>其实使用division也不完全是不好，如果division这样做：</p>
<blockquote><p>&lt;div class=”top20″&gt;<br />
&lt;div class=”top15″&gt;<br />
&lt;div class=”top10″&gt;<br />
&lt;div class=”top5″&gt;<br />
DIV[productItem]{1-5}<br />
&lt;/div&gt;<br />
DIV[productItem]{6-10}<br />
&lt;/div&gt;<br />
DIV[productItem]{11-15}<br />
&lt;/div&gt;<br />
DIV[productItem]{16-20}<br />
&lt;/div&gt;</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.aliued.com/2008/12/18/143/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
	</channel>
</rss>

