<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>hax的技术部落格</title>
    <description></description>
    <link>http://hax.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
          <item>
        <title>两篇预测2008年川滇强震的论文</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/192781" style="color:red;">http://hax.javaeye.com/blog/192781</a>&nbsp;
          发表时间: 2008年05月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://ilib.cn/A-nldz200604003.html" target="_blank">http://ilib.cn/A-nldz200604003.html</a><br /><br />摘要如下：<br /><br />中国大陆及邻区、川滇成组强震活动特征初步研究<br />THE PRELIMINARY STUDY OF THE ACTIVITY CHARACTERISTIC OF THE GROUP STRONG EARTHQUAKES IN CHINA MAINLAND AND ITS NEIGHBOURING AREA, SICHUAN AND YUNNAN<br />&lt;&lt;内陆地震 >>2006年04期<br />黄圣睦 , 董瑞英 , 张永久 <br /><br />将中国大陆及其邻区1902年以来MS≥7地震的成组活动划分出7组,其首发大震分别为1902年阿图什8.2级,1911年阿拉木图8.2级,1920年海原8.5级,1931年富蕴8.0级,1946年缅甸7.8级,1966年邢台7.2级,1988年缅甸7.2级.川滇MS≥6.7地震成组活动划分出5组,其首发强震为1913年峨山7.0级,1933年茂县7.5级,1948年理塘7.3级,1966年东川6.5级、6.2级,1988年澜沧7.4级.其中,川滇MS≥7的首发大震滞后中国大陆首发大震几个月至4年不等.按成组大震的界定,<strong>目前中国大陆处于1998～2007年(估计)的大震少发时段.川滇未来1～2年的大震形势为川滇西部存在发生大震的可能性.</strong>中国大陆新一轮强震成组活动中的大地震将可能在2007～2009年前后发生,主体危险区可能为天山地震带中段及川滇东部.2007～2008年可能出现5～6级地震的增强过程.巧家-东川一带可能最先发生6级地震. <br /><br /><br />另一篇：<br />http://scholar.ilib.cn/A-zhx200603018.html<br /><br />基于可公度方法的川滇地区地震趋势研究<br />Study on Earthquake Tendency in Sichuan-Yunnan Region Based on Commensurability<br />&lt;&lt;灾害学 >>2006年03期<br />龙小霞 , 延军平 , 孙虎 , 王祖正 <br /><br />川滇地区为我国大陆最显著的强震活动区域,地震活动频繁.在对川滇地区强震灾害数据分析的基础上,应用三元、四元、五元可公度法分别预测了该地区下(几)次可能发生强震的趋势,以便能更好地配合防震减灾工作. <br /> <br /><br />该论文全文中写道：<br /><strong>3　结论与建议<br />从以上所进行的推算与预测结果看, 在2008 年<br />左右, 川滇地区有可能发生≥6.7 级强烈地震。</strong>
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/192781#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 14 May 2008 02:22:44 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/192781</link>
        <guid>http://hax.javaeye.com/blog/192781</guid>
      </item>
          <item>
        <title>地震了，我咋没感觉</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/192250" style="color:red;">http://hax.javaeye.com/blog/192250</a>&nbsp;
          发表时间: 2008年05月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          刚才有人打电话来说，四川发生7.8级地震，上海有明显震感，陆家嘴还有无数人逃出大楼。可是我一点感觉也没有……-_-，难道是因为我这个楼（五层的厂房）太结实了？
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/192250#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 12 May 2008 15:20:46 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/192250</link>
        <guid>http://hax.javaeye.com/blog/192250</guid>
      </item>
          <item>
        <title>为什么usability很重要</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/191954" style="color:red;">http://hax.javaeye.com/blog/191954</a>&nbsp;
          发表时间: 2008年05月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="425" height="355"><param name="movie" value="http://www.youtube.com/v/ptnJpF_WvUk&hl=en" /><param name="quality" value="high" /><param name="menu" value="false" /><param name="wmode" value="" /><embed src="http://www.youtube.com/v/ptnJpF_WvUk&hl=en" wmode="" quality="high" menu="false" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="425" height="355"></embed></object>
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/191954#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 11 May 2008 17:07:12 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/191954</link>
        <guid>http://hax.javaeye.com/blog/191954</guid>
      </item>
          <item>
        <title>测试一下你属于哪种人</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/191839" style="color:red;">http://hax.javaeye.com/blog/191839</a>&nbsp;
          发表时间: 2008年05月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          抄自<a href="http://www.terrainformatica.com/index.php/?p=32" target="_blank">http://www.terrainformatica.com/index.php/?p=32</a><br /><br /><br /><br />What will following JavaScript function return?<br /><br />function test()<br />  {<br />    try<br />    {<br />      return "I am optimist";<br />    }<br />    finally<br />    {<br />      return "I am pessimist";<br />    }<br />  }<br /><br />Try to answer as this is a good chance to measure your attitude<img src="/images/smiles/icon_smile.gif"/>
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/191839#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 11 May 2008 04:20:48 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/191839</link>
        <guid>http://hax.javaeye.com/blog/191839</guid>
      </item>
          <item>
        <title>午餐肉产业链</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/191838" style="color:red;">http://hax.javaeye.com/blog/191838</a>&nbsp;
          发表时间: 2008年05月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          看到一篇关于spam的blog，摘录如下：<br /><div class="quote_title">引用</div><div class="quote_div"><br />Message started as: “I hate ( name of president of the country on the other side of the Earth ) … ”<br />has link to site (selling something) in <strong>domain .us (USA)</strong>. It has email address (fake one) from one of public e-mail servers in <strong>domain .ru (Russia)</strong>. And it was sent from IP that belongs to <strong>China Telecom</strong> address range. (Machiavelli, where are you?)<br /><br />This is not a spam anymore. This is provocation.<br /><br />My message is not about particular countries (this stuff could come from anywhere) but about the whole system. We shall do something with this. </div>
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/191838#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 11 May 2008 04:09:55 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/191838</link>
        <guid>http://hax.javaeye.com/blog/191838</guid>
      </item>
          <item>
        <title>一个嵌入式HTML引擎</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/191761" style="color:red;">http://hax.javaeye.com/blog/191761</a>&nbsp;
          发表时间: 2008年05月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.terrainformatica.com/" target="_blank">http://www.terrainformatica.com/</a><br /><br />提供了免费的HTML嵌入引擎，包括对HTML、CSS和脚本的支持。<br /><br />它有许多有趣的地方。<br /><br />一个是号称为嵌入式场景做过特别优化，性能超过以嵌入式闻名的Opera。<br /><br />除了应用前景外，我特别感兴趣的是它对现有Web技术的一些扩展和思索。<br />因为是从引擎开发者的角度探索，而且他不像Webkit、Gecko那样，没有<br />负担，所以可以更大胆的引入许多尝试。<br /><br />比如HTML语法，可以这样：<br /><br /><pre name="code" class="HTML">&lt;body>
  &lt;div .header />
  &lt;div #sidebar >
    &lt;div .panel #recent-projects>&lt;caption>Recent projects&lt;/caption>
      &lt;ul>&lt;include src="content/list-of-projects.htm" />&lt;/ul>
      &lt;table>
        &lt;tr>&lt;td>Open:&lt;/td>&lt;td href="#">Project...&lt;/td>&lt;/tr>
         &lt;tr>&lt;td>Create:&lt;/td>&lt;td href="#">Project...&lt;/td>&lt;/tr>
      &lt;/table>
    &lt;/div>
    &lt;div .panel #getting-started>&lt;caption>Getting started&lt;/caption>
      &lt;ul>&lt;include src="content/getting-started.htm" />&lt;/ul>
    &lt;/div>
    &lt;div .panel #headlines>&lt;caption>Headlines&lt;/caption>
      &lt;dl>&lt;include src="content/headlines.htm" />&lt;/dl>
    &lt;/div>
  &lt;/div>
  &lt;div .panel #msdn-news>
    &lt;caption>MSDN: Recent news&lt;/caption>
    &lt;dl>&lt;include src="content/msdn-recent-news.htm" />&lt;/dl>
    &lt;p style="text-align:right;">&lt;a href="#">More news...&lt;/a>&lt;/p>
  &lt;/div>
&lt;/body>
</pre><br /><br />其中 &lt;div .panel #recent-projects> 这样的我们显然可以猜到是什么。<br /><br />又如它对JavaScript的扩展：<br /><pre name="code" class="JavaScript">tab = Element.create { tag: "option", text: label, value: filename };</pre><br /><br />其实就是去掉了函数调用的括号来简化有名参数的语法。<br /><br />再如：<br /><pre name="code" class="JavaScript">  // for element with id="foo"
  function self#foo.onClick() { ... }
  // for element with id="foo-bar"
  function self#foo-bar.onClick() { ... }
</pre><br />其中self其实就是window.self，整个就相当于：<br /><pre name="code" class="JavaScript">window.self.document.getElementById('foo-bar').onclick = function () { ... }</pre><br /><br />此外，它还在CSS框架下纳入许多特性。<br /><br />总之，它包含许多有趣而值得借鉴的想法有待考察。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/191761#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 10 May 2008 18:28:32 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/191761</link>
        <guid>http://hax.javaeye.com/blog/191761</guid>
      </item>
          <item>
        <title>西方人通常发现不了的一个IE的bug</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/191555" style="color:red;">http://hax.javaeye.com/blog/191555</a>&nbsp;
          发表时间: 2008年05月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这个问题我大概在一年多以前在某个用到VML的页面中（当时倒是记录了<a href="http://blog.csdn.net/hax/archive/2006/11/23/1406679.aspx" target="_blank">VML的一个严重问题</a>）首次发现了这个Bug。经过一番狗狗之后，也未发现有同样的报告。后来我又逐渐在几种其他非VML的情形下重现了这个奇异的Bug。经过一番探究，我大致推断出了这个bug的原因。不过我一直没有公开发布过这个有趣的问题，只是跟少数同事提到过它。这个bug有个有趣的特点，就是西方人通常不会碰到这个bug。<br /><br />最近，<a href="http://realazy.org/blog/" target="_blank">真懒</a>同学（realazy）在<a href="http://realazy.org/blog/2008/03/29/understand-0-settimeout/#comment-63839" target="_blank">《认识延迟时间为 0 的 setTimeout》一文</a>中举例说明setTimeout的用途。代码大意如下：<br /><pre name="code" class="javascript">
