<?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>岁月如歌</title>
	<atom:link href="http://lifesinger.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://lifesinger.org/blog</link>
	<description>关注用户体验、前端开发，记录生活点滴、岁月足迹。</description>
	<lastBuildDate>Sun, 29 Aug 2010 11:02:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Behind a Gist</title>
		<link>http://lifesinger.org/blog/2010/08/behind-a-gist/</link>
		<comments>http://lifesinger.org/blog/2010/08/behind-a-gist/#comments</comments>
		<pubDate>Sun, 29 Aug 2010 09:52:05 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[思考]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2703</guid>
		<description><![CDATA[这是 8 月 26 日在前端架构懒懒分会上的分享：slide@github（请用 Chrome 浏览） 掺杂了两个主要话题：一个是老生常谈的兼容性探测代码的写法，另一个是 JavaScript 比较语句中的隐性转换。 什么叫伪特性探测？看代码： if(window.ActiveXObject) { // 一堆和 ActiveXObject 半毛钱关系都没有的代码 } 微探测的研究和探索精神都很值得推崇，但正式代码中尽量少用。质朴清晰更重要，能节省团队和自己未来的理解时间。 UA 不是恶魔，在大部分情况下，UA 是最可靠的。 探测代码的关键是尽量做到能自适应未来版本和自适应未知设备。针对特定版本的浏览器嗅探不会带来隐患： if(ie &#60; 7) { // 给 ie 增加 css 的 hover 支持 } 想想，上面的代码用特性探测如何写？可以把浏览器嗅探看成是打包了一堆特性的特性探测，只要这一堆特性是稳定的，不会给未来版本带来隐患，这时浏览器嗅探就是合理的，该用时就大胆用。（注意：大部分情况下，不带版本号的浏览器嗅探会给未来版本留下垃圾代码甚至隐患，要慎用。） 第二个话题是解释 a == b 的判断规律，详见 behind-a-gist.html#slide20. 弱类型动态语言，为了方便用户使用，一般都会自动进行类型的隐性转换。Douglas Crockford 认为 == 是糟粕，但实际上只要掌握了其中的转换规律，糟粕也可以成为精华。一个非常棒的应用是： // 让 UA.ie 的默认值是 undefined, 在 ie [...]]]></description>
			<content:encoded><![CDATA[<p>这是 8 月 26 日在前端架构懒懒分会上的分享：<a href="http://lifesinger.github.com/share/2010/behind-a-gist.html">slide@github</a>（请用 Chrome 浏览）</p>
<p>掺杂了两个主要话题：一个是老生常谈的兼容性探测代码的写法，另一个是 JavaScript 比较语句中的隐性转换。</p>
<p>什么叫伪特性探测？看代码：</p>
<pre>
if(window.ActiveXObject) {
    // 一堆和 ActiveXObject 半毛钱关系都没有的代码
}
</pre>
<p>微探测的研究和探索精神都很值得推崇，但正式代码中尽量少用。质朴清晰更重要，能节省团队和自己未来的理解时间。</p>
<p>UA 不是恶魔，在大部分情况下，UA 是最可靠的。</p>
<p>探测代码的关键是尽量做到能<strong>自适应未来版本</strong>和<strong>自适应未知设备</strong>。针对特定版本的浏览器嗅探不会带来隐患：</p>
<pre>
if(ie &lt; 7) {
    // 给 ie 增加 css 的 hover 支持
}
</pre>
<p>想想，上面的代码用特性探测如何写？可以把浏览器嗅探看成是打包了一堆特性的特性探测，只要这一堆特性是稳定的，不会给未来版本带来隐患，这时浏览器嗅探就是合理的，该用时就大胆用。（注意：大部分情况下，不带版本号的浏览器嗅探会给未来版本留下垃圾代码甚至隐患，要慎用。）</p>
<p>第二个话题是解释 a == b 的判断规律，详见 <a href="http://lifesinger.github.com/share/2010/behind-a-gist.html#slide20">behind-a-gist.html#slide20</a>. 弱类型动态语言，为了方便用户使用，一般都会自动进行类型的隐性转换。Douglas Crockford 认为 == 是糟粕，但实际上只要掌握了其中的转换规律，糟粕也可以成为精华。一个非常棒的应用是：</p>
<pre>
// 让 UA.ie 的默认值是 undefined, 在 ie 下，UA.ie = ie 的主版本号
// 这样，
if(UA.ie &lt; 8) {
    // 针对 ie6 和 ie7 的代码
}
</pre>
<p>上面的 API 微设计，利用了 <code>undefined &lt; 8</code> 为 false 的特性，有效避免了不少类库里的冗余写法 <code>if(UA.ie &#038;&#038; UA.ie &lt; 8) { }</code>.</p>
<p>探测代码 &#8211; 大道无形，道法自然。<br />
a == b &#8211; 此中有真意，欲辩已忘言。</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/08/behind-a-gist/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>KISSY 快讯（2）</title>
		<link>http://lifesinger.org/blog/2010/08/kissy-briefings-2/</link>
		<comments>http://lifesinger.org/blog/2010/08/kissy-briefings-2/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 04:50:01 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[KISSY]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2689</guid>
		<description><![CDATA[转眼又过了半个月，汇报下 KISSY 的新进展和相关资讯： 1. 经过一个多月的开发，KISSY Editor 2.0 已初具雏形： static-demo.html &#8211; 静态载入 loader-demo.html &#8211; 动态载入 下周将进入测试和细节完善阶段。大家有什么想法和需求，欢迎反馈。目前源码已放到 kissy-editor@github 上，欢迎 fork 和 review code. 2. 经过一年多的线上需求反馈，KISSY Suggest 已发布 1.1 版。这不是一个新鲜组件，基本上是各大网站的标配，但要做好做完美并不容易。目前 淘宝, 去哪儿 等站点已采用。很期待在您的站点上，也能看到 KISSY Suggest 的身影。 3. 浩行天下的研究精神非常值得推崇：KISSY 事件模型研究（2）. 没看的赶紧看，可以让你对 jQuery 和 KISSY 的事件机制有更深入的理解。 4. 做为前端开发工程师，不得不深刻关注浏览器占比，下面是淘宝首页昨天的统计数据： KISSY 类库立足国内，UA 组件里添加了对国内浏览器的嗅探: ua docs 非常期待 IE6 的份额在国内跌破 50% 5. 小鹤与独角兽撰写了两篇入门级的 KISSY [...]]]></description>
			<content:encoded><![CDATA[<p>转眼又过了半个月，汇报下 KISSY 的新进展和相关资讯：</p>
<p>1. 经过一个多月的开发，KISSY Editor 2.0 已初具雏形：</p>
<ul>
<li><a href="http://kissyteam.github.com/kissy-editor/tests/static-test.html">static-demo.html</a> &#8211; 静态载入</li>
<li><a href="http://kissyteam.github.com/kissy-editor/tests/loader-test.html">loader-demo.html</a> &#8211; 动态载入</li>
</ul>
<p>下周将进入测试和细节完善阶段。大家有什么想法和需求，欢迎反馈。目前源码已放到 <a href="http://github.com/kissyteam/kissy-editor">kissy-editor@github</a> 上，欢迎 fork 和 review code.</p>
<p>2. 经过一年多的线上需求反馈，<a href="http://lifesinger.org/blog/2010/08/ks-suggest-1-1/">KISSY Suggest 已发布 1.1 版</a>。这不是一个新鲜组件，基本上是各大网站的标配，但要做好做完美并不容易。目前 <a href="http://taobao.com/">淘宝</a>, <a href="http://labs.qunar.com/">去哪儿</a> 等站点已采用。很期待在您的站点上，也能看到 KISSY Suggest 的身影。</p>
<p>3. 浩行天下的研究精神非常值得推崇：<a href="http://ghsky.com/2010/08/kissy-event-model-part-two.html">KISSY 事件模型研究（2）</a>. 没看的赶紧看，可以让你对 jQuery 和 KISSY 的事件机制有更深入的理解。</p>
<p>4. 做为前端开发工程师，不得不深刻关注浏览器占比，下面是淘宝首页昨天的统计数据：<br />
<img src="http://lifesinger.org/blog/wp-content/uploads/2010/08/browsers.png" alt="browsers" height="207"/><img src="http://lifesinger.org/blog/wp-content/uploads/2010/08/browsers-core.png" alt="core" height="208" /><br />
KISSY 类库立足国内，UA 组件里添加了对国内浏览器的嗅探: <a href="http://kissyteam.github.com/kissy/docs/ua/index.html">ua docs</a><br />
非常期待 IE6 的份额在国内跌破 50%</p>
<p>5. 小鹤与独角兽撰写了两篇入门级的 KISSY 学习心得：<a href="http://www.rainoina.com/raino/archive/429.html">Kissy 库学习小结（一）</a> 和 <a href="http://www.rainoina.com/raino/archive/431.html">Kissy 库学习小结（二）</a>. 建议一读。</p>
<p>6. 来个预告：lizzie mm 精心制作的 Getting Started with KISSY 系列即将出炉，敬请期待。</p>
<p>7. 最后，作为压轴新闻，KISSY 核心已支持 loader 机制：<a href="http://kissyteam.github.com/kissy/src/kissy/test-loader.html">test-loader.html</a>. 支持多实例和共享机制：<a href="http://kissyteam.github.com/kissy-editor/tests/loader-test.html">loader-demo.html</a>. KISSY Editor 的代码组织和加载机制均基于 KISSY Loader. 我们要使用某个组件时，仅需引入 gzip 后不到 5k 的种子文件 seed.js, 然后 use 调用相关组件即可，比如：</p>
<pre>
&lt;script src="http://kissyteam.github.com/kissy/build/seed-min.js"&gt;&lt;/script&gt;
&lt;script&gt;
KISSY.use('switchable', function(S) {
    new S.Slide('#id');
});
&lt;/script&gt;
</pre>
<p>关于 Loader 的部分研究，可以阅读拔赤的文章：<a href="http://www.uedmagazine.com/ued/comments.php?y=10&#038;m=08&#038;entry=entry100814-104521">KISSY Loader 的设计</a></p>
<p>快讯完毕，期待您的参与和反馈。</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/08/kissy-briefings-2/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>优雅兼容之理想与现实</title>
		<link>http://lifesinger.org/blog/2010/08/graceful-is-hard/</link>
		<comments>http://lifesinger.org/blog/2010/08/graceful-is-hard/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 02:11:36 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[思考]]></category>
		<category><![CDATA[graceful-degradation]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2684</guid>
		<description><![CDATA[infinte 总是能给我们带来一些新思路新想法：更优雅的兼容 很不错的思路。不过实际操作时，并不好组织。比如：getOffset （获取 elem 相对 page 的偏移量）方法，对于高级浏览器，直接 getBoundingClientRect + win.scrollLeft/Top 即可。对于低级浏览器，比如 Safari 2, 得利用 offsetParent 不断向上回溯叠加。至此，利用文中提及的优雅兼容，可构造： nullDriver = {}; dhtmlDriver = derive(nullDriver); w3cDriver = derive(dhtmlDriver); if(supportsGetBoundingClientRect) { w3cDriver.getOffset = function() { ... } } else { dhtmlDriver.getOffset = function() { ... } } 看起来很美妙，可是问题不这么简单。w3cDriver.getOffset 里，依旧还有浏览器差异，比如在同是 webkit, 桌面版和 ipad 版是有差异的，并且郁闷的是，这个差异不大，就那么一两行代码。传统写法： w3cDriver.getOffset = function() { ... [...]]]></description>
			<content:encoded><![CDATA[<p>infinte 总是能给我们带来一些新思路新想法：<a href="http://typeof.net/2010/08/compatibility-with-elegance/">更优雅的兼容</a></p>
<p>很不错的思路。不过实际操作时，并不好组织。比如：getOffset （获取 elem 相对 page 的偏移量）方法，对于高级浏览器，直接 getBoundingClientRect + win.scrollLeft/Top 即可。对于低级浏览器，比如 Safari 2, 得利用 offsetParent 不断向上回溯叠加。至此，利用文中提及的优雅兼容，可构造：</p>
<pre>
nullDriver = {};
dhtmlDriver = derive(nullDriver);
w3cDriver = derive(dhtmlDriver);

if(supportsGetBoundingClientRect) {
    w3cDriver.getOffset = function() { ... }
} else {
    dhtmlDriver.getOffset = function() { ... }
}
</pre>
<p>看起来很美妙，可是问题不这么简单。w3cDriver.getOffset 里，依旧还有浏览器差异，比如在同是 webkit, 桌面版和 ipad 版是有差异的，并且郁闷的是，这个差异不大，就那么一两行代码。传统写法：</p>
<pre>
w3cDriver.getOffset = function() {
    ...
    if(isAppleMobileWebkit) { // bug fix }
    else { // go on }
    ...
}
</pre>
<p>按照优雅思路，上面的代码很 ugly, 一个可能的重构：<span id="more-2684"></span></p>
<pre>
appleMobileWebkitDriver = derive(w3cDriver)
appleMobileWebkitDriver.getOffset = function() { ... }
</pre>
<p>但这样的话，appleMobileWebkitDriver.getOffset 和 w3cDriver.getOffset 两个方法中将存在大量冗余代码。如何避免，获取可以利用 super.method:</p>
<pre>
appleMobileWebkitDriver.getOffset = function() {
    w3cDriver.getOffset();
    // fix code
}
</pre>
<p>但问题并不如此简单，fix code 有可能并不能简单放在 super.method 前面和后面。很可能得拆分：</p>
<pre>
w3cDriver.getOffsetPartA = function() { ... }
w3cDriver.getOffsetPartB = function() { ... }
appleMobileWebkitDriver.getOffset = function() {
    w3cDriver.getOffsetPartA();
    // fix code
   w3cDriver.getOffsetPartB();
}
</pre>
<p>（注意：对于 getOffset 来说，是可以仅重复少量代码，来使得 fix code 放在后面即可，上面仅是示例）</p>
<p>光拆分还不行，还得合并：</p>
<pre>
w3cDriver.getOffset = function() {
    this.getOffsetPartA();
    this.getOffsetPartB();
}
</pre>
<p>可以看出，原本两个 if else 可以搞定的事情，用优雅兼容思路重构后，代码量增加了很多，一定程度上，更晦涩了。</p>
<p>稍等，上面的代码还未考虑 dhtmlDriver.getOffset 的具体实现。现实世界里，这里面的差异更丰富多彩：</p>
<pre>
// from Ext 3.2
getXY : function(el) {
...
if (Ext.isGecko) {
    ...
}
...
if (Ext.isSafari &#038;&#038; hasAbsolute) {
    ...
}
...
if (Ext.isGecko &#038;&#038; !hasAbsolute) {
    ...
}
...
if (!Ext.isOpera || (...)) {
    ...
}
...
}
</pre>
<p>这真是一个糟糕的世界。采用 driver 思路，或许得构造出：</p>
<pre>
safariHasAbsDriver = derive(dhtmlDriver);
geckoNoAbsDriver = derive(dhtmlDriver);
nonOperaDrive = derive(dhtmlDrive);
</pre>
<p>还得拆分 dhtmlDriver.getOffset 方法，想想都麻烦，就不必再继续演示了。或许可以放在 dhtmlDriverBugfix 里，但这样的话，仅是将代码转移了一个地方，里面依旧达不到优雅。</p>
<p>等等，一开头我们还犯了个错误，getBoundingClientRect 其实是 IE 的标准，其它浏览器看着好，就抄袭过去（IE 当年的霸气，至今依旧在）。W3C 看大家差不多都实现了，于是写入标准。基于这个考虑，或许应该这么命名：</p>
<pre>
defactoDriver = derive(nullDriver)
fallbackDriver = derive(defactoDriver)
</pre>
<p>总结下来，导致兼容性代码的因素有：</p>
<ol>
<li>特性支持不全，比如 IE8- 不支持 getElementsByClassName. 这是最好解决的，给 IE 实现一个就行。</li>
<li>特性都支持，但有命名/调用接口或其它细节上的差异。典型是 DOM Range 接口。如果大家都支持 IE 的标准，世界很美妙。如果大家都支持 Mozzila 的接口，世界也很美妙。但现实世界是，大家各自实现自家的标准，细节差异一堆，杯具啊。所以做编辑器的，比如 FCKEditor, 干脆自己用 dom 操作再实现一套代码，完全不依赖各个浏览器的实现。要统一，得消灭。秦始皇焚书坑儒，估计也是被逼的。</li>
<li>还一种兼容代码，是设备差异引起的。比如桌面浏览器和 mobile 浏览器，不少地方，理念上都发生变化，代码实现上，肯定得变。</li>
</ol>
<p>再总结下目前常用的兼容代码的写法技巧：</p>
<p>代码组织上，用 if else / switch 还是其它。在大量重构书籍里，会告诉你，switch 和 if else 往往代表着某种坏味道，经常可以用工厂模式或对象模式（我杜撰的，对应 js 里的 { condition: code } 的分支重构法）等方式重构掉。但我觉得，如果 if else 并没引起混乱，看起来依旧清晰时，是不用重构的。计算机语言里，创造了 if else, 就不要排斥。</p>
<p>分支判断上，浏览器嗅探和特性探测。浏览器嗅探，这个大家都很熟悉，但最近一两年来，以 John Resig 为代表的一批先锋，开始抨击浏览器嗅探的种种不是。jQuery 里，直接不推荐再调用 browser, 全面改用 support. 但我觉得，事情没有这么绝对。浏览器嗅探就和 table 一样，table 布局遭受抨击，但并不意味着，就不能用 table. 该用 table 的地方，还是得大胆用。浏览器嗅探也如此。具体原因，看下一条。</p>
<p>进一步分析第二点，特性探测的好处究竟是什么？特性探测的好处是能自动适应未来设备和未知设备，比如 if(document.addEventListener) 假设 IE9 支持标准事件，则代码不用修改，就自适应了“未来浏览器”。对于未知浏览器也是如此。但是，这并不意味着浏览器嗅探就得彻底抛弃。当代码很明确就是针对已知特定浏览器的，或者并非是某个特性探测可以解决时，用浏览器嗅探反而能带来代码的简洁，同时也也不会有什么后患。</p>
<p>忘了哪位达人曾说过：每一个优雅的架构下面，都有一堆龌龊的实现。最近看陈冠中的《盛世 &#8211; 2013》，里面提到莱布尼茨的一句话挺有意思：在所有可能的世界中的最好的一个世界里，一切都已经是最好的了。因此优雅的架构和想法下面，龌龊的实现，或许已经是最好的了。当然，我们不能放弃对更好的追求。最后感谢 infinte, 一切让人往好的方向思考的尝试，都是值得钦佩的。</p>
<p>总之，一切皆权衡。</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/08/graceful-is-hard/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>提示补全组件 KISSY Suggest 1.1 更新</title>
		<link>http://lifesinger.org/blog/2010/08/ks-suggest-1-1/</link>
		<comments>http://lifesinger.org/blog/2010/08/ks-suggest-1-1/#comments</comments>
		<pubDate>Sun, 08 Aug 2010 14:56:20 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[KISSY]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2677</guid>
		<description><![CDATA[不了解的可以先看下这贴：KISSY Suggest 1.0 发布 这次更新主要有以下几点： 去除对 yahoo-dom-event 的依赖，完全仅依赖 ks-core 去掉了对静态 JSON 数据源的支持，因为实际项目中，从未出现过类似需求。（预告：类似需求将由正在开发中的 combobox 组件提供） 对 PgDn/PgUp/Down/Up 等页面导航控制键的智能响应。由于主搜索框一般会设置自动聚焦，这对键盘用户来说，当打开页面的第一操作不是搜索而是滚动页面时，自动聚焦会带来“干扰”。目前 Suggest 能有效“猜测”用户意图，当你想翻页时，就 PgDn 吧，不用再怀疑键盘是否失灵了。 增强了自定义事件，可以满足过去一年多以来，淘宝对 suggest 的各种定制化需求。 对焦点的管理更加健壮。目前可以满足当提示框下面是 iframe 时（比如页面的主内容是 iframe 的情况），点击 iframe 区域时，也能关闭提示框，无跨域问题。 输入框宽度改变时，提示层显示时，宽度的自动自适应，以及其它一些细节的优化。 支持 ipad 等 touch 设备。（注意：iphone 一代请升级 safari 浏览器到最新版） 文件大小更小了：min 压缩后 8.3k 测试页面：test.html（总共 30 项测试用例，目前除了 KISSY Suggest, 只有 Google 搜索提示能全部通过） 示范页面：demo.html（看下源码，相信你就知道如何使用了） 下载：ks-core-min.js + suggest-min.js [...]]]></description>
			<content:encoded><![CDATA[<p>不了解的可以先看下这贴：<a href="http://lifesinger.org/blog/2009/07/kissy-suggest/">KISSY Suggest 1.0 发布</a><br />
这次更新主要有以下几点：</p>
<ol>
<li>去除对 yahoo-dom-event 的依赖，完全仅依赖 ks-core</li>
<li>去掉了对静态 JSON 数据源的支持，因为实际项目中，从未出现过类似需求。（预告：类似需求将由正在开发中的 combobox 组件提供）</li>
<li>对 PgDn/PgUp/Down/Up 等页面导航控制键的智能响应。由于主搜索框一般会设置自动聚焦，这对键盘用户来说，当打开页面的第一操作不是搜索而是滚动页面时，自动聚焦会带来“干扰”。目前 Suggest 能有效“猜测”用户意图，当你想翻页时，就 PgDn 吧，不用再怀疑键盘是否失灵了。</li>
<li>增强了自定义事件，可以满足过去一年多以来，淘宝对 suggest 的各种定制化需求。</li>
<li>对焦点的管理更加健壮。目前可以满足当提示框下面是 iframe 时（比如页面的主内容是 iframe 的情况），点击 iframe 区域时，也能关闭提示框，无跨域问题。</li>
<li>输入框宽度改变时，提示层显示时，宽度的自动自适应，以及其它一些细节的优化。</li>
<li>支持 ipad 等 touch 设备。（注意：iphone 一代请升级 safari 浏览器到最新版）</li>
<li>文件大小更小了：min 压缩后 8.3k</li>
</ol>
<p>测试页面：<a href="http://kissyteam.github.com/kissy/src/suggest/test.html">test.html</a>（总共 30 项测试用例，目前除了 KISSY Suggest, 只有 Google 搜索提示能全部通过）<br />
示范页面：<a href="http://kissyteam.github.com/kissy/src/suggest/demo.html">demo.html</a>（看下源码，相信你就知道如何使用了）</p>
<p>下载：<a href="http://kissyteam.github.com/kissy/build/packages/ks-core-min.js">ks-core-min.js</a> + <a href="http://kissyteam.github.com/kissy/build/suggest/suggest-min.js">suggest-min.js</a></p>
<p>自定义事件简明说明：</p>
<pre>
beforeStart    // 监控计时器开始前触发，可以用来做条件触发
itemSelect     // 选中某项时触发，可以用来添加监控埋点等参数
beforeSubmit  // 表单提交前触发，可以用来取消提交或添加特定参数
beforeDataRequest  // 请求数据前触发，可以用来动态修改请求 url 和参数
dataReturn     // 获得返回数据时触发，可以用来动态修正数据
updateFooter  // 更新底部内容时触发，可以用来动态添加自定义内容
beforeShow    // 显示提示层前触发，可以用来动态修改提示层数据
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/08/ks-suggest-1-1/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>KISSY 快讯（1）</title>
		<link>http://lifesinger.org/blog/2010/08/kissy-briefings-1/</link>
		<comments>http://lifesinger.org/blog/2010/08/kissy-briefings-1/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 14:33:26 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[KISSY]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2675</guid>
		<description><![CDATA[KISSY 已于公元二零一零年八月二日发布，下面是相关资讯： 1. Lizzie mm 发布了一篇 About KISSY. “每个框架总有她自身的设计理念，最开始要想清楚的原则，以后就能按照此原则坚定不移的执行下去。而 kissy, 越仔细看就越喜欢:P” 简单质朴的文字，让人心里暖和和的。一起加油! 2. 浩行天下 据说从初中就开始写博文，所以文章质量那是杠杠的：KISSY事件模型研究（1）. 有志于深入了解 KISSY 的，赶快订阅吧。 3. 隆重推荐近期上线迅速红火史上最快上线的淘宝赛马项目：淘网址. 该项目是全世界上下五千年以来，第一个完全基于 KISSY 类库开发的独立站点。别小看它，作为 IT 精英的你可能压根儿不会去用，但是不妨先读读 L 和 W 先生的故事, 或许你就会领会到淘网址的巨大意义了。KISSY 的愿景之一是简洁实用，能用在淘网址上，深感荣幸。 4. 最后，低调隆重预告：淘宝首页已完全重构为仅依赖 KISSY 类库，同时采用了千呼万唤始出来的 cdn combo 服务。除了前端底层的革新，这次视觉设计和 CSS3 的运用上，也大胆尝试。让一直很低调的云谦 gg 都喊爽了：让前端忍不住喊爽的设计元素. 请耐心等待 8 月 6 日，淘宝首页，Thanks YUI, and says goodbye to YUI forever! 5. [...]]]></description>
			<content:encoded><![CDATA[<p>KISSY 已于公元二零一零年八月二日发布，下面是相关资讯：</p>
<p>1. Lizzie mm 发布了一篇 <a href="http://lizziesky.appspot.com/post/108001/">About KISSY</a>. “每个框架总有她自身的设计理念，最开始要想清楚的原则，以后就能按照此原则坚定不移的执行下去。而 kissy, 越仔细看就越喜欢:P” 简单质朴的文字，让人心里暖和和的。一起加油!</p>
<p>2. 浩行天下 据说从初中就开始写博文，所以文章质量那是杠杠的：<a href="http://ghsky.com/2010/08/kissy-event-model-part-one.html">KISSY事件模型研究（1）</a>. 有志于深入了解 KISSY 的，赶快订阅吧。</p>
<p>3. 隆重推荐近期上线迅速红火史上最快上线的淘宝赛马项目：<a href="http://123.taobao.com/">淘网址</a>. 该项目是全世界上下五千年以来，第一个完全基于 KISSY 类库开发的独立站点。别小看它，作为 IT 精英的你可能压根儿不会去用，但是不妨先读读 <a href="http://ucdchina.com/snap/7365">L 和 W 先生的故事</a>, 或许你就会领会到淘网址的巨大意义了。KISSY 的愿景之一是简洁实用，能用在淘网址上，深感荣幸。</p>
<p>4. 最后，低调隆重预告：淘宝首页已完全重构为仅依赖 KISSY 类库，同时采用了千呼万唤始出来的 cdn combo 服务。除了前端底层的革新，这次视觉设计和 CSS3 的运用上，也大胆尝试。让一直很低调的云谦 gg 都喊爽了：<a href="http://www.chencheng.org/blog/2010/08/04/cool-design-elements/">让前端忍不住喊爽的设计元素</a>. 请耐心等待 8 月 6 日，淘宝首页，Thanks YUI, and says goodbye to YUI forever!</p>
<p>5. 不忍心这么快结束此文，爆料下来淘宝面试满分一鸣惊人的 承玉 gg 的近期进展：<a href="http://lite-ext.googlecode.com/svn/trunk/lite-ext/playground/editor/test/styles-test.html">KISSY Editor 2.0 开发进行时版</a>. 完全基于 KISSY, 完全有理由相信，这将是一个精简小巧，极具潜力超越 CKEditor 的新一代编辑器。很快将会正式转移到 github 上的  <a href="http://github.com/kissyteam/kissy-editor">kissy-editor</a>  中维护，敬请期待。</p>
<p>还不结束，就不能称快讯了，赶紧洗洗睡去^o^</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/08/kissy-briefings-1/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>发布开源前端类库 KISSY 1.1.0</title>
		<link>http://lifesinger.org/blog/2010/08/release-kissy-1-1-0/</link>
		<comments>http://lifesinger.org/blog/2010/08/release-kissy-1-1-0/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 16:59:08 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[KISSY]]></category>
		<category><![CDATA[library]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2663</guid>
		<description><![CDATA[是否还记得，去年 10 月份的 美女与汽车 ? 眨眼近一年时光，KISSY 已经从一个开源编辑器的代号，演化成一个开源前端类库的名称。 愿景 KISSY 的愿景是：打造一个小巧灵活、简洁实用、使用起来让人感觉愉悦的前端 UI 类库。 源码 KISSY 基于 MIT 协议，完全开源。目前在 github 上管理：kissy@github 欢迎 fork! 欢迎 pull request! 我们相信，开源能让 KISSY 走向卓越。 文档 KISSY 的文档地址也在 github 上：docs 目前还不够丰富，但请相信我们，想要的，一定会有的。 下载与使用 github 的功能非常便捷：downloads 下载包里包含了所有源码和 build 好的文件。生产环境下使用时，建议引用 build/packages/ks-core-min.js 文件，然后再根据需要引用相关组件的 js 即可。 Version 1.1.0 1.1.0 版本，主要包括 core/css/utils 三大部分。widgets 部分，目前正式发布的仅有 switchable 组件。为了保证质量，接下来会逐步发布 suggest, imagezoom, combobox, [...]]]></description>
			<content:encoded><![CDATA[<p>是否还记得，去年 10 月份的 <a href="http://lifesinger.org/blog/wp-content/uploads/2009/10/road2girl.jpg">美女与汽车</a> ?<br />
眨眼近一年时光，KISSY 已经从一个开源编辑器的代号，演化成一个开源前端类库的名称。</p>
<p><img class="noborder" src="http://kissyteam.github.com/kissy.png" alt="kissy.png" width="138" height="74" /></p>
<h4>愿景</h4>
<p>KISSY 的愿景是：打造一个小巧灵活、简洁实用、使用起来让人感觉愉悦的前端 UI 类库。</p>
<h4>源码</h4>
<p>KISSY 基于 MIT 协议，完全开源。目前在 github 上管理：<a href="http://github.com/kissyteam/kissy">kissy@github</a><br />
欢迎 fork! 欢迎 pull request!</p>
<p>我们相信，开源能让 KISSY 走向卓越。</p>
<h4>文档</h4>
<p>KISSY 的文档地址也在 github 上：<a href="http://kissyteam.github.com/kissy/docs/">docs</a><br />
目前还不够丰富，但请相信我们，想要的，一定会有的。</p>
<h4>下载与使用</h4>
<p>github 的功能非常便捷：<a href="http://github.com/kissyteam/kissy/downloads">downloads</a><br />
下载包里包含了所有源码和 build 好的文件。生产环境下使用时，建议引用  build/packages/ks-core-min.js 文件，然后再根据需要引用相关组件的 js 即可。</p>
<h4>Version 1.1.0</h4>
<p>1.1.0 版本，主要包括 core/css/utils 三大部分。widgets 部分，目前正式发布的仅有 switchable 组件。为了保证质量，接下来会逐步发布 suggest, imagezoom, combobox, overlay 等组件。你的耐心和反馈，能让 KISSY 更完美。</p>
<h4>Version 1.2.0</h4>
<p>1.2.0 版本已经在开发中，包含的组件：<a href="http://kissyteam.github.com/kissy/docs/version/tasklist_v1.2.html">tasklist_v1.2.html</a><br />
9 月份将发布包括 editor 新版在内的诸多组件，敬请期待。</p>
<h4>致谢</h4>
<p>看书最不喜欢看的就是啰啰嗦嗦的致谢。但 KISSY 能走到今天，首先得感谢家人的支持，芳芳和小雕，还有爸妈，没有你们的支持，一切皆无可能。其次不得不感谢业界各位朋友和淘宝各位同事的支持。具体名字不用多说，拔赤、沉鱼、龙藏、正淳、明城、云谦、承玉、乔花、龙笛等，github 的提交记录里，已经永久留下了你们的名字。我希望更多的名字，也能很快出现在 commit log 里。还有不留名的二当家、小马、三通等人的支持，就不多说了，你们知道的。</p>
<p>修改下梭罗的一句话：如果一个团队自信地朝着梦想的方向前进，以破釜沉舟的勇气追求想要的类库，那么成功，就不会那么遥远。</p>
<p>深夜发文，有点困，有点累，也有点兴奋。最后给张 KISSY 在三亚度假的图：<br />
<img src="http://lifesinger.org/blog/wp-content/uploads/2010/08/kissy-sanya.jpg" alt="kissy-sanya.jpg" width="600" height="450" /><br />
将 KISSY 刻在心底，坚持坚强的走下去，何惧浪打风吹。</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/08/release-kissy-1-1-0/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Google Docs Ctrl + C 技术浅析</title>
		<link>http://lifesinger.org/blog/2010/07/goog-docs-copy-tech/</link>
		<comments>http://lifesinger.org/blog/2010/07/goog-docs-copy-tech/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 07:42:10 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[clipboard]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2657</guid>
		<description><![CDATA[用 google docs 打开 pdf 文件，选中文本： 表面上没有任何有趣的地方。但仔细一看，会发现选区的颜色是浅蓝色，而不是默认蓝。第一直觉是是有什么特殊的 CSS 属性，立马 firebug: 不看不知道，一看真蹊跷。selection-highlight 是选区，选区下面是一张图片 page-image! 于是立刻发现一个非常牛逼的特性：Ctrl + C 可以复制图片中的文字！ google 太强悍了，好在前端代码都是开源的，下面简单分析下。 首先数据在哪呢，这个比较容易找到，在 firebug 里有一个请求返回的数据如下： &#60;?xml version="1.0" encoding="UTF-8"?&#62; &#60;pdf2xml&#62; &#60;meta name="Creator" content="Adobe Acrobat 8.1 Combine Files"/&#62; &#60;meta name="Producer" content="Adobe Acrobat 8.1"/&#62; &#60;meta name="CreationDate" content="20100316080708-04'00'"/&#62; &#60;page t="0" l="0" w="612" h="773"&#62; &#60;text l="188" t="754" w="237" h="11" p="188,24,214,15,232,37,271, 7,280,39,322,7,330,11,344,24,370,23,395,20,418,7"&#62; Please post [...]]]></description>
			<content:encoded><![CDATA[<p>用 google docs 打开 pdf 文件，选中文本：<br />
<img src="http://lifesinger.org/blog/wp-content/uploads/2010/07/goog-docs-tech-01.png" width="429" height="171" /></p>
<p>表面上没有任何有趣的地方。但仔细一看，会发现选区的颜色是浅蓝色，而不是默认蓝。第一直觉是是有什么特殊的 CSS 属性，立马 firebug:<br />
<img src="http://lifesinger.org/blog/wp-content/uploads/2010/07/goog-docs-tech-02.png" width="526" height="324" /></p>
<p>不看不知道，一看真蹊跷。<code>selection-highlight</code> 是选区，选区下面是一张图片 <code>page-image</code>!<br />
于是立刻发现一个非常牛逼的特性：<strong><code>Ctrl + C</code> 可以复制图片中的文字！</strong></p>
<p>google 太强悍了，好在前端代码都是开源的，下面简单分析下。<span id="more-2657"></span></p>
<p>首先数据在哪呢，这个比较容易找到，在 firebug 里有一个请求返回的数据如下：</p>
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;

&lt;pdf2xml&gt;
&lt;meta name="Creator" content="Adobe Acrobat 8.1 Combine Files"/&gt;
&lt;meta name="Producer" content="Adobe Acrobat 8.1"/&gt;
&lt;meta name="CreationDate" content="20100316080708-04'00'"/&gt;
&lt;page t="0" l="0" w="612" h="773"&gt;
 &lt;text l="188" t="754" w="237" h="11" p="188,24,214,15,232,37,271,
7,280,39,322,7,330,11,344,24,370,23,395,20,418,7"&gt;
Please post comments or corrections to the Author Online forum at&lt;/text&gt;
...
</pre>
<p>有了这份数据，就可以根据选区得到对应的文本。</p>
<p>接下来的问题是，如何将文本放到剪贴板里？第一反应是用 flash 实现，但感觉 google 不会这么做。禁用掉 flash 插件后，功能正常，这说明是用 js 实现的。</p>
<p>通过 Profile 工具 + Fiddler + 肉眼识别 + 运气，终于定位到了关键代码：</p>
<pre>
n.am = function(a) {
    if (! (!this.k.Ca &#038;&#038; Mr(this, a))) {
        ac &#038;&#038; this.lf.focus();
        this.lf.select();
        Nr(this, a)
    }
};
</pre>
<p>只要注释掉上面的代码，<code>Ctrl + C</code> 复制功能就无效。<code>focus</code> 和 <code>select</code> 为我们提供了进一步线索，在 HTML 里，发现了秘密：<br />
<img src="http://lifesinger.org/blog/wp-content/uploads/2010/07/goog-docs-tech-03.png" width="514" height="50" /></p>
<p>到此真相大白：当用户按下 <code>Ctrl + C</code> 时，js 会注入事件，首先根据坐标从数据里取出对应文本，然后将文本赋值给 textarea, 并将其激活和选中。这样，就和用户选中 textarea 的内容，再按下 <code>Ctrl + C</code> 的效果是一样了。</p>
<p>强悍的 google, 技术创新无处不在！</p>
<p>注意：利用 textarea 只能复制纯文本，如果想复制富文本，可以借鉴 google docs 编辑 Word 文档时的处理方式：采用 iframe 充当临时容器，有兴趣的可以进一步研究。</p>
<p>简单演示：<a href="http://lifesinger.github.com/lab/2010/goog-docs-copy-demo.html">goog-docs-copy-demo.html</a></p>
<p>发现这个秘密后，最近在疯狂搞编辑器的牛人<a href="http://yiminghe.javaeye.com/">承玉</a>（欢迎搞编辑器的其他牛人加盟）立刻想到了各大站长们非常喜爱的功能：<a href="http://yiminghe.javaeye.com/blog/722264">附带警告信息的禁止copy</a>. 据说，能成功复制的，都不是“人”。</p>
<p>我的尝试是：点击按钮，复制指定文本到 Clipboard 里。应用场景是点击按钮复制证件号码等。尝试代码大家可以看上面 demo 页面源码中的注释。事件可以正常模拟并分发出去，但复制操作惨兮兮地失败了。感觉原因在于浏览器安全限制，对于触发的异步 <code>Ctrl + C</code>, 浏览器会限制其功能。 </p>
<p>Google 的产品里有很多秘密，真诱人，创意无限！</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/07/goog-docs-copy-tech/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>KISSY 迁移到 github.com</title>
		<link>http://lifesinger.org/blog/2010/07/kissy-on-github-com/</link>
		<comments>http://lifesinger.org/blog/2010/07/kissy-on-github-com/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 14:22:16 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[工具]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[KISSY]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2653</guid>
		<description><![CDATA[终于迁移到 github.com 了，欢迎 fork: github.com/kissyteam 调整了目录组织： 文档迁移到：KISSY Docs Git 使用，推荐阅读： 1. Git Reference（简明扼要的介绍了 Git 的基本理念和常用命令） 2. Pro Git &#124; 中文（深入浅出，看完不喜欢 Git 都难） 原本计划 7 月 22 日发布的 v1.1 版本，推迟到 8 月 2 日。详情：plan_v1.1.html v1.2 也已经在开发中，包含编辑器等组件：plan_v1.2.html 欢迎感兴趣的朋友与我联系，帮忙 review code 或者直接参与到 KISSY 组件的开发中来，等的就是你。]]></description>
			<content:encoded><![CDATA[<p>终于迁移到 github.com 了，欢迎 fork: <a href="http://github.com/kissyteam">github.com/kissyteam</a></p>
<p>调整了目录组织：<br />
<img src="http://kissyteam.github.com/team.png" alt="kissy team structure" width="627" height="420" /></p>
<p>文档迁移到：<a href="http://kissyteam.github.com/kissy/docs/">KISSY Docs</a></p>
<p>Git 使用，推荐阅读：<br />
1. <a href="http://gitref.org/">Git Reference</a>（简明扼要的介绍了 Git 的基本理念和常用命令）<br />
2. <a href="http://progit.org/book/">Pro Git</a> | <a href="http://progit.org/book/zh/">中文</a>（深入浅出，看完不喜欢 Git 都难）</p>
<p>原本计划 7 月 22 日发布的 v1.1 版本，推迟到 8 月 2 日。详情：<a href="http://kissyteam.github.com/kissy/docs/version/plan_v1.1.html">plan_v1.1.html</a><br />
v1.2 也已经在开发中，包含编辑器等组件：<a href="http://kissyteam.github.com/kissy/docs/version/plan_v1.2.html">plan_v1.2.html</a></p>
<p>欢迎感兴趣的朋友与我联系，帮忙 review code 或者直接参与到 KISSY 组件的开发中来，等的就是你。</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/07/kissy-on-github-com/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>用 JS 枚举质数</title>
		<link>http://lifesinger.org/blog/2010/07/js-prime-number/</link>
		<comments>http://lifesinger.org/blog/2010/07/js-prime-number/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 13:53:51 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[prime]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2647</guid>
		<description><![CDATA[酷壳上的这篇文章很诱人：检查素数的正则表达式 翻译成 JavaScript 代码如下： function prime(MAX) { var re = /^(11+?)\1+$/, n, C = '1', s = C, r = [], j = 0; while ((n = (s += C).length) < MAX) { !re.test(s) &#038;&#038; (r[j++] = n); } return r; } alert(prime(10000).length); 作为前端，为了让上面的脚本能在实际页面中应用，还得考虑 脚本在浏览器中的耐心 以及 分时优化处理。 最后，请猛击测试页面：prime-number.html]]></description>
			<content:encoded><![CDATA[<p>酷壳上的这篇文章很诱人：<a href="http://coolshell.cn/?p=2704">检查素数的正则表达式</a><br />
翻译成 JavaScript 代码如下：</p>
<pre>
function prime(MAX) {
    var re = /^(11+?)\1+$/,
        n, C = '1', s = C,
        r = [], j = 0;

    while ((n = (s += C).length) < MAX) {
        !re.test(s) &#038;&#038; (r[j++] = n);
    }
    return r;
}
alert(prime(10000).length);
</pre>
<p>作为前端，为了让上面的脚本能在实际页面中应用，还得考虑 <a href="http://www.planabc.net/2009/02/04/how_long_time_will_javascript_execute_in_browsers/">脚本在浏览器中的耐心</a> 以及 <a href="http://lifesinger.org/blog/2009/08/big-array-processing/">分时优化处理</a>。</p>
<p>最后，请猛击测试页面：<a href="http://lifesinger.github.com/lab/2010/prime-number.html">prime-number.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/07/js-prime-number/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>What it really is, not what it is</title>
		<link>http://lifesinger.org/blog/2010/07/what-it-really-is-not-what-it-is/</link>
		<comments>http://lifesinger.org/blog/2010/07/what-it-really-is-not-what-it-is/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 14:44:07 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[思考]]></category>
		<category><![CDATA[dess]]></category>
		<category><![CDATA[KISSY]]></category>
		<category><![CDATA[really]]></category>
		<category><![CDATA[ui3]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2642</guid>
		<description><![CDATA[看了 infinte 的这篇文章：再见，Button；你好，Command, 和我这半年的一些想法很相近，本质是对 UI Controls 的再次抽象分类。 传统的 UI 控件分类，体现的是 what is looks like, 比如 Menu, Button, Tabs, Toolbar, Dialog, Grid, Tree 等等。 近期新近的一些 UI 类库比如 jQuery EasyUI, 开始逐步抽象出 Draggable, Droppable, Resizable 等 Base 功能点，这些形容词已经逐步开始从 what to do, not what it is 层面开始抽象。虽然 EasyUI 最后体现出来的依旧是 Menu, Dialog, Tree 等传统 UI 控件，但抽象层次和代码组织等已经逐步演化。 前不久在 InfoQ 发过一篇文章：构建 UI [...]]]></description>
			<content:encoded><![CDATA[<p>看了 infinte 的这篇文章：<a href="http://corodidea.net/blog/index.php/archives/272">再见，Button；你好，Command</a>, 和我这半年的一些想法很相近，本质是对 UI Controls 的再次抽象分类。</p>
<p>传统的 UI 控件分类，体现的是 what is looks like, 比如 Menu, Button, Tabs, Toolbar, Dialog, Grid, Tree 等等。</p>
<p>近期新近的一些 UI 类库比如 jQuery EasyUI, 开始逐步抽象出 Draggable, Droppable, Resizable 等 Base 功能点，这些形容词已经逐步开始从 what to do, not what it is 层面开始抽象。虽然 EasyUI 最后体现出来的依旧是 Menu, Dialog, Tree 等传统 UI 控件，但抽象层次和代码组织等已经逐步演化。</p>
<p>前不久在 InfoQ 发过一篇文章：<a href="http://www.infoq.com/cn/articles/frontend-ui-component">构建 UI 组件的新思路</a>, 介绍了 KISSY 类库中，通过 Switchable 抽象，实现 Tabs, Slide, Album 等 UI 控件的思路，抽象的出发点是 what it really is, not what it is.</p>
<p>结合 infinte 的想法，画了一个还比较混乱的图：<br />
<img src="http://lifesinger.org/blog/wp-content/uploads/2010/07/ui3.png" alt="UI 3.0"/></p>
<p>或许 UI 3.0 的时代真的来临了！</p>
<p>比如 Autocomplete（自动补全组件）或 Suggest（搜索提示组件），可以这样实现：</p>
<pre>
    Suggest = Widget.combine(DataProvider, Overlay, Selectable);
</pre>
<p>在现实生活中，我们需要实现一个复杂实体时，经常用到的办法是将简单的实体组合起来。比如法拉利，是一堆汽车零件的组合。不同的法拉利，是选用的零件或组合方法有差异。类、继承等 OOP 概念，真的不是必须的。去掉后，世界照样清晰。</p>
<p>抽象、思考，思考、再抽象，多想想 what it really is, and what to do, not what it is. 我相信，未来是 UI 3.0 的世界！</p>
<p>infinte 的文章让我很激动，上面的想法还很不成熟，UI 3.0 是我杜撰的（当然，希望以后会说是我首创的，哈哈）。大家随意看看，极其欢迎讨论，提出你的想法与建议。</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/07/what-it-really-is-not-what-it-is/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>