$('myButton').onmousedown = function () {
  var input = document.createElement('input');
  input.type = 'text';
  $('myDiv').appendChild(input);
  input.focus();
}
</pre><br />在IE中，新创建的input没有如预期的获得焦点。<br /><br />如果把input.focus()放在一个setTimeout中延时执行，则就可以获得焦点。<br /><br />这个例子本身其实并不能证明realazy想要说明的观点，因为他不小心碰到了一个IE的微妙bug。在<a href="http://realazy.org/blog/2008/03/29/understand-0-settimeout/#comment-51746" target="_blank">留言</a>中，<a href="http://www.lunaticsun.com/" target="_blank">Lunatic Sun</a>倒是敏锐的判断出这是IE的bug，只是这个bug的本质不是那么容易认识到，它其实并不是onmousedown本身的bug。<br /><br />实际上，这是IE的focus机制的bug。<br /><br />IE中的所有元素其实并不是被凭空绘制出来的，而是统统基于已有的Windows控件之上。除了典型的按钮、下拉菜单等，普通的div其实也是一个textbox控件。<br /><br />所以IE的HTML focus等实际是被转换为windows控件的focus，于是在IE中存在两种不同层次的focus机制。理想上，HTML的focus应该被同步转换为windows控件的focus，然而IE可怜的代码导致这种转换存在许多bug。我们经常遇到的焦点虚线框丢失的问题其实就是一个例子。<br /><br />实际上，在上面的例子中，表面上input没有得到焦点，但是其实调用focus()之后，HTML focus确实已经到了新生成的input中，这一点你可以通过document.activeElement来验证，你也可以按tab和shift-tab观察焦点的切换来证明这一点。然而，由于mousedown事件默认会获得控件焦点，所以windows控件focus就跑回了你的按钮上面了。这里出现了windows focus机制和html focus机制的脱节。显然IE在focus上的同步代码实在是太脆弱了。<br /><br />事实上，IE对焦点的控制似乎本来就不和逻辑。所有的<a href="http://www.satzansatz.de/cssd/onhavinglayout.html" target="_blank">hasLayout</a>元素都能获得焦点！结果一个页面上大部分区域在mousedown之后焦点就不知跑到哪个元素上了——这显然不是我们想要的行为——合乎HTML规范逻辑的行为应该是只有交互控件，如表单控件和A元素等，才能获得焦点。这导致一个典型的用户体验问题：在一个限制高度的可卷动区域中（例如一个长表单），拖动scrollbar，控件焦点就丢失——实际焦点跑到scrollbar所在的元素（例如form元素）上了。最严重的是，body元素一般总会有scrollbar！为了缓解这个问题，微软为body元素打了补丁，使得body上的scrollbar不会抢走焦点。然而IE这个patch打得实在是太烂了，在标准模式下，canvas从body变成了html元素，所以页面scrollbar就到了html元素上，结果bug又回来了！<br /><br />撇开抢焦点问题，我们回到前面的话题。<br /><br />既然html focus还是在input元素上，那么当时windows控件焦点到底跑哪里去了？实际上这个焦点跑到了mousedown所发生的对象上。比如如果是一个input按钮，焦点就会在该input按钮实际对应的windows的Button控件上。不过button元素的实现和一般的input不同，所以button元素上的mousedown之后，windows控件焦点实际上会跑到button元素外层的那个元素所对应的windows控件（通常是TextBox控件）中。<br /><br />如何证明这一点？我过去用过一个调试工具可以显示出每个html控件实际的windows控件，也能查看实际的windows系统焦点。不过现在想不起来那个工具的名称了。搞笑的是，此处还会出现一个非常orz的症状——也就是本文标题所称的“西方人通常发现不了的一个IE的bug”——可以证明这一点。<br /><br />focus问题 + 西方人通常发现不了。各位是否已经猜到了呢？大家不妨用<a href="http://realazy.org/lab/settimeout.html" target="_blank">realazy的那个页面</a>中的第一个按钮来直接实验一把。<br /><br />我会在下篇blog中继续聊这个话题。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/191555#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 09 May 2008 20:00:12 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/191555</link>
        <guid>http://hax.javaeye.com/blog/191555</guid>
      </item>
          <item>
        <title>JS之父再谈JS历史（一）</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/190436" style="color:red;">http://hax.javaeye.com/blog/190436</a>&nbsp;
          发表时间: 2008年05月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          译自<a href="http://weblogs.mozillazine.org/roadmap/archives/2008/04/popularity.html" target="_blank">Brendan Eich的Blog上Popularity一文</a>。【】内为我的注。<br /><br />Popularity<br />关于流行<br /><br />It seems (according to one guru, but coming from this source, it's a left-handed compliment) that JavaScript is finally popular.<br />貌似（根据一位<a href="http://javascript.crockford.com/popular.html" target="_blank">精神导师</a>的说法【<a href="http://sp42.javaeye.com/blog/178525" target="_blank">中译</a>】）JavaScript最终流行了（尽管从原文来看这种赞美乃是言不由衷）。<br /><br />To me, a nerd from a tender age, this is something between a curse and a joke. (See if you are in my camp: isn't the green chick hotter?)<br />对我这个从小就是nerd【nerd就是痴迷于电脑的呆头鹅，当然nerd也可以以此为荣】的人来说，这介于诅咒和玩笑之间。（看看你是不是在我这个阵营：难道不是那个绿色女孩更hot？<span style="color: gray">【本段删除：不是很理解BE的意思，green chick大概是指那种天生尤物但是喜欢践踏男人自尊的女人，难道BE的意思是nerd都是呆头鹅，很贱地喜欢green chick？】</span>【<span style="color: green">5月7日更新：</span>感谢greens.leef的留言以及我<a href="http://annaliminyan.blogcn.com" target="_blank">女朋友</a>的提点，在原文中有这样<a href="http://www.youtube.com/watch?v=4LiynW5ok5I&eurl=http://weblogs.mozillazine.org/roadmap/archives/2008/04/popularity.html" target="_blank">一段视频</a>，是<a href="http://en.wikipedia.org/wiki/Wicked_(musical)" target="_blank">百老汇音乐剧Wicked（邪恶女巫）</a>中的唱段“Popular”（BE还真搞），这个剧是从<a href="http://zh.wikipedia.org/wiki/%E7%B6%A0%E9%87%8E%E4%BB%99%E8%B9%A4_%28%E7%AB%A5%E8%A9%B1%29" target="_blank">《绿野仙踪》（奥兹国的魔法师）</a>故事衍生而成，视频中绿色皮肤的那个就是西方女巫<a href="http://en.wikipedia.org/wiki/Elphaba" target="_blank">Elphaba</a>，由Idina Menzel扮演，她以该角获得<a href="http://en.wikipedia.org/wiki/Tony_Award_for_Best_Performance_by_a_Leading_Actress_in_a_Musical#2000s" target="_blank">2004年Tony Awards音乐剧最佳女主角奖</a>】）<br /><br /><br /><div class="quote_title">引用</div><div class="quote_div">    Brendan Eich convinced his pointy-haired boss at Netscape that the Navigator browser should have its own scripting language, and that only a new language would do, a new language designed and implemented in big hurry, and that no existing language should be considered for that role.</div><br /><div class="quote_title">引用</div><div class="quote_div">BrendanEich就有这个本事，能够说服当时Netscape的秃头老板，要做Navigator自己的脚本语言，还要不是新的语言不去做，－就这样，匆匆忙忙地设计出一门新的语言并实现出来，还真的没有别的语言能代替这种需求。【sp42译】<br /></div><br /><br />I don't know why Doug is making up stories. He wasn't at Netscape. He has heard my recollections about JavaScript's birth directly, told in my keynotes at Ajax conferences. Revisionist shenanigans to advance a Microhoo C# agenda among Web developers?<br />我不知道Doug干嘛要编故事。他并没在Netscape呆过。在<a href="http://www.ajaxexperience.com/" target="_blank">Ajax大会</a>我做的主题报告上，他也直接听过我关于JavaScript诞生的回忆。修正主义的玩笑是为了在Web开发者中推进<a href="http://www.google.com/search?hl=en&hs=Khw&q=microhoo+site%3Avalleywag.com&btnG=Search" target="_blank">“微虎”</a>的C#么？<br /><br />Who knows, and it's hard to care, but in this week of the tenth anniversary of mozilla.org, a project I co-founded, I mean to tell some history.<br />谁知道呢，也无所谓。不过本周【本篇文章写于4月3日】是我参与创建的<a href="http://www.mozilla.org/" target="_blank">mozilla.org</a>的第十个年头，我想聊一点历史。<br /><br />As I've often said, and as others at Netscape can confirm, I was recruited to Netscape with the promise of "doing Scheme" in the browser. At least client engineering management including Tom Paquin, Michael Toy, and Rick Schell, along with some guy named Marc Andreessen, were convinced that Netscape should embed a programming language, in source form, in HTML. So it was hardly a case of me selling a "pointy-haired boss" -- more the reverse.<br />正如我经常说的，并且其他Netscape的人也可以证明，我是以在浏览器中“搞<a href="http://en.wikipedia.org/wiki/Scheme_(programming_language)" target="_blank">Scheme</a>”的名头被招募到Netscape的。至少客户端工程管理层，包括<a href="http://www.tuko.com/u/paquin/" target="_blank">Tom Paquin</a>, <a href="http://www.toyland.org/" target="_blank">Michael Toy</a>和<a href="http://www.onset.com/team/team_schell.html" target="_blank">Rick Schell</a>，以及叫做<a href="http://blog.pmarca.com/" target="_blank">Marc Andreessen</a>的那些家伙，相信Netscape应该在HTML中以源代码形式嵌入一种编程语言。所以并非是我说服“秃头老板”【其实sp42翻译有误，并非秃头老板而是尖头老板，见<a href="http://en.wikipedia.org/wiki/Image:Dilbert-20050910.png" target="_blank">呆伯特的图片</a>，最左边一个就是尖头老板，根据维基中文，他是“呆伯特的直屬上司，長得像毛澤東，缺乏一般知識常識及其職位所應具有的管理能力，愛說大話且富有向物理現實挑戰的精神(永無止境的顛覆與冒險)，倒楣跟負責的往往是他的下屬。”】——而是反过来。<br /><br /><br />Whether that language should be Scheme was an open question, but Scheme was the bait I went for in joining Netscape. Previously, at SGI, Nick Thompson had turned me on to SICP.<br />这个语言是否应该是Scheme见仁见智，不过Scheme正是我加入Netscape的诱因之一。之前在SGI，<a href="http://mjtemplate.org/" target="_blank">Nick Thompson</a>曾向我介绍了<a href="http://mitpress.mit.edu/sicp/" target="_blank">SICP</a>。<br /><br />What was needed was a convincing proof of concept, AKA a demo. That, I delivered, and in too-short order it was a <em>fait accompli</em>.<br />当时需要的是一个有说服力的概念验证，也就是一个demo。我完成了它，而它随即变成了<em>既成事实</em>。<br /><br />【待续】
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/190436#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 07 May 2008 01:53:42 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/190436</link>
        <guid>http://hax.javaeye.com/blog/190436</guid>
      </item>
          <item>
        <title>意译词三种</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/189356" style="color:red;">http://hax.javaeye.com/blog/189356</a>&nbsp;
          发表时间: 2008年05月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          读书中。该书对意译词分为三类：<br />1. 翻译<br />如用“桌子”译table。“桌子”是汉语既有之词。<br />2. 仿译<br />如“蜜月、黑板、代沟、互联网”等。<br />3. 重新命名<br />如“维他命（Vitamin）、激光（Laser）、天使（Angel）、扬弃（Aufheben）”等。<br /><br />偶结合术语译名的思考：<br />第一种毋庸多言。第二种即常被叫做“直译”的。第三种则可能会被叫做“意译”。但是第三种也包含“半音半意译”等，因而讨论时会混在一起。所以，从该书的分类法来讨论，更加清晰。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/189356#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 04 May 2008 14:53:29 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/189356</link>
        <guid>http://hax.javaeye.com/blog/189356</guid>
      </item>
          <item>
        <title>轻量级的语言解析的基础问题</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/183575" style="color:red;">http://hax.javaeye.com/blog/183575</a>&nbsp;
          发表时间: 2008年04月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本文延续<a href="http://hax.javaeye.com/blog/181358" target="_blank">上一篇blog</a>，对语法解析问题做一点点思考。注意，本文的角度仅仅是从轻量级解析方面考虑，也就是说不考虑像语言的编译器或解释器那样要完整精确地将源码解析为AST。轻量级解析的目标应用是诸如语法高亮、预处理、lint、语法糖衣或简单的语言扩展之类。<br /><br /><br />因此讨论顺序也比较特殊，从注释开始。在上述处理中一般会要排除注释。<br /><br />通常语言可能支持两种comments，单行comments和多行comments。<br /><br />单行comments是从一个特定符号组合开始，到换行符结束。常见的单行comments包括：<br />// comments<br /># comments<br />-- comments<br />' comments<br />rem comments<br />多行comments是从一个特定符号组合开始到一个特定符号组合结束。多行comments要考虑是否允许嵌套（通常是不允许嵌套的）。常见的多行comments包括：<br />/* comments */<br />&lt;!-- comments --><br />" comments "<br /><br />再次是字符串源文本（string literal）。最常见的就是引号包围的部分。需要注意的是几点：<br />1. 特殊字符的escape，如\"、\'还有\\。<br />2. 可能会支持某种字符表达方式，例如\unnnn。有时这种表达法可能不限于字符串源文本而是整个源代码。<br />3. 某些特殊形式的字符串源文本，例如允许内插变量的（如"x=${x}"），无escape的（如@"c:\test"），跨行的（如"""..."""）等。<br /><br />语言的语法格式通常会包含一些特殊符号，例如EOS（如“;”）、block（如“{}”）等，然而在根据这些符号进行解析时，必须排除comments和string literal中的这些符号。但是comments所用符号和string literal的定界符本身也可能包含于string literal和comments中。比如一个包含注释定界符的字符串"/*"。<br /><br />许多语言还支持正则表达式源文本（regex literal）。这使得情况更复杂。注意由于正则源文本常常用/regex/形式包围，需要与除法符号区分开来。这存在一个很严重的问题，因为判断是否适用于除法，还是适用于正则，可能要用到语义的信息。因此，为了保证轻量级，我们可能要做一些折衷。<br /><br />comments、string literal和regex literal等是语言中的特殊构造，它们可能包含大量字符，包括语言的保留字和用于定界的标点符号等。而且它们往往可以包含对方的定界符，如在comments中的string literal开始符号就不再产生string literal了，而string literal中的comments起始符号也不再产生comments了。<br /><br />排除了它们之后，剩下的就是语言本身用到的特殊符号。<br /><br />首先是EOS（语句结束符）。大体可以分为三类：<br /><br />一类是以特殊符号为结束符，例如C-style的“;”。<br />一类是以EOL（行结束符）为结束符，有时也允许同时采用EOS。比如Python。<br />一类是没有明确的EOS，最有名的就是JavaScript，其次如Groovy。<br /><br />其次是代码块。大体是三类：<br /><br />一类是以符号表示，如C-style的花括号结构。<br />另一类是以关键字表示，如begin end。<br />还有一类是以缩进表示，如Python。<br /><br />再次是语言的保留字。包括关键字、特定的literal（如true、false）等。<br />注意，有些关键字并不总是关键字，而是可以在上下文中充当一般的标识符。<br /><br />其他特殊构造包括各种literal，如数字源文本、数组、映射表、元组等。<br /><br />最后，有些场景存在多种语言嵌套的情况。例如HTML会嵌套CSS、脚本等。有些语言则支持内嵌XML literal（如E4X）或内嵌其他语言（如LINQ、SQLJ？）。这些情况可能会很复杂，轻量级的解析方法很可能无法应对。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/183575#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Apr 2008 02:12:30 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/183575</link>
        <guid>http://hax.javaeye.com/blog/183575</guid>
      </item>
          <item>
        <title>Mix-In的译法探讨</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/182339" style="color:red;">http://hax.javaeye.com/blog/182339</a>&nbsp;
          发表时间: 2008年04月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          有许多动态语言都支持Mixin的特性，比如Ruby、Python。而JavaScript虽然在语言层面没有Mixin支持，但是Prototype所模拟的类似Ruby的extend方法其实就是一种Mixin方式。<br /><br />目前的工业语言（Java、C#等）普遍采用了单根继承+接口的方式。但是类的继承复用被一定程度上牺牲了（也就是要求尽可能用组合而不是继承）。这源于class既要用于实例化也要用于代码复用，而这两者存在矛盾。Mixin类似一种多继承，但是它明确是一种小粒度的代码复用单元，而不直接用于实例化。因此它避免了多继承的常见问题。<br /><br />但Mixin并没有非常统一确定的译名。目前使用最多的是“混入”的译法。在最近的翻译讨论中，有人提出了一些新的译法，比如“混生”、“掺料”等。请参见：<a href="http://groups.google.com/group/python-cn/browse_thread/thread/d7e0a256a1bf6465" target="_blank">http://groups.google.com/group/python-cn/browse_thread/thread/d7e0a256a1bf6465</a>。下面是我在一个翻译论坛中的讨论贴，整理于此。<br /><br />对于mix-in这样的新词，我觉得大体有几种做法：<br /><br />1. 不译。<br /><br />因为新词的意涵尚未普遍接受甚至本身内涵外延未确定下来，现有译名可能也存在问题，所以直接用英文也是一个比较好的方式。不过除了高端书之外，如果一般书籍采用这种策略，需得对名词做好译注，避免普通读者难以理解其意。<br /><br />我个人建议在未有好译名之前，暂时以此种方式为宜。<br /><br />2. 从既有之译名中选取一个。<br /><br />目前看来纯直译型的“混入”（真是直白，mix是混，in是入……）接受程度最高。但是“混入”其实意思不是很明确。Mix-In，根据我的理解，其本义是指可以被混入其他类的单元，而不是指混入这种动作。至于说现在变成Mixin（去掉了hyphen）之后，意思是否有所转变，还望大家共同讨论。偶个人认为仍然去掉hyphen只是从一个组合词固化为一个专业术语，本身含义还是没有发生变化的。<br /><br />3. 在译著中换用其他等价词汇。<br /><br />比如Trait。当然Trait的译名本身也是个难题。<br /><br />4. 自创译名。<br /><br />下面谈谈“混入”之外的其他几个译名。<br /><br />我觉得“掺料”不太好，工业味道太浓，它对应的英文大概是admixture，指混合剂。而mix-in根据wikipedia，是源于冰淇淋的混合口味，是很美味浪漫的，用“掺料”真是大煞风景了。还不如叫做“配料”甚至“浇头”，呵呵。<br /><br />“混生”这个词在汉语语法上似乎比“混入”更名词化一些，不过我认为“混生”与“派生”共用“生”字也并没有什么特别好的地方，因为mixin class和derived class并不是同种性质的东西。特别的，mixin本身不是说混和生成的类，而是说可以用来混合的部件。所以“混生”一词较“掺料”反而有点脱离了mixin的原意，容易让人误解“混生类”和“派生类”一样，是指子类。实际上mixin却是指“用于混入的类”，有那么点儿类似抽象类（abstract class）或者partial-class。<br /><br />如果一定要译，我贡献一个译法供大家批判：<br /><br />mixin 混元<br />mixin class 混元类<br /><br />所谓混元，就是用于混合的元件。 <br /><br /><br />BTW，“混元”在汉语中倒是古已有之，如“混元一气”，还有金庸小说中的大奸角成昆外号就是“混元霹雳手”。这个“混元”大体是指世界初创时的混沌元气。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/182339#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 13 Apr 2008 16:55:16 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/182339</link>
        <guid>http://hax.javaeye.com/blog/182339</guid>
      </item>
          <item>
        <title>JS解析测试代码片段</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/181358" style="color:red;">http://hax.javaeye.com/blog/181358</a>&nbsp;
          发表时间: 2008年04月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          前一日与jindw聊天，谈到了正在研究的JS代码转换。譬如JSA所作的，其实就是一种代码转换。<br /><br />PIES为了实现namespace（package）的管理，对JavaScript源代码也进行了处理。为了保证效率，所以想方设法只做了最最简单的预处理，也就是对代码段加头加尾，这样只是简单的字符串串接，对于效率是没有影响的。<br /><br />但是最近在考虑是否有可能支持一些JS2（ES4）的特性，譬如支持let。这就必然需要将let转换为ES3所支持的某种结构（简单的说，在let语句开始的时候，把let的scope之外的同名变量先压栈，然后到了let的scope之外再恢复出来）。<br /><br />总之这里就涉及到一种代码的transform或preprocessing。所以我在寻找某种轻型的代码解析方式。为此我先要写一些测试用例。<br /><br />如果要进行JS代码的parse、transform、预处理、代码生成甚或compile等等，就需要考虑到JS的语法。以下是个很不完整的代码片段，parser、lint、preprocessor、transformer等等都需要能正确处理它，才具有实用价值。<br /><br /><pre name="code" class="JavaScript">
function f(test) {
	
	return (test/*
	/* //
	' "
	{ ;
	\*/ && // /* // " ' { ; \
	test &&
	" /* // \
	\" ' \
	{ ;" &&
	' /* // \
	" \' \
	{ ;' &&
	test);
	
}
</pre><br />这个代码包含了多行注释、单行注释、字符串、多行字符串（非ES3标准，但各种引擎都支持）、转义字符等等。<br /><br />这个代码没有包含的，包括正则和e4x。正则literal（如/^r(eg)ex["'\/].*?$/ig）是个很麻烦的事情，比如考虑除法！所以暂时没有放入测试用例中。e4x也是一个麻烦事情，因为涉及了内插XML，暂时不予考虑。<br /><br />BTW，代码syntax highlight其实也会用到类似的处置，显然JavaEye的syntax highlight还是存在小小的地方不能辨识的，呵呵。<br /><br />下面是一个正则表达式，可以匹配最常见的造成解析困难的嵌套结构，包括注释和字符串，但是没有包括前面所说的正则和e4x的xml结构。<br /><pre name="code" class="JavaScript">/[/]<li>([\S\s]*?)(?:[*][/]|$)|[/][/](.*)|"((?:\\"|[^"])*)"|'((?:\\'|[^'])*)'/g;</pre></li><br />注：如果你看到上面的代码里存在奇怪的东西，那是JavaEye的bbcode解析错误。<br /><br />通过这个正则，我们可以过滤一般的JS代码（当然正则和e4x除外）。比如可以把注释都删除，把字符串里的特殊字符替换掉等等。我测试了上面那段人造的代码。然后我拿dojo 0.4.3的314KB的源代码做了测试，完成整个过滤在我的T60笔记本上大概需要0.5秒。<br /><br />不过因为还没有处理正则，所以这个方法还不能用于实用。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/181358#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 10 Apr 2008 17:19:42 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/181358</link>
        <guid>http://hax.javaeye.com/blog/181358</guid>
      </item>
          <item>
        <title>Apache与SPNEGO备忘</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/169266" style="color:red;">http://hax.javaeye.com/blog/169266</a>&nbsp;
          发表时间: 2008年03月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          过去配置过一次，有很多问题，但是最后似乎搞成了。<br />最近搞的时候又问题无数。所以还是要做个备忘，以免以后重蹈覆辙。<br /><br />1. Apache的验证模块：mod_auth_kerb<br /><br />地址：<a href="http://modauthkerb.sourceforge.net/" target="_blank">http://modauthkerb.sourceforge.net/</a><br /><br />此模块的问题：<br /><br />a. 这个模块支持HTTP Negotiation验证（即SPNEGO），但是不支持NTLM只支持Kerberos。而IE似乎在某种情况下会返回NTLM，所以自动的Negotiation验证就会失败（此问题待考）。FF完全按照config所设的来，所以没有问题。<br /><br />b. 如果Negotiation失败，可以用HTTP Basic验证。但是Basic验证很不安全，必须和HTTPS结合使用。本模块只支持Basic，不支持其他备选的验证方式。Basic验证也可关闭。<br /><br />c. 如果失败，可以将验证委托给其他模块，但没有试验过，可能需要自己编程。<br /><br />d. 错误信息不友好，常让人不明所以。<br /><br />e. 它仅仅是一个验证模块，并不会记录cookie/session来保持验证信息，所以每次访问都会有一次401。<br /><br />Solaris另有一个模块也支持Negotiation，与前者稍有不同，没有用过，不述。<br /><br /><br />2. Linux使用Windows Domain作为Kerberos服务器<br /><br />a. linux上配置/etc/krb5.conf，通常直接设domain就可以了，会根据DNS自动寻找kdc服务器。<br /><br />b. 时间要同步。最好将domain controller作为ntp服务器。<br /><br />c. 测试命令：<br />kinit<br />kvno<br />kdestroy<br />klist<br /><br /><br />3. 从Windows Domain中导出Kerberos所需的keytab<br /><br />a. 在domain中建立一个用户，表示一项服务。<br /><br />b. 到domain controller上用命令行，使用ktpass.exe导出keytab。<br /><br />注意：Windows 2003 sp1的ktpass有bug（shit M$），导致导出的keytab密码不对！需改用Windows 2003 sp2的ktpass。<br /><br />ktpass可将用户映射为一个serviceprincipalname，格式为service/fqdn@DOMAIN。对于mod_auth_kerb来说，默认前缀为HTTP。所以假设domain为EXAMPLE.COM（Domain都是全大写的），site的fqdn为mysite.example.com（域名为小写的，并且必须是完全域名），则princ为：HTTP/mysite.example.com@EXAMPLE.COM。ktpass会自动加Domain。需为该映射设定一个密码，这个密码与用户原密码不同，kvno会做对应增加。type需要设定为KERBEROS_SRV_HST。<br /><br />c. 在linux上测试该keytab<br /><br />kinit -k -t keytabfile HTTP/mysite.example.com@EXAMPLE.COM<br /><br /><br />4. 配置apache的conf文件<br />略<br /><br />5. 验证过程需要对上域名，所以<br /><br />a. 要使用fqdn，如果是CNAME要使用最后的name。<br /><br />b. 需要PTR记录，从IP指回fqdn。<br /><br />c. 如无PTR，或许可以在linux上写上hosts文件，内容为IP对应fqdn。<br /><br /><br />结论：<br /><br />确实挺烦。而且灵活性不够，比如我怎样只为内网（hostname不含完整域名后缀）启用kerb，而外网用其他验证模式？设成几个vhost有点太过。Basic不安全。每次都401浪费。<br /><br />当前目标：找一个纯Java的解决方案，然后最好能很灵活的配置。<br /><br />可以根据条件（如hostname、port、来源IP、时段等）设定不同的验证方案。<br />可以顺序发出几个不同的auth候选：<br /><br />Negotiation<br />Kerberos<br />NTLM<br />Digest<br />Basic<br /><br />可以选择其中几种，也可以去掉最后的Digest/Basic改转为form-based验证。<br /><br /><br />这个理想目前还无法实现（不过也许有商业软件已经实现了）。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/169266#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 08 Mar 2008 00:21:52 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/169266</link>
        <guid>http://hax.javaeye.com/blog/169266</guid>
      </item>
          <item>
        <title>Prototype 1.6的超级符咒</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/167131" style="color:red;">http://hax.javaeye.com/blog/167131</a>&nbsp;
          发表时间: 2008年03月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Ajax in Practice 中写道：<br /><br />With the sleight-of-hand tricks that Prototype provides us for declaring JavaScript object classes...<br /><br />译成：Prototype赐予了我们魔术手法般的技巧来声明JavaScript对象类。<br /><br />不过这个书里写的是Prototype 1.5.x的版本。其给出的示例中，父类必须在initialize方法中再调用一个_initSuperclass方法，因为子类的initialize会覆盖父类的，但又需要调用父类的初始化方法，所以就必须写一个_initSuperclass来给子类调用。这其实说明用Prototype的Object.extend()来模拟类继承根本是很拙劣的。<br /><br />我给出的注解是这样的：<br /><div class="quote_title">引用</div><div class="quote_div">从作者的这两段解说我们可以看出，使用Prototype来构造类继承其实并不方便，这是因为extend()方法原本就不是为完整的类继承机制而设计的，它模仿的是Ruby语言中的extend的语义。困难的根源在于缺乏对super调用的支持，因此不得不为每一层级的类都做一个独立的初始化器，以便子类可以调用父类的初始化器（相当于super调用）。Prototype 1.6.0将引入全新的Class设计，在每个子类方法中，如果第一个参数名为$super，就可以在该方法中通过$super来调用对应的父类方法。这样就不再需要写出类似_initializeDisc()这样难看的代码了。</div><br />在写完这段注解后，我再看到前面的“With the sleight-of-hand tricks that Prototype provides us”，不由起了戏虐之心，就加了一个注：<br /><br />Prototype赐予了我们魔术手法般的技巧【注】来声明JavaScript对象类。<br /><br />注：如果说这里所展现的是魔术手法（sleight-of-hand），那Prototype 1.6.0提供的就是超级符咒（super invocation）。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/167131#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 04 Mar 2008 04:18:08 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/167131</link>
        <guid>http://hax.javaeye.com/blog/167131</guid>
      </item>
          <item>
        <title>12球太少，我3次能称14球，不相信？我还4次称41球，5次122球……</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/166814" style="color:red;">http://hax.javaeye.com/blog/166814</a>&nbsp;
          发表时间: 2008年03月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这个题目很久以前在大学的BBS上发表过解法，现在找不到了，重新写一遍也不费劲。<br /><br />下面是怎么称14个球（设为A1-A14）。<br />前提是有多一个标准球A0。<br /><br />A0-A4 vs A5-A9<br />如果相等，则坏球在A10-A14这5个球中。<br /><br />5球（重新记做A1-A5外加一个A0为标准球）的称法如下：<br />A0,A1 vs A2,A3<br />如果相等，则坏球是A4或A5，取其中一个与A0再称一次即可判断（这个不用说了，人人都知道怎么称）。<br />如果不等，假设A0,A1 > A2,A3（&lt;的话，下面的判断都反一反即可），则再称一次：<br />A2 vs A3<br />如果相等，则坏球是A1，否则A1就是好球，坏球在A2、A3中，根据上一次称量结果可以判断出，坏球比标准球轻，所以A2 vs A3的结果，轻的那个就是坏球。<br /><br />如果第一次称量不等，则坏球在A1-A9这9个球中，并且你知道一个不等关系，我们假设是A0-A4 > A5-A9（&lt;的话，下面的判断都反一反即可）。<br /><br />然后测A1,A2,A5 vs A3,A4,A6<br />如果相等，则坏球在A7,A8,A9中，并且可以推导出其中轻的那个是坏球，再称一次肯定能找出坏的那个。<br />如果A1,A2,A5 > A3,A4,A6<br />则坏球在A1,A2,A6中，并且可以推导出A1,A2 > A0,A6<br />反之坏球在A5,A3,A4中，并且可以推导出A5,A0 &lt; A3,A4<br />不难看出这两种情况实际是等价的，只需比较两个同处一侧的球就可以判断哪个是坏球了。<br /><br /><br />如果没有标准球A0的话，那第一次称量就不能5对5了，只能4对4，所以最多只能称13个球。第一次相等的情况跟前面完全一样，如果不等，就是那8个球有问题，比前面的9个还少一个，所以你肯定可以称出来。那么为什么常见的题目都是12球呢？估计最初流传时很少有人真正从理论（信息论）上理解这个题，所以答案都是凑出来的，自然很难做到最优化。<br /><br />但是如果掌握了理论，这个称球问题就可以推广，比如4次最多可以称量27+14=41个。前提也是你多一个标准球，这样第一次称量就是14 vs 13+1，如果相等，坏球就在剩下的14个里，就转化为了前面描述的14球称量问题。如果不等，则坏球在27个里，通过合理调配，你肯定可以把它们区别成3组分别9个，通过一次称量判断出坏球到底是在哪9个球中。因为一次称量有3种状态，可以把一堆球分成3组。以下每次都是3组1分，所以27=3的3次方就是表示3次称量就可以区分出来了。<br /><br />不难看出，如果5次的话，可以最多称量27*3+41=122个，以下可以逐级类推，有兴趣的同志可以求出它的公式。<br /><br />最后是一个思考题，既然可以3个一组分，为什么3次称量只能称14个而不是27个呢？
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/166814#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 03 Mar 2008 06:05:24 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/166814</link>
        <guid>http://hax.javaeye.com/blog/166814</guid>
      </item>
          <item>
        <title>IE memory leak 备忘</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/166794" style="color:red;">http://hax.javaeye.com/blog/166794</a>&nbsp;
          发表时间: 2008年03月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本篇只记录一下工具，有空再做研究。<br /><br />Drip: <a href="http://outofhanwell.com/ieleak/index.php?title=Main_Page" target="_blank">http://outofhanwell.com/ieleak/index.php?title=Main_Page</a><br /><br />微软自己的：<a href="http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector.aspx" target="_blank">http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector.aspx</a><br /><br /><br />待研究课题：<br /><br />结合使用JavaScript和VBScript所产生的memory leak的风险是否可以化解，如何化解？VBScript如果只调用JavaScript函数是否不会产生循环引用，并不可能出现memory leak？<br />IE7下的表现如何？<br /><br />HTC的memory leak如何？<br />$之类的DOM包装函数如果使用VBScript会怎么样？<br /><br />参考：<br /><br />看过的那几篇就不列了。<br /><br />图不错：<a href="http://www.codeproject.com/KB/scripting/leakpatterns.aspx" target="_blank">http://www.codeproject.com/KB/scripting/leakpatterns.aspx</a><br />关于VBScript的Terminator的解说：<a href="http://blogs.msdn.com/ericlippert/archive/2004/12/22/330276.aspx" target="_blank">http://blogs.msdn.com/ericlippert/archive/2004/12/22/330276.aspx</a><br />Script的垃圾回收（包括结合使用VBScript和JScript的只字片语）：<br /><a href="http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx" target="_blank">http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx</a>
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/166794#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 03 Mar 2008 01:07:36 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/166794</link>
        <guid>http://hax.javaeye.com/blog/166794</guid>
      </item>
          <item>
        <title>代码尾大不掉不堪卒读</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/165153" style="color:red;">http://hax.javaeye.com/blog/165153</a>&nbsp;
          发表时间: 2008年02月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天翻译时用了两个成语：尾大不掉、不堪卒读，来形容这样一种带有太多可选参数的函数调用：<br />new Button('myButton',null,doSomething,null,null,null,'pressedButton');<br /><br />其原文是rather unwieldy and less-than-readable invocation。<br /><br />成语怕用错了，故查了一查，最后确定可以这样用。<br /><br />尾大不掉，台湾教育部重編國語辭典修訂本：<br />尾巴過大就不易擺動。比喻下屬的勢力強大，在上者難以駕馭。語出左傳．昭公十一年：所謂末大必折，尾大不掉，君所知也。後亦比喻事物因本末關係倒置，形成難以控制的局面。明˙郎瑛˙七修類稿˙卷八˙國事類．陳友諒始末略：今乘尾大不掉之舟，損兵弊甲，遲遲與吾相持。亦作末大不掉、尾大難掉。<br /><br />虽然现在尾大不掉多用来比喻机构庞大，指挥不灵（大概是中国特色），不过就其本义和比喻义来说，形容代码笨重也是完全可以的。<br /><br />不堪卒读，我原写做不忍卒读。不过不忍卒读其实多是形容文章太过悲惨不忍心读下去。所以改为了不堪卒读。说实话，不堪卒读和不忍卒读，意思其实应该是一样的，说前者为贬义后者为褒义，恐怕没有根据，最多统计当代人使用频率或许可观察到这样的趋势（不过只是或许，未见有人做过实际可信的统计）。不过如果单考虑使用习惯，那不忍卒读作为贬义的用法就真的太普遍了，简单的说人家都是误用，也并不能解决问题。因为本来褒词贬用，也是常见的修饰手法——因为太差了所以不忍心读下去……久之，贬义用法也成为了这个词的常态。成语的这种内在涵义的演变，也不是个案。不过最终，为避免编辑读者认为我是文盲乱用成语，所以还是改了个争议或许小一点的“不堪卒读”。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/165153#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 26 Feb 2008 14:58:44 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/165153</link>
        <guid>http://hax.javaeye.com/blog/165153</guid>
      </item>
          <item>
        <title>批量修改style采取哪种方式好（续篇）</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/164614" style="color:red;">http://hax.javaeye.com/blog/164614</a>&nbsp;
          发表时间: 2008年02月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          前篇见<a href="http://www.javaeye.com/topic/164500" target="_blank">批量修改style采取哪种方式好</a>，主要是回答fins的提问。<br /><br />下面我来说说我们实际期望怎样的编程方式。<br /><br />假设一个这样的需求：<br /><br />页面上有一些文本是highlight的。例如，javaeye的文章如果是点击<a href="http://www.google.cn/search?q=%E6%89%B9%E9%87%8F+%E4%BF%AE%E6%94%B9+style+fins+%E5%B1%80%E5%9F%9F%E5%8C%96+site%3Ajavaeye.com" target="_blank">google搜索结果</a>过来的，javaeye的后台会自动判断出关键字，并为这些关键字包裹上标记（&lt;span class="hilite1">关键字&lt;/span>）。<br /><br />我们现在希望有这样一个功能，就是允许开启/关闭highlight。<br /><br />如果关闭的话，那么大家通常可以想到的做法，就是检索所有的.hilite1的元素，然后去掉这个class。<br /><br />$('span.hilite1').forEach(function(e){e.className=''});<br /><br />但是这样做好之后，我们就无法再次开启highlight了！所以，我们要换种做法。一种方式是遍历所有的.hilite1然后替换为.hilite0。这样下次就可以找回来。不过正如上一篇文章中所说的，我们其实有更加经济的做法。<br /><br />我们在body上加入一个class： &lt;body class="hiliteEnabled"...> ，然后把样式改为： body.hiliteEnabled span.hilite1 {...} ，这样，当要关闭highlight的时候，差不多就只需要 document.body.className = '' ，就可以了。<br /><br />Ok，我们完成这个功能了。<br /><br />这个时候，有用户希望我们提供另一个很cool的功能，即在页面下方加入一个slider，然后用户可以拖动slider改变highlight部分文字的字体大小。<br /><br />这就类似于我上一篇中提到的批量修改的问题了。我们有两种做法：<br /><br />A.<br /><pre name="code" class="JavaScript">$('#fontSizeSlider').onchange = function() {
  var size = this.value;
  $('span.hilite1').forEach(function(e){
    e.style.fontSize = size;
  });
}
</pre><br />B.<br /><pre name="code" class="JavaScript">$('#fontSizeSlider').onchange = function() {
  var size = this.value;
  getStyle('span.hilite1').fontSize = size;
}
function getStyle(selector){
  //示意代码
  return document.styleSheets[0].cssRules[0].style;
}
</pre><br /><br />单纯看的话，托各种支持selector query的library的福，A做法是很简单的。B做法也不复杂。<br /><br />但是还记得我们第一个开启关闭的功能么？如果highlight被关闭了，显然，从用户的角度上说，应该也禁用修改font size的效果。乍一看这个很简单，改成select出 body.hiliteEnabled span.hilite1 然后遍历就好了。<br /><br />对于B做法来说，确实如此，你只需确保getStyle()返回的是针对 body.hiliteEnabled span.hilite1 的样式对象即可。<br /><br />但是注意这点对于A做法是不够的！因为你给所有的body.hiliteEnabled span.hilite1都加上了inline style，这个是不会自动消失的。所以你需要在 document.body.className = '' 之后加上清理语句 resetFontSize(false) 而在再次开启的语句 document.body.className = 'hiliteEnabled' 之后也需要加上 resetFontSize(true) 。该函数的代码如下：<br /><br /><pre name="code" class="JavaScript">function resetFontSize(flag) {
  var v = flag ? $('#fontSizeSlider').value : null;
  $('span.hilite1').forEach(function(e){
    e.style.fontSize = v;
  });
}
</pre><br /><br />这个味道就不太好。这倒不是因为两个功能被交织了起来。我们原来修改body.className其实隐含了关闭/开启highlight的语义，所以fontSize生效与否受到它的影响是正常的。你可以把“document.body.className = ''; resetFontSize(false)”纳入一个disableHilite()函数中。<br /><br />这里的问题实际是，每次你加入一个与highlight有关的新功能（例如我们下次可能允许大家定制hilite的颜色），你就需要修改disableHilite()/enableHilite()，加上新功能的清理和初始化代码的调用。这显然味道很不好。<br /><br />各位可能会想到观察者模式了！<br /><br />是的，你可以把hilite启用和禁用做成一个事件，然后其他功能都来订阅这个事件，并调用各自的初始化和清理代码。<br /><br />不错不是嘛。问题都迎刃而解了！<br /><br />不过还有一个问题。在这里，我们开启/禁用，只是一个二选一的问题。但是我们也可能遇到（制造出）更复杂的需求。比如假设是论坛帖子，除了整个页面的开启/禁用之外，每个回复都可以单独开启禁用hilite（即每个article元素上可以有.hiliteEnabled或.hiliteDisabled，如果没有任何一个class，则看body上是否有.hiliteEnabled），局域的设置override上层设置。这时，你就惨了，因为你的初始化/清理代码是针对整个页面写的，你必须改造成针对一个区域进行初始化和清理。你可能需要把用于遍历的selector作为事件的一个信息来传递。你的事件触发也需要重新写过，可能要让disableHilite()/enableHilite()能够接受一个参数指定操作范围，显然这个参数最好也用css selector。<br /><br />Ok，这是我生造的需求，所以你会觉得不合理，不过对于程序员来说，需求一般总是不合理的。呵呵。我们这里只是举例。<br /><br />其实我们从上面可以看到一个线索，那就是hilite启用与否，实际上可以取决于某个selector的模式匹配，因为我们通常把带有语义的开关存放在元素的class属性中。对于最初的简单需求来说：<br />匹配body.hiliteEnabled span.hilite1，就启用hilite以及hilite相关的功能，<br />不匹配body.hiliteEnabled span.hilite1，就禁用hilite以及hilite相关的功能。<br />每个hilite功能（如动态改变fontSize）去监听我们自制的hilite事件来进行初始化和清理，其实也可以等价于监听这一匹配的变化（如果我们能够监听的话）。<br /><br />对于我们下面人为制造的需求，其实可以转化为：<br />（注：article元素表示整个页面中每个单独的帖子）<br />匹配body article.hiliteEnabled span.hilite1，启用hilite，<br />匹配body.hiliteEnabled article span.hilite1，也启用hilite，<br />除非匹配body article.hiliteDisabled span.hilite1，则禁用hilite。<br /><br />如果写成一个单一的selector，就是：<br />article.hiliteEnabled span.hilite1, body.hiliteEnabled article:not(.hiliteDisabled) span.hilite1<br /><br />一连串复杂的逻辑，其实就可以简化为对于这一模式匹配的监听。<br /><br />这样我们期望中的代码就呼之欲出了：<br /><br />首先，启用和禁用hilite，就是简单的直接对元素（body或article）上设置className。<br /><br />然后我们这样写：<br /><br /><pre name="code" class="JavaScript">var hiliteSelector = new Selector('article.hiliteEnabled span.hilite1, body.hiliteEnabled article:not(.hiliteDisabled) span.hilite1');

function initHiliteFontSizeFeature() {
  hiliteSelector.addEventListener('match', function(evt){
    var hiliteSpan = evt.target;
    hiliteSpan._syncFontSize = function(evt) {
      hiliteSpan.style.fontSize = evt.target.value;
    };
    hiliteSpan.style.fontSize = $('#fontSizeSlider').value;
    $('#fontSizeSlider').addEventListener('change', hiliteSpan._syncFontSize, false);
  }, false);
  hiliteSelector.addEventListener('unmatch', function(evt){
    var hiliteSpan = evt.target;
    $('#fontSizeSlider').removeEventListener('change', hiliteSpan._syncFontSize, false);
    hiliteSpan._syncFontSize = null;
    hiliteSpan.style.fontSize = null;
  }, false);
}
</pre><br /><br />也就是，如果有一个Selector API提供给我们监听match/unmatch事件的话，要做的事情就非常简单了！<br /><br />理想中，Selector会产生match/unmatch事件，并自动dispatch到所有匹配的节点上。<br /><br />不过，我们现在并没有这样的API……querySelector及各种library提供的，都是一次性取出符合条件的节点，而没有监听的功能。<br /><br />实际上，在现有浏览器内使用JavaScript来实现这一API，是相当困难的。但是，我们知道，浏览器内部肯定有等价的功能，因为stylesheet的应用就是遵循这样的机制的。而且我们知道，IE的htc和Mozilla的XBL，正是利用这样一种机制的！未来的XBL2规范，也是如此！<br /><br />在下一篇blog中，我会拿htc、xbl1和xbl2，来实现我们上面提到的例子。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/164614#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 24 Feb 2008 19:20:21 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/164614</link>
        <guid>http://hax.javaeye.com/blog/164614</guid>
      </item>
          <item>
        <title>XBL2的实现</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/164536" style="color:red;">http://hax.javaeye.com/blog/164536</a>&nbsp;
          发表时间: 2008年02月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天发现几种XBL2的实现。浏览器实现XBL2还要等上一段时间，但是JS实现已经有了。<br />备忘如下：<a href="http://meekostuff.net/xbl2/" target="_blank">http://meekostuff.net/xbl2/</a>。上面包括另两种实现的链接。其中包括一个Google的实现，但是目前似乎源代码还没有放出来。<br /><br />有兴趣的同志可看看。XBL2会是一个很重要的东西。它将是未来正牌的组件实现方式。dojo、ext之类的将来应该会改到XBL2上。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/164536#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 24 Feb 2008 02:35:32 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/164536</link>
        <guid>http://hax.javaeye.com/blog/164536</guid>
      </item>
          <item>
        <title>批量修改style采取哪种方式好（答fins）</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/164500" style="color:red;">http://hax.javaeye.com/blog/164500</a>&nbsp;
          发表时间: 2008年02月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          fins同志向我提了个问题。因这个问题其实可以展开讨论，所以提出来大家共同探讨。<br /><br /><div class="quote_title">fins 写道</div><div class="quote_div"><br />在同类元素 例如 td 很多的情况下, "一次性改变元素的class对应的styleSheet"<br />和 "在循环里改变每一个元素style" 哪个更好<br /><br />ext的代码不知道你看过没<br />在ext 1 里 改变表格列宽的方式 就是用的 改变那一列的 td对应的class里的 width<br />而ext 2里变成了 用循环 依次改变每一个 td的style.width<br />两种方法哪个好呢? 我一直喜欢第一种<br />不过实在不明白为什么 ext 2里换了方式 <br /></div><br /><br />对于这一问题，我的意见是，就这个个例来说，两种方式都不好。因为table中一个column的width不应该在每个td上都做设置，而应该设置在table的col或colgroup元素上。注意，col元素上有效的css prop是很少的，这关系到另一个问题，这里不做展开，不过，width恰好属于那少数几个有效的css prop之一。<br /><br />当然，我对ext不熟，不知道在ext上是否能做这件事情。比方说如果ext产生的datagrid并不用col/colgroup，那你就干不了这个事情。但是有个变通方式。对于table-layout:fixed的表格来说（注意：对于大表格来说，应尽可能使用fixed），其td宽度只取决于第一行上的td的宽度。所以，可以把width设在第一行对应的td上。<br /><br /><br />本身，这个问题大体就是这样了。但是我想fins提出的这个问题，其实有更广泛的意义。那就是对于批量动态修改style，到底采取哪种方式好。<br /><br />批量修改style的具体形式千变万化，但是万变不离其宗，归根到底就是两种：<br /><br />A. 动态修改多个元素。<br />B. 动态修改stylesheet上的单个cssdeclaration。<br /><br />差别就是，前者选择待修改元素的集合（符合条件的snapshot）的过程是由脚本完成的（比如用一个getElementsByTagName选出一批元素，现在有了jQuery之类的，就更方便了，直接拿css selector来选择元素集合），并需要遍历所有元素一一进行修改；而后者选择待修改对象集合（这个集合是live的）的过程是由css selector自动完成的，然后style的变更也是自动分发到所有对象的。<br /><br />这两种方式本身，在具体实践时还有一些可以注意的地方。<br /><br />比如对于A方式来说，直接修改inline style实际上是把style混入了script中，味道通常不好，可考虑在stylesheet中创建若干个class来表示几组不同的style，然后script中只要修改className就好。这适合那些样式切换的需求，因为样式切换往往隐含语义，所以确实也应该用class来显式的标记这些语义。但是对于修改width这样的例子，就并不适合了。修改width，是一个纯粹UI上的操作，它并不带有语义价值（我指对应用的功能来说UI并不significant——当然某些应用除外，例如UI编辑器）。<br /><br />又如对于B方式来说，我们应该记得，selector很好很强大，因此不要老是给许多元素码上无数的class，完全可以用其他的selector方式，例如父子关系的，不必每个li都li class=mylist，完全可以ul class=mylist，然后样式表写ul.mylist>li{...}。<br /><br />如果这些地方都注意了，你会发现，真正需要批量修改的地方其实很少。大多数场合，只需要修改某个父级元素的className就可以了。<br /><br />我们下面谈论的是除了这些情况之外，真正需要批量修改style的地方。<br /><br />一种比较理论化的方案，是判断真正的需求，是要批量修改符合特定模式（实际是根据语义来匹配）的某些元素的样式（采用方式B），还是批量修改只是临时碰巧符合某个结构的（实际上没有持久有效的语义，甚至可能是随机的，比如由用户临时指定的）一批元素的属性（采用方式A）。但是许多时候，这个界限并不清楚，或者难以明确。就好象，在写样式表的时候，我是写<br />div#div1 {font-size:small}<br />div#div2 {font-size:small}<br />div#div3 {font-size:small}<br />还是抽象出一个div.class1，然后<br />div.class1 {font-size:small}<br /><br />这个事情脱离环境，是无法判断的！因为有时候你知道这里要达到这个效果，但是你并没有花精力去判断，font-size为small这个事情是纯粹偶然，还是这三个div真的具有某种一体的联系？况且，很多时候，追究这一点是不经济的（或者根本不可能，比如身为程序员的你无法找到真正懂需求的人，或者做UI设计的人根本没有这个概念，无法回答你的问题）。<br /><br />撇开对“需求的真正含义”的判断，我们假设，就个案来说已经存在确定的匹配模式（不管它有语义还是碰巧），也就是说不考虑你进行额外抽象的负担（比如原来页面上并没有某个class，而你决定额外加入一个class，并给一些元素加上class——这不仅是一种额外负担，在匹配模式其实是碰巧的情况下，长久来看其实可能是起了反作用），然后来关注纯技术层面的问题，那么：<br /><br />通常来说，B方式看上去更好一些。fins同志也是这样认为的。因为它只修改了一处，而且这个修改是单点可控的，不可能受到外部因素的破坏。而方式A则没有那么安全，因为样式与元素的匹配，只是一次性的，不存在始终有效的绑定。如果在完成批量改变style的操作之后，我们可能某个时候要再做一次操作批量去除所附加的style。其潜台词是在这个期间，这些元素仍旧符合原先所设的条件。<br /><br />如果元素由于某种外部因素的影响，不再符合原始的条件（例如一个元素被移动到了DOM树的其他地方），或者有新的符合条件的元素出现（例如插入了一个新元素），既有的约定就被破坏了，结果自然是可能出现bug，而且几乎无法跟踪。即使你可以监听某些变化，成本也非常之高。使用css selector的jQuery之类的，尤其如此，因为css selector的模式匹配是如此强大，以至于完全无法track一个元素是否发生了一个变化就不再匹配既定模式了。<br /><br />所以实际上，采用A方式，意味着DOM结构（包括所有影响你选择元素集合的因素）至少在一定范围内最好是静态的。幸好，这个需求在许多应用中还是符合的，在受控的框架中通常也是可以保证的。还有一个例子是组件库，组件内部的DOM结构一般是确定不变的，然后可变的部分已经被封装为它的外部接口了。对于组件来说，使用A方式还有一个副作用是，它能隔绝外部css对它内部元素的样式的影响，因为inline style优先级最高。当然组件可以正常工作的前提是，你的代码（或者你用的第三方代码）不会破坏它的封装，比如不破坏它内部的DOM结构。这一点其实存在一点隐患，比如假设你搞来一个自动圆角的库，然后加诸于某个组件之上，因为这个圆角库会自动插入一堆b啦i啦的元素，结果你的脆弱的组件就完蛋了。<br /><br />而B方式，因为它依赖的是声明性的selector，模式匹配是自动的，所以没有A方式的问题。DOM结构你随便变吧。但是B方式并不是没有自己的问题。首先，stylesheet是全局的，对于一个rule修改所产生的影响也是全局的。在现有的CSS中缺乏将一部分style局域化的能力（CSS 3有草案<a href="http://www.w3.org/TR/css-style-attr" target="_blank">http://www.w3.org/TR/css-style-attr</a>，html5中有对style元素的局域化定义，但是得到浏览器普遍支持还需时日）。而组件需要局域化style。现在我们需要用id或者class来限定stylesheet的scope。就ext的例子来说，它需要td上有一个class，而且每个table上的class都不能一样。维护局域化标识，同时在全局stylesheet中维护局域化的style，这样的操作，其实是较为复杂的一件事情，目前似乎还没有一个库提供这方面的支持。<br /><br />其次，A方式的stylesheet是静态的，而B方式的stylesheet是动态的。既然stylesheet是一种声明性的东西，那么通常stylesheet本身就倾向于保持静态。这允许一些针对stylesheet的前处理和后处理。比如dean edwards的IE7，它会重新解析stylesheets。而我之前也写过<a href="http://hax.javaeye.com/blog/112287" target="_blank">预编译stylesheet来产生兼容ie的css的思路</a>。然而，如果stylesheet是动态可变的，对这些方案就存在很大的挑战。因为监听stylesheet的变化如果不是不可能，那至少是非常非常困难的。而且无论是跟踪你修改的rules对应哪些实际的rules，还是整个重新编译样式表，成本可能都很巨大。要解决这个问题，需要投入很大的努力。（dean edwards的IE7还有更严重的问题，因为它实际上内部是使用A方式的，所以是对AJAX不友好的，不过这与这里的讨论关系不大。）<br /><br />以上，就是我对fins所提出的问题所做的一些考虑。结论其实是，首先看看是否你真的需要批量修改style。也许有90%的情况，你应该改为修改单一元素上的一个className。又有90%的情况，你可能只需修改单一元素上的inline style。虽然jquery、mootools、prototype等框架先后提供了css selector的功能，未来浏览器甚至会提供原生的querySelector功能，但是没有必要滥用这个能力。<br /><br />剩下1%的情形，那就要根据你的情况进行权衡。理想上，方式B更好一些，但是也存在一些现实问题。更多时候，我们见到的是大量方式A的写法，因为带有selector query功能的工具使得这样做更容易，而且在绝大多数时候，方式A也是可行的。<br /><br />其实，我们期望的理想的编程方式也许是这样：<a href="http://hax.javaeye.com/blog/164614" target="_blank">http://hax.javaeye.com/blog/164614</a>。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/164500#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 23 Feb 2008 21:55:34 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/164500</link>
        <guid>http://hax.javaeye.com/blog/164500</guid>
      </item>
          <item>
        <title>使用捕获事件监听器（useCapture=true）的陷阱及其对策</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/162718" style="color:red;">http://hax.javaeye.com/blog/162718</a>&nbsp;
          发表时间: 2008年02月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          DOM event flow有三个phase，capture、target和bubble。通常我们只在后两个阶段处理事件，也即在调用addEventListener(type, listener, useCapture)时，useCapture设为false。偶尔可能会使用所谓捕获事件监听器（Capturing Event Listeners），即useCapture设为true。但有一个很搞的问题，那就是在event.currentTarget等于event.target的时候（即event flow处于target phase时），是否会调用添加到currentTarget上的useCapture为true的listener？<br /><br />不同浏览器在这一点上存在分歧。各版本的Firefox和最新版本的Safari会调用，而Opera和老版本的Safari就不会调用。<br /><br />有人认为DOM Level 2事件规范在这一点上存有歧义，但如果仔细分析，可以确定DOM 2规范的意思确实是不应在目标阶段（target phase）调用捕获事件监听器，W3C发布的测试套件（test suite）也测试了这一点，DOM 3事件规范的草案也再次明确了这一点。<br /><br />然而基于种种原因，所有版本的Gecko引擎（Firefox等浏览器）和最近版本的WebKit引擎（Safari等浏览器）都会在目标阶段调用包括捕获事件监听器在内的所有监听器，并且有些人认为应该据此修改DOM规范。这种看法确实也存在一定的合理性。<br /><br />具体情况可参考：<br /><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=235441" target="_blank">https://bugzilla.mozilla.org/show_bug.cgi?id=235441</a><br /><a href="http://bugs.webkit.org/show_bug.cgi?id=9127" target="_blank">http://bugs.webkit.org/show_bug.cgi?id=9127</a><br /><br />总之，这一问题在短期内可能不会有确定的结果。无论如何，在使用捕获处理器时应注意避免这一不确定行为的影响。<br /><br /><strong>Gotchas</strong><br /><br />元素所对应的区域如果有一部分不在任何子元素内（如文本节点），严格遵循DOM规范的浏览器，就不会执行对应的捕获事件监听器。<br /><br /><pre name="code" class="html">
&lt;div id="div1">
As DOM spec, &lt;strong>Only this area&lt;/strong> will trigger
the capturing event listener for click event on the containing
div element.
&lt;/div>
&lt;script>
var div1 = document.getElementById('div1');
div1.addEventListener('click', function () { alert('ok'); }, true);
&lt;/script>
</pre><br /><br />又如，如果同一个监听器，在同一个元素上注册两次，一次useCapture为true，一次为false，那么在严格遵循DOM规范的浏览器中，监听器在整个event flow中只会被调用一次；反之则会被连续调用两次，而且函数自身是无法判断到底是作为捕获事件监听器被调用，还是作为非捕获事件监听器被调用。当然，实际上是先调用捕获事件监听器再调用非捕获事件监听器的，但是如果加上target对象上的event handler（即onclick之类的事件属性），就又产生了微妙的顺序问题。Gecko的顺序是先执行handler再执行监听器，而WebKit的顺序是先执行捕获事件监听器，再执行handler，最后执行非捕获事件监听器。<br /><br /><strong>Workaround</strong><br /><br />为了解决这类不确定性，可以采用一个通用的模式如下：<br /><br /><pre name="code" class="javascript">
node.addEventListener(type, listener, true);

function listener(evt) {
  if (evt.currentTarget == evt.target) return;
  ...
}
</pre><br /><br />这样就确保了不会在target阶段执行捕获事件监听器。我们也可以判断 evt.eventPhase != evt.CAPTURING_PHASE，但是浏览器的eventPhase也可能有bug，所以最好直接判断currentTarget是否等于target。<br /><br />此外，有些时候我们反而希望确保在target阶段执行（这也正是认为应该修改DOM规范的理由之一）。可以采用以下模式：<br /><br /><pre name="code" class="javascript">
node.addEventListener(type, listener1, true);
node.addEventListener(type, listener2, false);

function listener1(evt) {
  if (evt.currentTarget == evt.target) return;
  ...
}
function listener2(evt) {
  if (evt.currentTarget != evt.target) return;
  ...
}
</pre><br /><br />或者<br /><br /><pre name="code" class="javascript">
node.addEventListener(type, listener, true);
node.parentNode.addEventListener(type, listener, true);

function listener(evt) {
  if (evt.currentTarget == node.parentNode && evt.target != node
  || evt.currentTarget == evt.target) return;
  ...
}
</pre><br /><br />在执行顺序上，前者类似Gecko的行为，后者类似WebKit的行为。<br /><br />而且最好不要使用后者，因为它强制要求事件监听器引用target节点，从而构成了闭包，这降低了listener的可重用性。<br /><br />总的来说，我建议应尽可能避免使用useCapture=true，因为绝大多数需求都应在target和bubbling阶段处理，特别是涉及UI的事件。如果确实有必要使用捕获事件处理器，应优先考虑符合当前DOM规范的约束，即不在target阶段执行它。这意味着，useCapture应该用于<strong>拦截</strong>符合条件的子节点事件（许多事件常常仅限于元素），而不是用于一般的事件响应。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/162718#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 17 Feb 2008 07:02:42 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/162718</link>
        <guid>http://hax.javaeye.com/blog/162718</guid>
      </item>
          <item>
        <title>运动型灵车</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/161832" style="color:red;">http://hax.javaeye.com/blog/161832</a>&nbsp;
          发表时间: 2008年02月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          联想的David Hill回顾了他年轻时候误打误撞的故事，结果是出现了保时捷概念的灵车。<br />原文请看：<a href="http://lenovoblogs.com/designmatters/?p=199" target="_blank">DOA Design</a>。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/161832#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 10 Feb 2008 22:55:02 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/161832</link>
        <guid>http://hax.javaeye.com/blog/161832</guid>
      </item>
          <item>
        <title>版本、兼容性以及标准 续（翻译）</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/161818" style="color:red;">http://hax.javaeye.com/blog/161818</a>&nbsp;
          发表时间: 2008年02月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          续<a href="http://hax.javaeye.com/blog/161796" target="_blank">前半部分</a>。<br /><br /><strong>Commitment to Standards and Interoperability<br />对于标准和互操作性的承诺</strong><br /><br />Yet another reason we feel more mode switches are not a good idea for WebKit is our commitment to Web standards, and to interoperability with other browsers. We strongly believe that Web standards are the path forward for interoperability, and we work closely with Web standards groups and other browser vendors to align behavior.<br />我们认为对于WebKit来说更多模式切换不是好主意，还有另一个原因，那就是我们对于Web标准的信仰，以及我们对于与其他浏览器的互操作性的承诺。我们坚定的相信，Web标准是通向互操作性之路，并且我们与Web标准团体和其他浏览器厂商紧密合作，以统一浏览器的行为。<br /><br />Part of this commitment is delivering standards-compliant behavior out of the box. We don’t ask you to set a special preference, or to add extra markup to your web page, or anything else beyond the long established standards mode switch. That means WebKit can truly pass standards-based tests like Acid2 and someday the forthcoming Acid3, and we’ll work more like other standards-based browsers over time. In general, web developers are happy to get automatic ever-advancing standards support from our engine, and indeed our support for advanced CSS3 properties has unleashed a wave of creativity in iPhone web apps.<br />让遵循标准的行为即时可用，也是这一承诺的应有之义。我们不会要求你设置特别选项，或是在你的网页中加入额外标记，除了已经存在的标准和怪癖模式切换之外，我们不会要求你做任何其他额外的事情。这意味着WebKit能真正的通过基于标准的测试，如<a href="http://www.webstandards.org/action/acid2" target="_blank">Acid2</a>和未来的Acid3，我们也会与其他基于标准的浏览器逐步趋向一致。总的来说，web开发者乐于从我们的引擎获得自动不断提升的标准支持，事实上我们对于高级CSS3特性的支持已经在iPhone的web应用中释放了<a href="http://lipidity.com/apple/iphone-webkit-css-3" target="_blank">巨大的创造力</a>。<br /><br /><strong>Reducing Engine Fragmentation<br />减少引擎的散乱</strong><br /><br />Another key reason to avoid more modes is to reduce the number of different compatibility profiles that web content authors have to deal with. With many different vendors shipping WebKit-based products, we rely a lot on the fact that uptake of WebKit-based browsers is really fast. Already many web developers are focusing primarily on Safari 3 and not Safari 2, because in only a few months the majority of users have upgraded.<br />应避免更多模式的另一个关键原因，是为了减少web内容创作者所需面对的不同兼容性配置方案（profile）的数量。随着许多不同的厂商采用基于WebKit的产品，市场对于基于WebKit的浏览器接受很快。已经有许多web开发者主要为Safari 3而不是Safari 2做开发，因为在很短时间内大多数用户就已经升级。<br /><br />But locking in compatibility would mean you have to think about the compatibility profiles of old browsers a lot longer. And no one wants to think about the state of the engine in Safari 2 - I sure don’t! We made thousands of fixes and improvements and those fixes deserve to stick.<br />而兼容性锁定意味着你必须更长久的考虑旧浏览器的兼容性配置方案。没有人想去考虑Safari 2中引擎的版本状况——至少我不想。我们已经做了数以千计的修补与改进，它们可不好对付【这句意思吃不准】。<br /><br /><strong>We Don’t Really Need It<br />我们并不很需要它</strong><br /><br />Finally, while we sympathize with the tough road that the IE team has to travel to achieve a high degree of standards compliance, we haven’t really experienced the same problem. The IE team has mentioned severe negative feedback on the IE7 release, due to sites expecting standards behavior from most browsers, but IE6 bugs from IE.<br /><br />最后，我们理解IE团队为了做到高度遵循标准，需要经历艰难之旅，不过我们自己并没有这样的问题。IE团队提到了IE7发布后严重的负面反馈，这是因为对于大多数浏览器，网站期待的是符合标准的行为，唯独对于IE，网站期待的是IE6的bug。<br /><br />But WebKit already has a high degree of standards compliance. And we are not in the enviable but tough position of being the most widely used browser. The fixes we do for standards compliance rarely cause widespread destruction, and when they do, it’s often a sign that the standards themselves may need revision. We do not get complaints from web content authors about their sites breaking, on the contrary we get a lot of praise for each version of the engine handling web sites better.<br />WebKit已经高度遵循标准了。我们也没有像最广为使用的浏览器那样，处于令人羡慕却又进退两难的位置。我们为遵循标准而做的修改极少会造成广泛的破坏，而且如果产生破坏，那往往说明标准本身需要修订。我们没有从web内容创作者那儿听到网站坏掉的抱怨，相反，我们得到了大量的赞扬，称赞我们每个引擎版本都能使网站变得越来越好。<br /><br /><strong>Conclusion<br />结论</strong><br /><br />So, in conclusion, we don’t see a great need to implement version targeting in Safari. We think maintaining multiple versions of the engine would have many downsides for us and little upside. The IE team is, of course, under different constraints and free to make their own choices.<br />所以，结论是，我们并没有发现有必要在Safari中实现版本目标（version targeting）。我们认为维护引擎的多个版本对我们来说是弊大于利。当然，IE团队处于不同的约束条件下，自然可自行作出他们自己的决策。<br /><br /><br />正文完。<br /><br />注意：对本文所涉及的HTML版本问题，请<a href="http://www.javaeye.com/topic/161733" target="_blank">移驾此处讨论</a>。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/161818#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 10 Feb 2008 19:40:38 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/161818</link>
        <guid>http://hax.javaeye.com/blog/161818</guid>
      </item>
          <item>
        <title>版本、兼容性以及标准（翻译）</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/161796" style="color:red;">http://hax.javaeye.com/blog/161796</a>&nbsp;
          发表时间: 2008年02月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本文译自Maciej Stachowiak在webkit团队blog上的文章<a href="http://webkit.org/blog/155/versioning-compatibility-and-standards/" target="_blank">Versioning, Compatibility and Standards</a>。本文可作为分歧巨大的“HTML的版本问题”的背景材料，对此问题的探讨也请<a href="http://www.javaeye.com/topic/161733" target="_blank">移驾此处讨论</a>。注意，【】中的内容为我所加的注。<br /><br /><span style="font-size: large">Versioning, Compatibility and Standards<br />版本、兼容性以及标准</span><br /><br />Posted by Maciej Stachowiak on Tuesday, January 22nd, 2008 at 11:51 pm<br />Maciej Stachowiak发表于2008年1月22日星期二<br /><br />The new IE8 version targeting switch, announced on IEBlog and A List Apart, has been the talk of the web. Some web standards experts, like Eric Meyer and Jeffrey Zeldman see the switch in a positive light. Others, including Dean Edwards, Robert O’Callahan and Anne van Kesteren think the proposal is a bad idea.<br /><a href="http://blogs.msdn.com/ie/archive/2008/01/21/compatibility-and-ie8.aspx" target="_blank">IEBlog</a>和<a href="http://alistapart.com/articles/beyonddoctype" target="_blank">A List Apart</a>上声明了新的IE8的版本目标切换特性（version targeting switch），这成为了最近谈论的焦点。一些web标准专家，如<a href="http://alistapart.com/articles/fromswitchestotargets" target="_blank">Eric Meyer</a>和<a href="http://www.zeldman.com/2008/01/22/in-defense-of-version-targeting/" target="_blank">Jeffrey Zeldman</a>对这种切换特性给予了正面评价，而其他人，包括<a href="http://dean.edwards.name/weblog/2008/01/quotes/" target="_blank">Dean Edwards</a>、<a href="http://weblogs.mozillazine.org/roc/archives/2008/01/post_2.html" target="_blank">Robert O'Callahan</a>和<a href="http://annevankesteren.nl/2008/01/ie-lock-in" target="_blank">Anne van Kesteren</a>，则认为这一提案是个糟糕的主意。<br /><br />We don’t talk much about what other browsers are doing on this blog. While we’re happy to collaborate on web standards and testing, and sometimes share a little friendly rivalry, we try to keep our focus on making the best Web browser engine we can, not on the competition. So we’re not going to give in-depth commentary on the IE team’s decision. Straddling compatibility and Web standards is a tough job requiring tough choices.<br />在本blog【webkit的官方blog】上我们不会去讨论其他浏览器的所作所为。尽管我们很高兴在Web标准和测试方面进行合作，有时还参与一点友好的竞争，但我们希望把关注点集中于如何尽我所能创造最好的Web浏览器引擎，而不是竞赛上。所以我们不会对IE团队的决定多嘴多舌。平衡兼容性和Web标准总是一项艰难的工作，需要做出艰难的选择。<br /><br />However, some have asked if other browser engines, including WebKit, would adopt a similar version switch. For example, the original announcement asks, “I, for one, hope other browser vendors join Microsoft in implementing this functionality.” I can’t make any definitive statement for all time, but such an approach does not seem like a good idea to us currently. Why, you may ask? There are a few reasons.<br />然而，有人问其他浏览器引擎，包括WebKit，是否能引入类似的版本切换机制。比如，最初声明中提到，“我本人，希望其它浏览器厂商也能和微软一起，实现该特性。”我并不能做出权威声明，但是可以说，这一想法对我们目前来说并不是一个好主意。 <br /><br /><strong>Mode Switches in WebKit<br />WebKit中的模式切换</strong><br /><br />WebKit, like most browser engines, has a quirks mode that is triggered by certain old HTML doctypes, or lack of a doctype declaration in text/html. Documents with newer or unknown doctypes, or sent as XML, are processed in standards mode. Like Mozilla and Opera, we apply only a limited set of nonstandard behaviors in quirks mode, and otherwise fix bugs across both modes, if they do not have a specific significant impact on Web compatibility. This is in contrast to the IE approach of completely freezing old behavior in quirks mode.<br />WebKit，正如大多数浏览器引擎一样，具有<a href="http://www.quirksmode.org/css/quirksmode.html" target="_blank">怪癖模式</a>，可由特定的老的HTML doctype或者在text/html下不写doctype声明来触发。文档如果使用新的或者未知的doctype，或者作为XML传送，则会按标准模式处理。像Mozilla和Opera一样，我们在怪癖模式下引入的非标准的行为是相当有限的；其他那些bug，如果对于Web兼容性没有特别重大的影响，则在所有模式下都会被修复。这与IE的方式截然相反，IE的方式是在怪癖模式中完全沿袭旧的行为。<br /><br />We actually have a few modes besides that. A handful of doctypes trigger what is called “almost standards mode”, which is standards mode with one minor deviation, mainly affecting how images lay out in table cells; this is copied from Mozilla. In addition, we have a few rendering and DOM differences between documents served with an XML MIME type and those served with an HTML MIME type, but we are trying to reduce these over time. And finally, we have a Dashboard compatibility mode that has a few extra quirks beyond quirks mode, to handle Dashboard widgets that were coded to depend on old WebKit bugs.<br />我们其实还有一些其他的模式。有一些doctype会触发所谓“几乎标准模式”，也就是标准模式附带一个小例外，主要是影响图像在表格单元中的布局方式【即在单元格中的图像会紧贴边界，而不会因默认的baseline对齐方式留下空白】；这一方式是从Mozilla照搬来的。此外，文档按照XML MIME类型传输或HTML MIME类型传输，在呈现效果和DOM模型上还有少许不同之处，但是我们试图逐渐消除这些不同。最后，我们还有一个Dashboard兼容模式，它在怪癖模式之外还有一些额外的怪癖，以满足一些Dashboard微件（widget）的需求，它们的代码依赖某些旧的WebKit的bug。<br /><br /><strong>Maintainability<br />可维护性</strong><br /><br />As you can see, this is quite a few modes already. Having lots of modes raises a number of challenges for maintaining the engine.<br />如你所见，我们已经有好些不同的模式了。这对于引擎的维护来说是很大的挑战。<br /><br />First, the more different modes there are, the harder it is to fully test the engine. We have an aggressive approach to automated testing, and our layout tests often find critical problems before they are shipped or even checked in. Having more modes means many things need to be tested in multiple modes. So that’s more tests, more time for developers to run the test suite, and more chances of missing code coverage, especially when different modes interact.<br />首先，模式越多，越难以对引擎进行全面测试。我们采用积极的<a href="http://trac.webkit.org/projects/webkit/wiki/Writing%20Layout%20Tests%20for%20DumpRenderTree" target="_blank">自动测试</a>方式，通过我们的布局测试，那些严重的问题一般总能在正式发布甚至签入代码库之前就被发现。更多的模式意味着有许多事情需要在多个模式中进行测试。也就是要写更多的测试，开发者要花更多的时间来运行测试套件，并且更有可能达不到代码的测试覆盖度，特别是当不同模式相互作用时。<br /><br />Second, implementing mode switches hurts hackability of the code. Hackability is one of our core project goals. It’s part of the reason new contributors can dive in quickly, and enables us to rapidly develop new features, while improving performance, stability, and security.<br />其次，实现模式切换会损害代码的hackability。hackability是我们这个<a href="http://webkit.org/projects/goals.html" target="_blank">项目的核心目标</a>之一。新的贡献者之所以能快速切入，hackability是很重要的一点，它让我们在改进性能、稳定性和安全的同时，也能快速开发新的特性。<br /><br />There’s two plausible ways to add more modes. One is to make all engine changes conditional on a version flag. Another is to have a whole second copy of the layout code. Either would be a huge additional barrier to entry for developers, and would make it harder to maintain the code.<br />要增加新的模式，有两种看似可行的方式。一种是引擎所有的改动都加上对版本号的条件判断。另一种则是完整拷贝一份布局代码。无论哪种方式，对于开发者的参与来说都是一个巨大的额外障碍，也使得代码更难维护。<br /><br />So, bottom line, we’d like to see fewer modes, not more.<br />所以基本上，我们希望模式更少，而不是更多。<br /><br /><strong>Mobile-Readiness<br />移动适用性</strong><br /><br />In addition to maintainability, an important feature of the WebKit engine is the ease with which it is deployed on limited-capability devices such as mobile phones. Some of the more prominent examples include Nokia’s S60 Browser, Apple’s iPhone and iPod touch, and Google’s Android platform. These and other products all include a full-powered version of WebKit, no compromises.<br />除了可维护性之外，WebKit引擎的一个重要特色是易于部署到功能有限的设备，如移动电话上。大家熟知的例子包括诺基亚的<a href="http://www.s60.com/business/productinfo/builtinapplications/webrowser/" target="_blank">S60浏览器</a>、苹果的<a href="http://www.apple.com/iphone/" target="_blank">iPhone</a>和<a href="http://www.apple.com/ipodtouch/" target="_blank">iPod touch</a>，以及谷歌的<a href="http://code.google.com/android/" target="_blank">Android平台</a>。这些产品都包含了一个WebKit的全功能版本，没有损失任何功能。<br /><br />However, having more mode switches cuts against this. The extra code (possibly whole extra copies of the engine, at the very least a whole lot of extra if statements) would be a significant burden on mobile devices. It’s not very well aligned with our mission of staying lean and mean.<br />然而，如果有更多的模式切换，则会损害这一点。额外的代码（可能是所有额外的引擎拷贝，或者至少是大量额外的if语句）对于移动设备来说会是严重的负担。这与我们至精至简（lean and mean）的目标不相一致。<br /><br /><a href="http://hax.javaeye.com/blog/161818" target="_blank">待续……</a>
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/161796#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 10 Feb 2008 06:03:42 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/161796</link>
        <guid>http://hax.javaeye.com/blog/161796</guid>
      </item>
          <item>
        <title>萝卜丝莱斯——萝卜中的劳斯莱斯</title>
        <author>hax</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hax.javaeye.com">hax</a>&nbsp;
                    链接：<a href="http://hax.javaeye.com/blog/161757" style="color:red;">http://hax.javaeye.com/blog/161757</a>&nbsp;
          发表时间: 2008年02月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          刚刚在《上班这点事》中看到的，实在是太赞太爆笑了！强烈推荐！不知道有人能把它上传到youtube上去么。
          <br/>
          <span style="color:red;">
            <a href="http://hax.javaeye.com/blog/161757#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/70' target='_blank'><span style="color:red;font-weight:bold;">第二届网络工程师侠客行大会5月24日杭州举行</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 09 Feb 2008 16:14:59 +0800</pubDate>
        <link>http://hax.javaeye.com/blog/161757</link>
        <guid>http://hax.javaeye.com/blog/161757</guid>
      </item>
      </channel>
</rss>