<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.feedsky.com/styles/temp01.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link href="http://feed.army8735.org" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/army8735" type="application/rss+xml"></fs:self_link><lastBuildDate>Fri, 25 Nov 2011 03:50:18 GMT</lastBuildDate><title>army8735</title><description>我可以A，我也可以-A，我可以同时A和-A。</description><link>http://army8735.org</link><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><language>en</language><pubDate>Fri, 25 Nov 2011 04:07:52 GMT</pubDate><item><title>基于interactive机制的onload次序测试</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668177/5961215/1/item.html</link><content:encoded>&lt;p&gt;接&lt;a href=&quot;http://army8735.org/2011/11/19/1041.html&quot; target=&quot;_blank&quot;&gt;上篇&lt;/a&gt;。ie下错位几率相对而言有些大，于是基于interactive特性进行改善。这其实反而是走回老路了～&lt;/p&gt;
&lt;p&gt;在意想之中的是，ie下十万分之一几率的错位果然降了，而且降到了没有一个错误……webkit内核依旧保持极低概率，奇怪的是firefox在上两次中从未出现错误的先提下，这次爆出了十位数的错位。&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie6&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;162339&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;858130&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;859823&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1551704&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie7&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;40125&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;208591&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;208680&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;376486&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie8&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;113878&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;622694&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;625345&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1131155&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie9&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;24716&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;113455&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;113505&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;201967&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie10&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;8&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;25&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;29&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;43&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;webkit&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AbBa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BAab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;3&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;53189&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;261443&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;261880&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;470557&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ff&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;&amp;#8220;AbBa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;85&amp;#8243;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;5707&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;36962&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;36998&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;68004&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;opera&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;5&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;3124&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;3221&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;6360&amp;#8243;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;other&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;3&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;5&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;5&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;11&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;21&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;76&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;82&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;92&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;95&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;134&amp;#8243;&lt;/div&gt;
&lt;div&gt;&amp;#8220;AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;175&amp;#8243;&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;8420947&lt;/span&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668177/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668177/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/11/25/1048.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>接上篇。ie下错位几率相对而言有些大，于是基于interactive特性进行改善。这其实反而是走回老路了～
在意想之中的是，ie下十万分之一几率的错位果然降了，而且降到了没有一个错误……webkit内核依旧保持极低概率，奇怪的是firefox在上两次中从未出现错误的先提下，这次爆出了十位数的错位。
ie6
&amp;#8220;BbAa&amp;#8221; &amp;#8220;162339&amp;#8243;
&amp;#8220;Aa&amp;#8221; &amp;#8220;858130&amp;#8243;
&amp;#8220;Bb&amp;#8221; &amp;#8220;859823&amp;#8243;
&amp;#8220;AaBb&amp;#8221; &amp;#8220;1551704&amp;#8243;
ie7
&amp;#8220;BbAa&amp;#8221; &amp;#8220;40125&amp;#8243;
&amp;#8220;Aa&amp;#8221; &amp;#8220;208591&amp;#8243;
&amp;#8220;Bb&amp;#8221; &amp;#8220;208680&amp;#8243;
&amp;#8220;AaBb&amp;#8221; &amp;#8220;376486&amp;#8243;
ie8
&amp;#8220;BbAa&amp;#8221; &amp;#8220;113878&amp;#8243;
&amp;#8220;Bb&amp;#8221; &amp;#8220;622694&amp;#8243;
&amp;#8220;Aa&amp;#8221; &amp;#8220;625345&amp;#8243;
&amp;#8220;AaBb&amp;#8221; &amp;#8220;1131155&amp;#8243;
ie9
&amp;#8220;BbAa&amp;#8221; &amp;#8220;24716&amp;#8243;
&amp;#8220;Aa&amp;#8221; &amp;#8220;113455&amp;#8243;
&amp;#8220;Bb&amp;#8221; &amp;#8220;113505&amp;#8243;
&amp;#8220;AaBb&amp;#8221; &amp;#8220;201967&amp;#8243;
ie10
&amp;#8220;BbAa&amp;#8221; &amp;#8220;1&amp;#8243;
&amp;#8220;BbAa&amp;#8221; &amp;#8220;8&amp;#8243;
&amp;#8220;Aa&amp;#8221; &amp;#8220;25&amp;#8243;
&amp;#8220;Bb&amp;#8221;...&lt;img src=&quot;http://www1.feedsky.com/t1/580668177/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668177/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>前端开发</category><category>amd</category><category>commonjs</category><pubDate>Fri, 25 Nov 2011 11:50:18 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/11/25/1048.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=1048</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/11/25/1048.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668177/5961215</fs:itemid></item><item><title>错位交换算法被pass</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668178/5961215/1/item.html</link><content:encoded>&lt;p&gt;接&lt;a href=&quot;http://army8735.org/2011/11/18/1034.html&quot; target=&quot;_blank&quot;&gt;上篇&lt;/a&gt;。尽管已经降到了十万分之一级别的几率，但并发下浏览器的不靠谱行为依旧存在。IE6-8下依旧为主要因素，这与使用者人数多也有关，基数大所以数量高。另外2次幂延迟算法对于单线程情况（aA）是能够完全纠正的，这点值得欣慰。&lt;/p&gt;
&lt;p&gt;并发时，abAB、aABb、aAbB、ABba、abBA、AbBa、aBbA、aBAb几种情况按几率依次递减，想要完美解决必须全部纠正。在2次幂延迟算法纠正后，前面3个已经正确，但后面的还是错误的，它们可以统一概括为：ABba。结果原本应该赋给A的a跑到B的身上，互相错位了，所以要进行错位交换。&lt;/p&gt;
&lt;p&gt;理论上前期不可能再进行处理了，我耗了很久发现前期处理是个悖论，剩下的可能只有运行时决定。&lt;/p&gt;
&lt;p&gt;在运行时：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;use(['a', 'b'], function(a, b) {
	a.methodA();
	b.methodB();
});&lt;/pre&gt;
&lt;p&gt;在错位情况下，a不具有methodA方法b才具有，b也反之。此时会抛异常。简单的做法是运行时try，捕捉到异常后交换错位的arguments再运行一次。看起来似乎不错，实际陷阱重重。&lt;/p&gt;
&lt;p&gt;首先methodA和methodB可能方法名相同，甚至逻辑极为相似。这样就不会异常但运行结果是错的。这个概率很低。&lt;/p&gt;
&lt;p&gt;然后这是在2个参数的情况下，2个以上排列比例太多，交换次数很恐怖，不切实际。&lt;/p&gt;
&lt;p&gt;还有这只有1级递归，也就是a和b互相颠倒而已。如果a有依赖或b有依赖，所造成的错位可能有很多，那它们之间互相递归交换非常恐怖，根本不可能实现。&lt;/p&gt;
&lt;p&gt;即使可以通过的define进行包裹一层，抽出factory返回的方法名来提升判断callback的参数顺序准确度，但依然不能解决上述所有问题。所以最后错位交换算法被pass。&lt;/p&gt;
&lt;p&gt;IE下，通过getInteractiveScript的方法，可能提升并发准确度到百万分之一的级别，有待验证。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668178/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668178/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/11/19/1041.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>接上篇。尽管已经降到了十万分之一级别的几率，但并发下浏览器的不靠谱行为依旧存在。IE6-8下依旧为主要因素，这与使用者人数多也有关，基数大所以数量高。另外2次幂延迟算法对于单线程情况（aA）是能够完全纠正的，这点值得欣慰。
并发时，abAB、aABb、aAbB、ABba、abBA、AbBa、aBbA、aBAb几种情况按几率依次递减，想要完美解决必须全部纠正。在2次幂延迟算法纠正后，前面3个已经正确，但后面的还是错误的，它们可以统一概括为：ABba。结果原本应该赋给A的a跑到B的身上，互相错位了，所以要进行错位交换。
理论上前期不可能再进行处理了，我耗了很久发现前期处理是个悖论，剩下的可能只有运行时决定。
在运行时：
use(['a', 'b'], function(a, b) {
	a.methodA();
	b.methodB();
});
在错位情况下，a不具有methodA方法b才具有，b也反之。此时会抛异常。简单的做法是运行时try，捕捉到异常后交换错位的arguments再运行一次。看起来似乎不错，实际陷阱重重。
首先methodA和methodB可能方法名相同，甚至逻辑极为相似。这样就不会异常但运行结果是错的。这个概率很低。
然后这是在2个参数的情况下，2个以上排列比例太多，交换次数很恐怖，不切实际。
还有这只有1级递归，也就是a和b互相颠倒而已。如果a有依赖或b有依赖，所造成的错位可能有很多，那它们之间互相递归交换非常恐怖，根本不可能实现。
即使可以通过的define进行包裹一层，抽出factory返回的方法名来提升判断callback的参数顺序准确度，但依然不能解决上述所有问题。所以最后错位交换算法被pass。
IE下，通过getInteractiveScript的方法，可能提升并发准确度到百万分之一的级别，有待验证。&lt;img src=&quot;http://www1.feedsky.com/t1/580668178/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668178/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>数据结构、算法</category><category>前端开发</category><category>amd</category><category>commonjs</category><pubDate>Sat, 19 Nov 2011 12:07:15 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/11/19/1041.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=1041</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/11/19/1041.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668178/5961215</fs:itemid></item><item><title>改进load机制后的onload次序测试</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668179/5961215/1/item.html</link><content:encoded>&lt;p&gt;接&lt;a href=&quot;http://army8735.org/2011/11/17/1028.html&quot; target=&quot;_blank&quot;&gt;上篇&lt;/a&gt;，之前用的加载script机制有问题，同时赋予了onload = onreadystatechange，这在同时支持的浏览器（ie9）下有影响，新的方法分开对待。&lt;/p&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;other success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		3&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		3&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		4&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		4&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		6&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		6&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		6&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		12&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		17&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		23&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		26&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		30&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		32&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		76&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		102&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		155&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie7 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ab		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;bAa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;a		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		61&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		83&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		12481&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		26430&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		69314&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		201493&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		202091&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		295501&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie6 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;aBb		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		22&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		89&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		50511&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		106465&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		287284&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		835892&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		836129&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		1227774&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;webkit success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		7&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		51452&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		254856&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		255189&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		454364&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;FF success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		109&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		5512&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		35757&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		36034&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		65577&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie10 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		4&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		7&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		12&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		35&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		45&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		59&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;opera success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		6&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		3077&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		3092&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		5990&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie9 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		7968&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		17482&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		26081&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		109073&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		109478&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		166921&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie8 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		16&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		80&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		31761&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		84319&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		241514&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		616614&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		617047&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		874323&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&lt;strong&gt;出现了onload抢先exec的现象且顺序不一致，比如 CcaABb，总数：123&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;B		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		7&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		16&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		22&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		61&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #000080;&quot;&gt;&lt;strong&gt;顺序不一致，比如 CcAbBa，总数：381&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ab		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;aBb		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;B		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;bAa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;a		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		7&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		16&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		22&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		61&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		80&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		83&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		89&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;几率381/8226030 =0.000046316388342857974，主要集中在IE6-IE8。&lt;/span&gt;&lt;/div&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668179/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668179/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/11/18/1034.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>接上篇，之前用的加载script机制有问题，同时赋予了onload = onreadystatechange，这在同时支持的浏览器（ie9）下有影响，新的方法分开对待。
other success
BAba		1
Bb		1
BbAa		1
AaBb		1
BbAa		1
BAba		1
BbAa		1
Aa		2
AaBb		2
Bb		3
Aa		3
BAba		4
ABab		4
Aa		6
BbAa		6
ABab		6
Bb		8
ABab		12
AaBb		17
Bb		23
AaBb		26
ABab		30
Aa		32
Aa		76
Bb		102
ABab		155
ie7 success
ab		1
bAa		1
a		1
BaAb		61
ABba		83
BAba		12481
BbAa		26430
AaBb		69314
Aa		201493
Bb		202091
ABab		295501
ie6 success
aBb		1
AbBa		22
BAab		89
BAba		50511
BbAa		106465
AaBb		287284
Bb		835892
Aa		836129
ABab		1227774
webkit success
ABba		2
BaAb		7
BbAa		51452
Bb		254856
Aa		255189
AaBb		454364
FF success
BAba		2
ABab		109
BbAa		5512
Bb		35757
Aa		36034
AaBb		65577
ie10 success
BbAa		4
BAba		7
AaBb		12
Bb		35
Aa		45
ABab		59
opera success
ABab		6
Bb		3077
Aa		3092
AaBb		5990
ie9 success
BaAb		8
AbBa		8
BbAa		7968
BAba		17482
AaBb		26081
Bb		109073
Aa		109478
ABab		166921
ie8 success
AbBa		16
BAab		80
BAba		31761
BbAa		84319
AaBb		241514
Bb		616614
Aa		617047
ABab		874323
出现了onload抢先exec的现象且顺序不一致，比如 CcaABb，总数：123
B		1
BaAb		7
BaAb		8
AbBa		8
AbBa		16
AbBa		22
BaAb		61
顺序不一致，比如 CcAbBa，总数：381
ab		1
aBb		1
B		1
bAa		1
a		1
ABba		2
BaAb		7
BaAb		8
AbBa		8
AbBa		16
AbBa		22
BaAb		61
BAab		80
ABba		83
BAab		89
几率381/8226030 =0.000046316388342857974，主要集中在IE6-IE8。&lt;img src=&quot;http://www1.feedsky.com/t1/580668179/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668179/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>前端开发</category><category>amd</category><category>commonjs</category><pubDate>Fri, 18 Nov 2011 11:47:19 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/11/18/1034.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=1034</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/11/18/1034.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668179/5961215</fs:itemid></item><item><title>采用2次幂延迟算法的onload次序测试</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668180/5961215/1/item.html</link><content:encoded>&lt;p&gt;接&lt;a href=&quot;http://army8735.org/2011/11/10/1019.html&quot; target=&quot;_blank&quot;&gt;上篇&lt;/a&gt;。另外对于基础性原理不清楚的请查看射雕的介绍：&lt;a href=&quot;http://lifesinger.wordpress.com/2011/11/11/get-url-in-module-loader/&quot;&gt;http://lifesinger.wordpress.com/2011/11/11/get-url-in-module-loader/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;通过1周的海量数据多次测试与研究，我和射雕发现了所有浏览器下都有的共同bug：onload事件先于script标签的加载发生。这个结论直接表明，目前所有对于script的onload的侦听都不是完美的！一旦有了这个低几率问题，那些莫名的错误会让人十分困惑。&lt;/p&gt;
&lt;p&gt;介于此，我尝试使用2^ delay的算法来延迟onload的运行。它的理论基础来源于抑制网络风暴的算法：即onload先检查script的exec，没有时延迟2 ^ 0单位时间后再检查、再没有延迟2 ^ 1、2 ^ 2……以此类推。&lt;/p&gt;
&lt;p&gt;在昨天的海量观测数据下面，结果是惊喜的。没有1次发生了error，全部正确。但是依然存在低几率次序打乱的情况，这是接下来要着手解决的问题（或者干脆忽略掉）。&lt;/p&gt;
&lt;p&gt;最后祝福下Firefox和IE10，你们的顺序是100%正确的。&lt;/p&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;other success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		3&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		3&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		3&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		4&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		5&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		11&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		12&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		23&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		23&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		26&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		28&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		28&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		91&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		97&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		171&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;opera success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		1&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		28&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		2742&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		2783&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		5484&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie8 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		17&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		29&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		30901&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		82405&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		233970&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		599658&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		600632&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		853122&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;webkit success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		4&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		5&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		50606&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		246173&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		246419&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		441956&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie10 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		9&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		29&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		31&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		36&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie9 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		2&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		4&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		30&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		159&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		8915&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		15603&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		35080&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		104627&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		105027&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		149314&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie7 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		8&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		12&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		35&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		81&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		11900&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		25614&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		66317&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		193519&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		193970&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		282723&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;ie6 success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABba		10&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AbBa		14&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAab		21&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BaAb		57&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BAba		50272&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		104528&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		275505&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		811928&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		813622&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		1189557&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;FF success&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;ABab		90&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;BbAa		5578&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Bb		34745&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;Aa		34866&lt;/div&gt;
&lt;div id=&quot;_mcePaste&quot;&gt;AaBb		63339&lt;/div&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668180/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668180/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/11/17/1028.html/feed</wfw:commentRss><slash:comments>1</slash:comments><description>接上篇。另外对于基础性原理不清楚的请查看射雕的介绍：http://lifesinger.wordpress.com/2011/11/11/get-url-in-module-loader/
通过1周的海量数据多次测试与研究，我和射雕发现了所有浏览器下都有的共同bug：onload事件先于script标签的加载发生。这个结论直接表明，目前所有对于script的onload的侦听都不是完美的！一旦有了这个低几率问题，那些莫名的错误会让人十分困惑。
介于此，我尝试使用2^ delay的算法来延迟onload的运行。它的理论基础来源于抑制网络风暴的算法：即onload先检查script的exec，没有时延迟2 ^ 0单位时间后再检查、再没有延迟2 ^ 1、2 ^ 2……以此类推。
在昨天的海量观测数据下面，结果是惊喜的。没有1次发生了error，全部正确。但是依然存在低几率次序打乱的情况，这是接下来要着手解决的问题（或者干脆忽略掉）。
最后祝福下Firefox和IE10，你们的顺序是100%正确的。
other success
AaBb		1
BbAa		1
Aa		1
AaBb		1
Bb		1
BAba		1
ABab		1
BbAa		1
BAba		1
ABab		1
Aa		1
AaBb		2
BbAa		3
Aa		3
BAba		3
Bb		4
Aa		5
BbAa		8
ABab		11
Bb		12
ABab		23
AaBb		23
Aa		26
AaBb		28
Bb		28
Aa		91
Bb		97
ABab		171
opera success
BbAa		1
BAab		1
ABba		1
BaAb		1
ABab		28
Bb		2742
Aa		2783
AaBb		5484
ie8 success
ABba		2
AbBa		8
BAab		17
BaAb		29
BAba		30901
BbAa		82405
AaBb		233970
Bb		599658
Aa		600632
ABab		853122
webkit success
ABba		2
BAab		2
BaAb		4
AbBa		5
BbAa		50606
Aa		246173
Bb		246419
AaBb		441956
ie10 success
BAba		2
AaBb		8
BbAa		9
Aa		29
Bb		31
ABab		36
ie9 success
AbBa		2
BaAb		4
BAab		30
ABba		159
BAba		8915
BbAa		15603
AaBb		35080
Aa		104627
Bb		105027
ABab		149314
ie7 success
AbBa		8
BaAb		12
BAab		35
ABba		81
BAba		11900
BbAa		25614
AaBb		66317
Aa		193519
Bb		193970
ABab		282723
ie6 success
ABba		10
AbBa		14
BAab		21
BaAb		57
BAba		50272
BbAa		104528
AaBb		275505
Bb		811928
Aa		813622
ABab		1189557
FF success
ABab		90
BbAa		5578
Bb		34745
Aa		34866
AaBb		63339&lt;img src=&quot;http://www1.feedsky.com/t1/580668180/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668180/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>数据结构、算法</category><category>前端开发</category><category>amd</category><category>commonjs</category><pubDate>Thu, 17 Nov 2011 10:53:17 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/11/17/1028.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=1028</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/11/17/1028.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668180/5961215</fs:itemid></item><item><title>onload次序测试</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668181/5961215/1/item.html</link><content:encoded>&lt;p&gt;问题的起源是这样的：&lt;/p&gt;
&lt;p&gt;假设加载有2个脚本A和B，而a和b则是附加在各自脚本上的onload侦听。众所周知的，IE下A加载完成exec后a并不是保证立刻触发的，非IE下正常。但是，倘若前提是A的加载完成和B的加载完成顺序确定，即A-&amp;gt;B，那么a-&amp;gt;b的顺序能不能得到保证？即：有可能是AaBb、ABab，但绝不可能有ABba。&lt;/p&gt;
&lt;p&gt;自己测是发现不了问题，但显然范围太小不足以说明情况，所以我借助土豆的某个次要页面流量，做了个大范围精度测试。&lt;/p&gt;
&lt;p&gt;目标：测出IE6、7、8、9下面的顺序情况。&lt;/p&gt;
&lt;p&gt;理由：懂的入。&lt;/p&gt;
&lt;p&gt;用例：用户有25%的几率加载a.js、25%的几率加载b.js、剩余50%全部加载，以此模拟出各种可能被缓存的情况——即可能先缓存a，然后再加载a和b。&lt;/p&gt;
&lt;p&gt;数据结构：第一位的0和1标明页面是否发生error，是的话1，否的话0；后面大写字母是script标签被加载exec时记录，小写字母是其onload触发时记录；再后面数字是次数。&lt;/p&gt;
&lt;p&gt;结果：近千万份数据，&lt;span style=&quot;color: #000000;&quot;&gt;可能因对浏览器ua的判断稍稍有些误差。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;error&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;ie6&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;3410&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1a&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2979&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1b&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2901&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1575&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;136&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;61&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1&amp;#8243;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;56&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;12&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1A&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;10&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1ab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;9&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;7&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;4&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1AB&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;ie7&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1b&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;771&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1a&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;743&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;738&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;376&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1&amp;#8243;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;108&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;23&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;15&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;10&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;3&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;ie8&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2460&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1a&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2050&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1b&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1887&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1290&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1&amp;#8243;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;322&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;95&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;39&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;20&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;11&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;ie9&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;372&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1a&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;321&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1b&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;285&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;218&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;10&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Aba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;6&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1&amp;#8243;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;1Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;success&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;ie6&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1591785&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1093518&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1093213&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;373421&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;137775&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BAba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;79495&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ABba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;4&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0aBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BaAb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;ie7&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;371165&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;257674&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;257001&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;88582&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;33734&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BAba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;20710&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ABba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;108&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BAab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;23&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BaAb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;2&amp;#8243;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;ie8&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1108442&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;794383&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;792879&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;313784&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;108791&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BAba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;54147&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ABba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;4&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BaAb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;1&amp;#8243;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;ie9&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ABab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;188309&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0Aa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;132499&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0Bb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;131587&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0AaBb&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;44003&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BbAa&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;19110&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BAba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;12620&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0ABba&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;211&amp;#8243;&lt;/p&gt;
&lt;p&gt;&amp;#8220;0BAab&amp;#8221;&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;#8220;40&amp;#8243;&lt;/p&gt;
&lt;p&gt;补张同事做的图：&lt;a href=&quot;http://army8735.org/wp-content/uploads/2011/11/111.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-1026&quot; title=&quot;111&quot; src=&quot;http://army8735.org/wp-content/uploads/2011/11/111.jpg&quot; alt=&quot;&quot; width=&quot;1149&quot; height=&quot;619&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668181/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668181/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/11/10/1019.html/feed</wfw:commentRss><slash:comments>28</slash:comments><description>问题的起源是这样的：
假设加载有2个脚本A和B，而a和b则是附加在各自脚本上的onload侦听。众所周知的，IE下A加载完成exec后a并不是保证立刻触发的，非IE下正常。但是，倘若前提是A的加载完成和B的加载完成顺序确定，即A-&amp;#62;B，那么a-&amp;#62;b的顺序能不能得到保证？即：有可能是AaBb、ABab，但绝不可能有ABba。
自己测是发现不了问题，但显然范围太小不足以说明情况，所以我借助土豆的某个次要页面流量，做了个大范围精度测试。
目标：测出IE6、7、8、9下面的顺序情况。
理由：懂的入。
用例：用户有25%的几率加载a.js、25%的几率加载b.js、剩余50%全部加载，以此模拟出各种可能被缓存的情况——即可能先缓存a，然后再加载a和b。
数据结构：第一位的0和1标明页面是否发生error，是的话1，否的话0；后面大写字母是script标签被加载exec时记录，小写字母是其onload触发时记录；再后面数字是次数。
结果：近千万份数据，可能因对浏览器ua的判断稍稍有些误差。
error
ie6
&amp;#8220;1Aab&amp;#8221; &amp;#8220;3410&amp;#8243;
&amp;#8220;1a&amp;#8221; &amp;#8220;2979&amp;#8243;
&amp;#8220;1b&amp;#8221; &amp;#8220;2901&amp;#8243;
&amp;#8220;1Bba&amp;#8221; &amp;#8220;1575&amp;#8243;
&amp;#8220;1Bab&amp;#8221; &amp;#8220;136&amp;#8243;
&amp;#8220;1Aba&amp;#8221; &amp;#8220;61&amp;#8243;
&amp;#8220;1&amp;#8243; &amp;#8220;56&amp;#8243;
&amp;#8220;1Aa&amp;#8221; &amp;#8220;12&amp;#8243;
&amp;#8220;1A&amp;#8221; &amp;#8220;10&amp;#8243;
&amp;#8220;1ab&amp;#8221; &amp;#8220;9&amp;#8243;
&amp;#8220;1Bb&amp;#8221; &amp;#8220;7&amp;#8243;
&amp;#8220;1ABab&amp;#8221; &amp;#8220;4&amp;#8243;
&amp;#8220;1AB&amp;#8221; &amp;#8220;1&amp;#8243;
ie7
&amp;#8220;1b&amp;#8221; &amp;#8220;771&amp;#8243;
&amp;#8220;1a&amp;#8221; &amp;#8220;743&amp;#8243;
&amp;#8220;1Aab&amp;#8221; &amp;#8220;738&amp;#8243;
&amp;#8220;1Bba&amp;#8221; &amp;#8220;376&amp;#8243;
&amp;#8220;1&amp;#8243; &amp;#8220;108&amp;#8243;
&amp;#8220;1Bab&amp;#8221; &amp;#8220;23&amp;#8243;
&amp;#8220;1Aba&amp;#8221;...&lt;img src=&quot;http://www1.feedsky.com/t1/580668181/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668181/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>前端开发</category><category>amd</category><category>commonjs</category><pubDate>Thu, 10 Nov 2011 12:48:03 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/11/10/1019.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=1019</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/11/10/1019.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668181/5961215</fs:itemid></item><item><title>基于amd规范的自动化版本及智能依赖构建系统实验报告</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668182/5961215/1/item.html</link><content:encoded>&lt;p&gt;实验前提是了解amd规范：&lt;a href=&quot;http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition&quot;&gt;http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition&lt;/a&gt;，国内很多社区或个人或公司或开源项目都已有一些具体实现，不再赘述。&lt;/p&gt;
&lt;p&gt;另外，这里只有概念，不涉及具体算法和代码。&lt;/p&gt;
&lt;h3&gt;版本控制&lt;/h3&gt;
&lt;p&gt;土豆网现有的js版本控制逻辑是为每个更新发布的js文件自动更新版本号，它以&lt;span style=&quot;color: #ff0000;&quot;&gt;下划线+版本号数字&lt;/span&gt;为文件名结尾（不包括后缀名）：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://army8735.org/wp-content/uploads/2011/09/1.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-1009&quot; title=&quot;1&quot; src=&quot;http://army8735.org/wp-content/uploads/2011/09/1.png&quot; alt=&quot;&quot; width=&quot;370&quot; height=&quot;237&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;而在amd中，我们自己实现的异步加载模块机制，譬如说是个use方法，需要使用a.js这个模块。那么不可能每更新一次a.js，所有使用到它的地方都手动改为&lt;span style=&quot;color: #ff0000;&quot;&gt;use(&amp;#8216;a_2.js&amp;#8217;)&lt;/span&gt;。&lt;/p&gt;
&lt;p&gt;实际情况是：源代码里一直写的是&lt;span style=&quot;color: #ff0000;&quot;&gt;use(&amp;#8216;a.js&amp;#8217;)&lt;/span&gt;，至于版本控制，它是在服务器端自动追加的：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://army8735.org/wp-content/uploads/2011/09/2.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-1010&quot; title=&quot;2&quot; src=&quot;http://army8735.org/wp-content/uploads/2011/09/2.png&quot; alt=&quot;&quot; width=&quot;475&quot; height=&quot;416&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;红色字体部分需要特殊解释一下，它并不是正则替换掉所有use(&amp;#8216;a.js&amp;#8217;)的地方，而是做了一个映射或者说路由。以&lt;span style=&quot;color: #ff0000;&quot;&gt;a.js&lt;/span&gt;为key、&lt;span style=&quot;color: #ff0000;&quot;&gt;a_2.js&lt;/span&gt;为value存入一个HashMap中，然后use(&amp;#8216;a.js&amp;#8217;)方法执行时读取到映射关系，将key转换为value后再加载。&lt;/p&gt;
&lt;p&gt;这样做的好处是既不影响规范的id语义，又屏蔽了版本号对开发人员的细节可见度，甚至当迫不得已时想使用某个古老版本亦可：&lt;span style=&quot;color: #ff0000;&quot;&gt;use(&amp;#8216;a_1.js&amp;#8217;)&lt;/span&gt;——因为匹配不到映射关系，所以会直接加载a_1.js这个模块。&lt;/p&gt;
&lt;h3&gt;智能依赖构建&lt;/h3&gt;
&lt;p&gt;有时候一个页面上的js要使用到多个模块，为了节省请求数量，我们希望将多个模块合并到这一个js中。为此引入了&lt;span style=&quot;color: #ff0000;&quot;&gt;@import&lt;/span&gt;语法，它以注释形式出现在文件头部，服务器端构建工具会自动将导入的js文件合并到一起。这个过程是递归的，也就是说会导入可能所有需要导入的子孙文件。&lt;/p&gt;
&lt;p&gt;事实上，这个方法早已屡见不鲜，很多构建工具都是这样做的，只是大部分都是客户端构建，由开发人员手动打包文件后发布。将这一过程移植到服务器端可省却许多不必要的麻烦。&lt;/p&gt;
&lt;p&gt;值得一提的是，打包构建会影响到版本映射时的逻辑。譬如我们use(&amp;#8216;a.js&amp;#8217;)，但a.js已经被导入到当前文件中了，因此映射逻辑会忽视掉它——这个id的模块已经存在，不会再去异步加载了，映射还有什么用呢？&lt;/p&gt;
&lt;h3&gt;更进一步&lt;/h3&gt;
&lt;p&gt;手动导入其实不仅仅限于导入依赖或者导入模块，导入其它不相关的东西都行。有时候，在使用一个模块时，这个模块有依赖、依赖的模块还会继续依赖……我们希望一下子全部导入所有依赖到这个文件，而不想手动@import。较好的做法是增加一个关键字比如&lt;span style=&quot;color: #ff0000;&quot;&gt;@build&lt;/span&gt;，它会递归将所有依赖打包到一个文件中。&lt;/p&gt;
&lt;p&gt;这个步骤我还没有做。&lt;/p&gt;
&lt;h3&gt;是否需要final&lt;/h3&gt;
&lt;p&gt;经过讨论有这样一个观点：a.js被b.js和c.js所依赖，a.js更新后原本b和c都会自动追加版本映射（如果是导入则自动更新导入），但是c并不想随之自动更新，c想等自己文件有更新后才去更新导入和依赖的东西，因此需要增加一个&lt;span style=&quot;color: #ff0000;&quot;&gt;@final&lt;/span&gt;关键字指定。&lt;/p&gt;
&lt;p&gt;经过思考我觉得它&lt;strong&gt;带来的好处和带来的坏处一样多&lt;/strong&gt;：构建和版本映射系统将变得复杂； 阅读维护上增加歧义；等c下次更新时你可能已经忘记了依赖的哪些模块上次没有自动更新。所以这个指令还是不要的好，每次更新一个模块后，所有依赖和导入的都随之自动更新，由测试人员在测试环境根据文件列表全部测试到位。&lt;/p&gt;
&lt;p&gt;实际上我们也应该这样做，一个底层的被大量依赖的模块必须经过严格的测试，它被设计成被大量依赖的说明它是全局性的，即使不存在于amd中也是被写成全局代码，在更新时一样要测试到位。&lt;/p&gt;
&lt;h3&gt;允许并存&lt;/h3&gt;
&lt;p&gt;开发人员手动合并还存在一种冲突现象：这个页面用到了a.js和b.js，一个人改了a另外一个人改了b，他俩在发布测试环境时会互相覆盖对方的结果。服务器端智能构建可以很好的解决这一问题：一个人发a的源文件而另外一个人发b的源文件，同时在测试环境测试；a测试完成后a发布上线即可，不会发布到b，反之亦然。&lt;/p&gt;
&lt;p&gt;甚至某个模块想要设计时也可以是“平滑过渡”的。试想由于某些原因，底层模块a要升级了，但并不是所有地方都兼容新版本，此时我们可以新建个底层模块a2作为新版本，兼容的地方手动替换a2，不兼容的继续使用a。这得益于模块化的松耦合特性。&lt;/p&gt;
&lt;h3&gt;单元测试&lt;/h3&gt;
&lt;p&gt;有了模块化之后，单元测试便有了前提。具体怎么测试就不探讨了，这是属于测试人员的范畴。至于为什么说有了前提，那是因为所有模块文件都是异步加载的，在线上环境可能被合并构建成了一个文件，但是只要将全部js代理成源代码（源代码里只写了类似@import的东西，并没有合并，合并是在服务器端最后发布做的），所有导入都变成异步加载了，这有利于分离调试并定位错误。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668182/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668182/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/09/06/1006.html/feed</wfw:commentRss><slash:comments>1</slash:comments><description>实验前提是了解amd规范：http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition，国内很多社区或个人或公司或开源项目都已有一些具体实现，不再赘述。
另外，这里只有概念，不涉及具体算法和代码。
版本控制
土豆网现有的js版本控制逻辑是为每个更新发布的js文件自动更新版本号，它以下划线+版本号数字为文件名结尾（不包括后缀名）：

而在amd中，我们自己实现的异步加载模块机制，譬如说是个use方法，需要使用a.js这个模块。那么不可能每更新一次a.js，所有使用到它的地方都手动改为use(&amp;#8216;a_2.js&amp;#8217;)。
实际情况是：源代码里一直写的是use(&amp;#8216;a.js&amp;#8217;)，至于版本控制，它是在服务器端自动追加的：

红色字体部分需要特殊解释一下，它并不是正则替换掉所有use(&amp;#8216;a.js&amp;#8217;)的地方，而是做了一个映射或者说路由。以a.js为key、a_2.js为value存入一个HashMap中，然后use(&amp;#8216;a.js&amp;#8217;)方法执行时读取到映射关系，将key转换为value后再加载。
这样做的好处是既不影响规范的id语义，又屏蔽了版本号对开发人员的细节可见度，甚至当迫不得已时想使用某个古老版本亦可：use(&amp;#8216;a_1.js&amp;#8217;)——因为匹配不到映射关系，所以会直接加载a_1.js这个模块。
智能依赖构建
有时候一个页面上的js要使用到多个模块，为了节省请求数量，我们希望将多个模块合并到这一个js中。为此引入了@import语法，它以注释形式出现在文件头部，服务器端构建工具会自动将导入的js文件合并到一起。这个过程是递归的，也就是说会导入可能所有需要导入的子孙文件。
事实上，这个方法早已屡见不鲜，很多构建工具都是这样做的，只是大部分都是客户端构建，由开发人员手动打包文件后发布。将这一过程移植到服务器端可省却许多不必要的麻烦。
值得一提的是，打包构建会影响到版本映射时的逻辑。譬如我们use(&amp;#8216;a.js&amp;#8217;)，但a.js已经被导入到当前文件中了，因此映射逻辑会忽视掉它——这个id的模块已经存在，不会再去异步加载了，映射还有什么用呢？
更进一步
手动导入其实不仅仅限于导入依赖或者导入模块，导入其它不相关的东西都行。有时候，在使用一个模块时，这个模块有依赖、依赖的模块还会继续依赖……我们希望一下子全部导入所有依赖到这个文件，而不想手动@import。较好的做法是增加一个关键字比如@build，它会递归将所有依赖打包到一个文件中。
这个步骤我还没有做。
是否需要final
经过讨论有这样一个观点：a.js被b.js和c.js所依赖，a.js更新后原本b和c都会自动追加版本映射（如果是导入则自动更新导入），但是c并不想随之自动更新，c想等自己文件有更新后才去更新导入和依赖的东西，因此需要增加一个@final关键字指定。
经过思考我觉得它带来的好处和带来的坏处一样多：构建和版本映射系统将变得复杂； 阅读维护上增加歧义；等c下次更新时你可能已经忘记了依赖的哪些模块上次没有自动更新。所以这个指令还是不要的好，每次更新一个模块后，所有依赖和导入的都随之自动更新，由测试人员在测试环境根据文件列表全部测试到位。
实际上我们也应该这样做，一个底层的被大量依赖的模块必须经过严格的测试，它被设计成被大量依赖的说明它是全局性的，即使不存在于amd中也是被写成全局代码，在更新时一样要测试到位。
允许并存
开发人员手动合并还存在一种冲突现象：这个页面用到了a.js和b.js，一个人改了a另外一个人改了b，他俩在发布测试环境时会互相覆盖对方的结果。服务器端智能构建可以很好的解决这一问题：一个人发a的源文件而另外一个人发b的源文件，同时在测试环境测试；a测试完成后a发布上线即可，不会发布到b，反之亦然。
甚至某个模块想要设计时也可以是“平滑过渡”的。试想由于某些原因，底层模块a要升级了，但并不是所有地方都兼容新版本，此时我们可以新建个底层模块a2作为新版本，兼容的地方手动替换a2，不兼容的继续使用a。这得益于模块化的松耦合特性。
单元测试
有了模块化之后，单元测试便有了前提。具体怎么测试就不探讨了，这是属于测试人员的范畴。至于为什么说有了前提，那是因为所有模块文件都是异步加载的，在线上环境可能被合并构建成了一个文件，但是只要将全部js代理成源代码（源代码里只写了类似@import的东西，并没有合并，合并是在服务器端最后发布做的），所有导入都变成异步加载了，这有利于分离调试并定位错误。&lt;img src=&quot;http://www1.feedsky.com/t1/580668182/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668182/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>前端开发</category><category>amd</category><pubDate>Tue, 06 Sep 2011 16:08:36 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/09/06/1006.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=1006</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/09/06/1006.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668182/5961215</fs:itemid></item><item><title>改进了下jq的html5form插件</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668183/5961215/1/item.html</link><content:encoded>&lt;p&gt;以前写过一个旧版本的，现在做了不少变化，最主要修改是分离出2个文件：html5formcore.js和html5form.js。前者用以模拟不支持的低版本浏览器行为，后者则是在其基础上与ui相关的部分。另外也增加了submit类型的各种属性，取消了浏览器默认的表现行为。&lt;/p&gt;
&lt;p&gt;以下便是2个版本，第一个没有ui，第二个基于前者小弄了个ui上去。说明和源码都在链接页面里。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://army8735.org/Ai/test/html5formcore.html&quot;&gt;http://army8735.org/Ai/test/html5formcore.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://army8735.org/Ai/test/html5form.html&quot;&gt;http://army8735.org/Ai/test/html5form.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8212;&lt;/p&gt;
&lt;p&gt;已经修改为晚绑定，这意味着即使元素是后添加进来的，也可以完全模拟html5元素的特性。另外改写使得其对jq1.4版本也有兼容。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668183/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668183/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/08/23/1000.html/feed</wfw:commentRss><slash:comments>1</slash:comments><description>以前写过一个旧版本的，现在做了不少变化，最主要修改是分离出2个文件：html5formcore.js和html5form.js。前者用以模拟不支持的低版本浏览器行为，后者则是在其基础上与ui相关的部分。另外也增加了submit类型的各种属性，取消了浏览器默认的表现行为。
以下便是2个版本，第一个没有ui，第二个基于前者小弄了个ui上去。说明和源码都在链接页面里。
http://army8735.org/Ai/test/html5formcore.html
http://army8735.org/Ai/test/html5form.html
&amp;#8212;
已经修改为晚绑定，这意味着即使元素是后添加进来的，也可以完全模拟html5元素的特性。另外改写使得其对jq1.4版本也有兼容。&lt;img src=&quot;http://www1.feedsky.com/t1/580668183/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668183/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>html5</category><category>前端开发</category><category>form</category><pubDate>Tue, 23 Aug 2011 15:13:56 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/08/23/1000.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=1000</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/08/23/1000.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668183/5961215</fs:itemid></item><item><title>jssc5.1中的匹配模式</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668184/5961215/1/item.html</link><content:encoded>&lt;p&gt;预览：&lt;a href=&quot;http://jssc.googlecode.com/svn/trunk/jssc5/bin/index.html&quot;&gt;http://jssc.googlecode.com/svn/trunk/jssc5/bin/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下载：&lt;a href=&quot;http://code.google.com/p/jssc/downloads/list&quot;&gt;http://code.google.com/p/jssc/downloads/list&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;源码：&lt;a href=&quot;http://jssc.googlecode.com/svn/trunk/jssc5/src/&quot;&gt;http://jssc.googlecode.com/svn/trunk/jssc5/src/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;好久不动，都生疏了。离上次5.1alpha版有好几个月了，今天释出beta版，添加了Python语法。&lt;/p&gt;
&lt;p&gt;之前说过5.1版本最大的变动是使得添加新的语法变得更加容易，老的5.0版每个新语言都得写个词法分析器太累了，于是乎花大精力修改这一部分，添加了“匹配模式”类，用以方便添加新语法解析。&lt;/p&gt;
&lt;h3&gt;匹配模式的概念&lt;/h3&gt;
&lt;p&gt;简单地说，匹配模式就是描述某个语言基本词法单元（Token）的规则。以javascript举例，需要高亮的Token大致有注释、字符串、正则表达式、数字、关键字。其中关键字属于Word中的保留字。注释的匹配模式就是以/*开头*/结尾的代码、字符串是指引号之间的内容等等。&lt;/p&gt;
&lt;h3&gt;现有的几种匹配模式&lt;/h3&gt;
&lt;p&gt;所有匹配模式都实现IMatch接口，我目前定义了以下几种：CharacterSet、CompleteEqual、LinearSearch、LinearParse、IDMatch、RegularMatch。&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;CharacterSet&lt;/span&gt; 是个字符集匹配，它定义了Token以什么字符集为开头并以什么字符集为组成内容。比如js中的Word是以下划线、美元符号、字母为开头，下划线、美元符号、字母和数字为组成内容。出于初期设计的原因，字符集不能完全自定义，只能使用已经定义的若干常量。这个缺陷会在以后考虑。&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;CompleteEqual&lt;/span&gt; 是最简单的全等匹配，只有完全相等时才会匹配成功。在js中我用全等来查找花括号和圆括号，因为它们要参与计算深度（折叠功能）。&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;LinearSearch&lt;/span&gt; 线性查找，寻找以什么字符串为开头和结尾的内容。js中注释是以此实现的。注释是以/*开头*/结尾、或者//开头行末结尾。&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;LinearParse&lt;/span&gt; 线性分析和线性查找很像，只是它多了判断转义的逻辑，性能稍稍差一些。js中字符串是以此实现的。字符串以引号开始引号结束，但是结尾的引号可能存在转义的情况，字符串中也可能出现转义符，需要特殊对待。&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;IDMatch&lt;/span&gt; ID匹配和线性查找也有点相似，它定义了以什么字符串为开头，然后匹配一个正则表达式结果。js中并没有直接用到，但其实注释部分也可以用它来实现：以//为开头，匹配的正则表达式是//[^\n]*。至于为什么不用ID匹配来实现呢，那是因为正则的消耗比较大，为性能考虑才使用的线性查找。事实上只要是能用线性查找替换的地方，都应该这样做。&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;RegularMatch&lt;/span&gt; 看名字就知道这是终极解决方案了，和IDMatch的差异也只在于定义开头也是个正则。最消耗的方案。我根本没有用到它，放在那里有备无患而已。&lt;/p&gt;
&lt;h3&gt;ecmascript的示例&lt;/h3&gt;
&lt;p&gt;以下是用来解析js、as等语言的定义类文件：&lt;/p&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;package lexer.rule {
	/**
	 * ...
	 * @author army8735
	 */
	import lexer.*;
	import lexer.depth.*;
	import lexer.match.*;

	public class EcmascriptRule extends LanguageRule {

		public function EcmascriptRule() {
			var keywords:Array = &quot;if else for break case continue function true use \
switch default do while int float double long short char null public super in false \
abstract boolean Boolean byte class const debugger delete static void synchronized this import \
enum export extends final finally goto implements protected throw throws transient \
instanceof interface native new package private try typeof var volatile Vector with \
document window return Function String Date Array Object RegExp Event Math Number \
decodeURI decodeURIComponent encodeURI encodeURIComponent escape isFinite isNaN namespace \
isXMLName parseFloat parseInt trace uint unescape XML XMLList undefined Infinity NaN&quot;.split(&quot; &quot;);
			super(keywords, true);

			addMatch(new CompleteEqual(Token.DEPTH, &quot;{&quot;, LanguageLexer.IS_PERL_REG));
			addMatch(new CompleteEqual(Token.DEPTH, &quot;}&quot;, LanguageLexer.IS_PERL_REG));
			addMatch(new CompleteEqual(Token.DEPTH, &quot;[&quot;, LanguageLexer.IS_PERL_REG));
			addMatch(new CompleteEqual(Token.DEPTH, &quot;]&quot;, LanguageLexer.IS_PERL_REG));
			addMatch(new CompleteEqual(Token.DEPTH, &quot;(&quot;, LanguageLexer.IS_PERL_REG));
			addMatch(new CompleteEqual(Token.DEPTH, &quot;)&quot;, LanguageLexer.NOT_PERL_REG));
			addMatch(new LinearSearch(Token.COMMENT, &quot;//&quot;, &quot;\n&quot;, false));
			addMatch(new LinearSearch(Token.COMMENT, &quot;/*&quot;, &quot;*/&quot;, true));
			addMatch(new LinearParse(Token.STRING, &quot;'&quot;, &quot;'&quot;, true, LanguageLexer.IS_PERL_REG));
			addMatch(new LinearParse(Token.STRING, &quot;\&quot;&quot;, &quot;\&quot;&quot;, true, LanguageLexer.IS_PERL_REG));
			addMatch(new CharacterSet(Token.ID, [
				CharacterSet.LETTER,
				CharacterSet.UNDERLINE,
				CharacterSet.DOLLAR
			], [
				CharacterSet.LETTER,
				CharacterSet.UNDERLINE,
				CharacterSet.DOLLAR,
				CharacterSet.DIGIT
			], LanguageLexer.NOT_PERL_REG));

			addDep(new TokenDepth(Token.DEPTH, &quot;{&quot;, &quot;}&quot;));
			addDep(new TokenDepth(Token.DEPTH, &quot;[&quot;, &quot;]&quot;));
			addDep(new TokenDepth(Token.DEPTH, &quot;(&quot;, &quot;)&quot;));
		}

	}

}&lt;/pre&gt;
&lt;p&gt;super()构造函数的2个参数分别为保留字数组和语言本身是否支持Perl风格的正则表达式（perl风格的判别被直接集成在了父层解析器中）。&lt;/p&gt;
&lt;p&gt;可以看到下方一系列的addMatch()方法，它按照出现顺序来添加匹配模式并排序优先级，先出现的匹配模式具有高优先级。&lt;/p&gt;
&lt;p&gt;addDep()方法则是解析深度用的，有兴趣的可以看看——它也很容易被猜出来是怎么做的。&lt;/p&gt;
&lt;h3&gt;python的示例&lt;/h3&gt;
&lt;p&gt;python语言可能是比较特殊的例子了，因为它的深度折叠不是靠Token识别，而是看每行开始的空格？！我对python语法不大了解，所以简单搜索写了下，这也能体现出添加新语法文件方便多了的特性。&lt;/p&gt;
&lt;pre class=&quot;brush:as3&quot;&gt;package lexer.rule {
	/**
	 * ...
	 * @author army8735
	 */
	import lexer.*;
	import lexer.depth.*;
	import lexer.match.*;

	public class PythonRule extends LanguageRule {

		public function PythonRule() {
			var keywords:Array = &quot;and assert break class continue def del elif else \
except exec finally for from global if import in is lambda not or pass print raise \
return try yield while __import__ abs all any apply basestring bin bool buffer callable \
chr classmethod cmp coerce compile complex delattr dict dir divmod enumerate eval \
execfile file filter float format frozenset getattr globals hasattr hash help hex id \
input int intern isinstance issubclass iter len list locals long map max min next \
object oct open ord pow print property range raw_input reduce reload repr reversed \
round set setattr slice sorted staticmethod str sum super tuple type type unichr \
unicode vars xrange zip&quot;.split(&quot; &quot;);
			super(keywords, true);

			addMatch(new LinearSearch(Token.COMMENT, &quot;#&quot;, &quot;\n&quot;, false));
			addMatch(new LinearSearch(Token.STRING, &quot;'''&quot;, &quot;'''&quot;, true, LanguageLexer.IS_PERL_REG));
			addMatch(new LinearSearch(Token.STRING, '&quot;&quot;&quot;', '&quot;&quot;&quot;', true, LanguageLexer.IS_PERL_REG));
			addMatch(new LinearParse(Token.STRING, &quot;'&quot;, &quot;'&quot;, true, LanguageLexer.IS_PERL_REG));
			addMatch(new LinearParse(Token.STRING, &quot;\&quot;&quot;, &quot;\&quot;&quot;, true, LanguageLexer.IS_PERL_REG));
			addMatch(new CharacterSet(Token.ID, [
				CharacterSet.LETTER,
				CharacterSet.UNDERLINE
			], [
				CharacterSet.LETTER,
				CharacterSet.UNDERLINE,
				CharacterSet.DIGIT
			], LanguageLexer.NOT_PERL_REG));
		}

	}

}&lt;/pre&gt;
&lt;p&gt;python的深度解析直接内嵌集成了，所以没有出现addDep()。其中的疏漏欢迎指出。&lt;/p&gt;
&lt;p&gt;想要添加新的语法文件更加欢迎，即使不了解as或者flash的，你也只需告诉我组成规则即可，譬如：python代码的注释部分需要高亮，它由#开头到行末结尾；java的Word由字母下划线开头、字母下划线数字组成……&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668184/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668184/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/08/17/991.html/feed</wfw:commentRss><slash:comments>0</slash:comments><description>预览：http://jssc.googlecode.com/svn/trunk/jssc5/bin/index.html
下载：http://code.google.com/p/jssc/downloads/list
源码：http://jssc.googlecode.com/svn/trunk/jssc5/src/
好久不动，都生疏了。离上次5.1alpha版有好几个月了，今天释出beta版，添加了Python语法。
之前说过5.1版本最大的变动是使得添加新的语法变得更加容易，老的5.0版每个新语言都得写个词法分析器太累了，于是乎花大精力修改这一部分，添加了“匹配模式”类，用以方便添加新语法解析。
匹配模式的概念
简单地说，匹配模式就是描述某个语言基本词法单元（Token）的规则。以javascript举例，需要高亮的Token大致有注释、字符串、正则表达式、数字、关键字。其中关键字属于Word中的保留字。注释的匹配模式就是以/*开头*/结尾的代码、字符串是指引号之间的内容等等。
现有的几种匹配模式
所有匹配模式都实现IMatch接口，我目前定义了以下几种：CharacterSet、CompleteEqual、LinearSearch、LinearParse、IDMatch、RegularMatch。
CharacterSet 是个字符集匹配，它定义了Token以什么字符集为开头并以什么字符集为组成内容。比如js中的Word是以下划线、美元符号、字母为开头，下划线、美元符号、字母和数字为组成内容。出于初期设计的原因，字符集不能完全自定义，只能使用已经定义的若干常量。这个缺陷会在以后考虑。
CompleteEqual 是最简单的全等匹配，只有完全相等时才会匹配成功。在js中我用全等来查找花括号和圆括号，因为它们要参与计算深度（折叠功能）。
LinearSearch 线性查找，寻找以什么字符串为开头和结尾的内容。js中注释是以此实现的。注释是以/*开头*/结尾、或者//开头行末结尾。
LinearParse 线性分析和线性查找很像，只是它多了判断转义的逻辑，性能稍稍差一些。js中字符串是以此实现的。字符串以引号开始引号结束，但是结尾的引号可能存在转义的情况，字符串中也可能出现转义符，需要特殊对待。
IDMatch ID匹配和线性查找也有点相似，它定义了以什么字符串为开头，然后匹配一个正则表达式结果。js中并没有直接用到，但其实注释部分也可以用它来实现：以//为开头，匹配的正则表达式是//[^\n]*。至于为什么不用ID匹配来实现呢，那是因为正则的消耗比较大，为性能考虑才使用的线性查找。事实上只要是能用线性查找替换的地方，都应该这样做。
RegularMatch 看名字就知道这是终极解决方案了，和IDMatch的差异也只在于定义开头也是个正则。最消耗的方案。我根本没有用到它，放在那里有备无患而已。
ecmascript的示例
以下是用来解析js、as等语言的定义类文件：
package lexer.rule {
	/**
	 * ...
	 * @author army8735
	 */
	import lexer.*;
	import lexer.depth.*;
	import lexer.match.*;

	public class EcmascriptRule...&lt;img src=&quot;http://www1.feedsky.com/t1/580668184/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668184/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>jssc</category><category>jssc5</category><pubDate>Wed, 17 Aug 2011 17:59:47 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/08/17/991.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=991</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/08/17/991.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668184/5961215</fs:itemid></item><item><title>突然间看到刚毕业时写的web socket game</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668185/5961215/1/item.html</link><content:encoded>&lt;p&gt;&lt;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; width=&quot;336&quot; height=&quot;264&quot; codebase=&quot;http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0&quot;&gt;&lt;param name=&quot;src&quot; value=&quot;/wp-content/uploads/2011/03/fs.swf&quot; /&gt;&lt;embed type=&quot;application/x-shockwave-flash&quot; width=&quot;336&quot; height=&quot;264&quot; src=&quot;/wp-content/uploads/2011/03/fs.swf&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;&lt;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; width=&quot;240&quot; height=&quot;160&quot; codebase=&quot;http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0&quot;&gt;&lt;param name=&quot;src&quot; value=&quot;/wp-content/uploads/2011/03/test.swf&quot; /&gt;&lt;embed type=&quot;application/x-shockwave-flash&quot; width=&quot;240&quot; height=&quot;160&quot; src=&quot;/wp-content/uploads/2011/03/test.swf&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://army8735.org/wp-content/uploads/2011/03/temp-233.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-968&quot; title=&quot;temp-233&quot; src=&quot;http://army8735.org/wp-content/uploads/2011/03/temp-233.jpg&quot; alt=&quot;&quot; width=&quot;253&quot; height=&quot;176&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;感慨万千啊，mmorpg，聊天、任务、战斗……刚开始随即夭折，只保留有这2段视频和1张截图了。《Fantasy Sky》——纪念那些逝去的代码，还有青春。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668185/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668185/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/03/28/965.html/feed</wfw:commentRss><slash:comments>5</slash:comments><description>感慨万千啊，mmorpg，聊天、任务、战斗……刚开始随即夭折，只保留有这2段视频和1张截图了。《Fantasy Sky》——纪念那些逝去的代码，还有青春。&lt;img src=&quot;http://www1.feedsky.com/t1/580668185/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668185/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>其它</category><category>as、flex</category><pubDate>Mon, 28 Mar 2011 21:39:48 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/03/28/965.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=965</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/03/28/965.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668185/5961215</fs:itemid></item><item><title>jquery的html5form插件</title><link>http://item.feedsky.com/~feedsky/army8735/~8113855/580668186/5961215/1/item.html</link><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.matiasmancini.com.ar/jquery-plugin-ajax-form-validation-html5.html&quot; target=&quot;_blank&quot;&gt;http://www.matiasmancini.com.ar/jquery-plugin-ajax-form-validation-html5.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;前阵子在这个地址发现了jq的html5form插件，api设计得不错，功能上稍有欠缺，于是乎借鉴了思想重新写了一个：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://army8735.org/Ai/html5form.html&quot; target=&quot;_blank&quot;&gt;http://army8735.org/Ai/html5form.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;暂时提取了较为常用的html5表单属性做成了jq插件，样式自己先凑合的，如此可以节省和统一大量的重复校验和表现工作。那些错误以及提示信息均为新生成的绝对定位节点。&lt;/p&gt;
&lt;p&gt;input类型有：email、url、number、date、time、search、color几种类型，这些类型根据不同浏览器的支持表现各不相同。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;比如number在webkit下支持非常好，输入框尾部有微调按钮；&lt;/li&gt;
&lt;li&gt;color和date在opera下支持非常好，直接内置弹出一个选择框用鼠标点一下即可选择； 在不支持的比如ie下，它会默认解读为type=”text”，无任何影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;较为常用的属性有：placeholder、autofocus、novalid、required、pattern、maxlength。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;placeholder在chrome下支持最好，占位符和输入文字自动用2种颜色表示，其它的webkit用同一种颜色表示；&lt;/li&gt;
&lt;li&gt;autofocus也是chrome支持最好，ie等需模拟，多个autofocus将以最后一个为准；&lt;/li&gt;
&lt;li&gt;novalid指明这个表单无需验证便可提交；&lt;/li&gt;
&lt;li&gt;required表明这个input必须填写；&lt;/li&gt;
&lt;li&gt;pattern是自定义正则验证，比如示例中自定义的中文输入框，必须输入中文；&lt;/li&gt;
&lt;li&gt;maxlength指定最大输入文字长度，在webkit中超过了就无法输入（safari没校验输入法，chrome没校验回车），其它的不行。textarea上使用了这一属性，在输入时会自动提示长度；&lt;/li&gt;
&lt;li&gt;step、max、min等均为新特性，高级浏览器中会体现到，低级浏览器中不出现，渐进增强吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些属性可以组合起来使用，用firebug查看下源码，看看input上的属性即可理解。&lt;/p&gt;
&lt;p&gt;&amp;#8212;&lt;/p&gt;
&lt;p&gt;API： $(‘form’).html5form(callback);&lt;/p&gt;
&lt;p&gt;Callback: 一个回调function，可省略，在form的submit通过html5校验之后触发，this指向form本身，返回值为form.submit的返回值（return false阻止默认提交行为）。&lt;/p&gt;
&lt;p&gt;源码，还只是个雏形：&lt;/p&gt;
&lt;pre class=&quot;brush:js&quot;&gt;(function() {

	var body = $(document.body),
		PLACE_HOLDER_CLASS = 'td_placeholder',
		ERROR_CLASS = 'td_error',
		TIP_CLASS = 'td_tip',
		TYPE_VALID = {
			'url': {
				pattern: /^[a-zA-z]+:\/\/[^\s]*$/,
				message: 'url格式不合法'
			},
			'email': {
				pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
				message: 'email格式不合法'
			},
			'number': {
				pattern: /^\d+$/,
				message: '这不是一个数字'
			},
			'date': {
				pattern: /^\d{2,4}-\d{1,2}-\d{1,2}$/,
				message: '日期格式不合法'
			},
			'time': {
				pattern: /^\d{1,2}:\d{1,2}(:\d{1,2}(\.\d{1,3})?)?$/,
				message: '时间格式不合法'
			},
			'color': {
				pattern: /^#[a-z\d]{3,6}$/,
				message: '颜色格式不合法'
			}
		},
		tipBox,
		tpl = [
			'&amp;lt;table class=&quot;td_mesbox&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&amp;gt;&amp;lt;tbody&amp;gt;',
				'&amp;lt;tr&amp;gt;',
					'&amp;lt;td class=&quot;round left_top&quot;&amp;gt;&amp;lt;/td&amp;gt;',
					'&amp;lt;td class=&quot;line top&quot;&amp;gt;&amp;lt;/td&amp;gt;',
					'&amp;lt;td class=&quot;round right_top&quot;&amp;gt;&amp;lt;/td&amp;gt;',
				'&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;',
					'&amp;lt;td class=&quot;left&quot;&amp;gt;&amp;lt;/td&amp;gt;',
					'&amp;lt;td class=&quot;center&quot;&amp;gt;',
						'&amp;lt;div class=&quot;container&quot;&amp;gt;&amp;lt;%=text%&amp;gt;&amp;lt;/div&amp;gt;',
					'&amp;lt;/td&amp;gt;',
					'&amp;lt;td class=&quot;right&quot;&amp;gt;&amp;lt;/td&amp;gt;',
				'&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;',
					'&amp;lt;td class=&quot;round left_bottom&quot;&amp;gt;&amp;lt;/td&amp;gt;',
					'&amp;lt;td class=&quot;line bottom&quot;&amp;gt;&amp;lt;/td&amp;gt;',
					'&amp;lt;td class=&quot;round right_bottom&quot;&amp;gt;&amp;lt;/td&amp;gt;',
				'&amp;lt;/tr&amp;gt;',
			'&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;'
		].join('');

	function showError(node, message) {
		var s = $$.render(tpl, { text: message }),
			box = $('&amp;lt;div&amp;gt;').addClass(ERROR_CLASS).html(s).hide().appendTo(body),
			pos = getPos(node, box);
		//最初的坐标保存起来
		box.data('html5form_left', pos.left).data('html5form_top', pos.top);
		//以及对:input的引用
		box.data('html5form_node', node);
		//设置位置
		box.css({
			left: pos.left + 'px',
			top: pos.top + 'px'
		}).fadeIn(200).click(function() {
			node.focus().val(node.val());
		});
		shake(box);
		return box;
	}
	function hideError(box) {
		clearShake(box);
		box.remove();
	}
	function shake(box) {
		clearShake(box);
		var offset = 1,
			count = 0;
		//颤动动画存在自身的interval变量上
		box.data('html5form_interval', setInterval(function() {
			if(count++ &amp;gt; 10) {
				clearShake(box);
			}
			box.css({
				left: box.data('html5form_left') + offset + 'px',
				top: box.data('html5form_top') + offset + 'px'
			});
			offset *= -1;
		}, 50));
	}
	function clearShake(box) {
		var interval = box.data('html5form_interval');
		if(interval) {
			clearInterval(interval);
		}
	}
	function showTip(node, current, maxLength) {
		if(!tipBox) {
			var s = $$.render(tpl, { text: '' });
			tipBox = $('&amp;lt;div&amp;gt;').addClass(TIP_CLASS).html(s);
		}
		//focus时显示并设置位置
		if(node) {
			tipBox.hide().appendTo(body);
			var pos = getPos(node, tipBox);
			tipBox.css({
				left: pos.left + 'px',
				top: pos.top + 'px'
			}).fadeIn(200);
		}
		else {
			tipBox.show();
		}
		//更新说明
		current = current &amp;gt; maxLength ? '&amp;lt;strong&amp;gt;' + current + '&amp;lt;/strong&amp;gt;' : current;
		tipBox.find('div.container').html(current + ' / ' + maxLength);
	}
	function hideTip() {
		if(tipBox) {
			tipBox.hide();
		}
	}
	function getPos(node, box) {
		var left = node.offset().left + node.outerWidth() + 10,
			top = node.offset().top;
		//不够放在node后面的时候，放在前面，top暂不考虑，很少遇到
		if(left + box.outerWidth() &amp;gt; body.innerWidth()) {
			left = Math.max(1, node.offset().left - box.outerWidth() - 10);
		}
		return {
			left: left,
			top: top
		};
	}

	$.fn.html5form = function(cb) {
		this.each(function() {
			var form = $(this),
				novalidate = !$.isUndefined(form.attr('novalidate')),
				inputs = form.find(':input:visible:not(:button, :submit, :radio, :checkbox)'),
				input = document.createElement('input'),
				autofocus = 'autofocus' in input,
				placeholder = 'placeholder' in input,
				required = 'required' in input,
				maxlength = 'maxlength' in input,
				validArray = [];

			//有novalidate属性的话无需验证表单
			if(novalidate) {
				return;
			}

			inputs.each(function(index) {
				var item = $(this),
					type = (this.getAttribute('type') || '').toLowerCase(),
					interval;
				//placeholder占位符
				if(!placeholder &amp;amp;&amp;amp; this.getAttribute('placeholder') != null) {
					var ph = item.attr('placeholder'),
						place; //开关，标明input当前是否是占位符状态。
					//占位符为空字符串无效
					if(ph.length) {
						function focus() {
							//打开状态下认为是占位符
							if(place) {
								item.val('').removeClass(PLACE_HOLDER_CLASS);
							}
						}
						function blur() {
							//离开时如有输入数据开关关闭，否则打开
							if(item.val() == '') {
								item.val(ph).addClass(PLACE_HOLDER_CLASS);
								place = true;
							}
							else {
								place = false;
							}
						}
						item.focus(focus).blur(blur);
						//初始化判断，因为ie和ff会在刷新页面后可能autocomplete遗留表单数据，此时占位符就成为遗留的默认数据；也可能在js执行前有用户输入。唯一的缺点是假如在js执行前用户输入的和占位符相同，会被误认为占位符，可忽视。
						if(ph == item.val() || item.val() == '') {
							place = true;
							item.val(ph).addClass(PLACE_HOLDER_CLASS);
						}
					}
				}
				//maxlength
				var maxLength = parseInt(this.getAttribute('maxlength'));
				if(!isNaN(maxLength)) {
					function input() {
						showTip(null, item.val().length, maxLength);
					}
					item.focus(function() {
						if(!validArray[index]) {
							showTip(item, item.val().length, maxLength);
						}
					}).blur(function() {
						hideTip();
						var v = item.val().length;
						if(!validArray[index] &amp;amp;&amp;amp; v &amp;gt; maxLength) {
							validArray[index] = showError(item, '最多只允许输入&amp;lt;strong&amp;gt;' + maxLength + '&amp;lt;/strong&amp;gt;个字符');
						}
					});
					//input事件除了ie都支持，可以用onpropertychange代替
					if(window.addEventListener) {
						this.addEventListener('input', input, false);
					}
					else if(window.attachEvent) {
						this.attachEvent('onpropertychange', input);
					}
				}
				//autofocus自动聚焦
				if(!autofocus &amp;amp;&amp;amp; this.getAttribute('autofocus') != null) {
					item.focus();
				}
				//required
				if(this.getAttribute('required') != null) {
					item.blur(function() {
						if(validArray[index]) {
							shake(validArray[index]);
						}
						else if($.trim(item.val()) == '') {
							validArray[index] = showError(item, '此项必填');
						}
					});
				}

				//默认的校验
				var typeValid = TYPE_VALID[type];
				if(this.nodeName.toLowerCase() == 'input' &amp;amp;&amp;amp; typeValid) {
					item.blur(function() {
						if(validArray[index]) {
							shake(validArray[index]);
						}
						else {
							var v = item.val().trim();
							if(v.length &amp;amp;&amp;amp; !typeValid.pattern.test(v)) {
								validArray[index] = showError(item, typeValid.message || '格式不正确');
							}
						}
					});
				}
				//number类型另附验证范围
				if(type == 'number') {
					var max = parseFloat(item.attr('max')),
						min = parseFloat(item.attr('min'));
					if(!isNaN(max) || !isNaN(min)) {
						item.blur(function() {
							if(validArray[index]) {
								shake(validArray[index]);
							}
							else {
								var v = item.val().trim();
								if(v.length) {
									v = parseFloat(v);
									if(!isNaN(max) &amp;amp;&amp;amp; v &amp;gt; max) {
										validArray[index] = showError(item, '超出范围，不能大于' + max);
									}
									if(!isNaN(min) &amp;amp;&amp;amp; v &amp;lt; min) {
										validArray[index] = showError(item, '超出范围，不能小于' + max);
									}
								}
							}
						});
					}
				}
				//自定义pattern
				var pattern = this.getAttribute('pattern');
				if(pattern != null &amp;amp;&amp;amp; pattern.length) {
					pattern = new RegExp(pattern);
					item.blur(function() {
						if(validArray[index]) {
							shake(validArray[index]);
						}
						else {
							var v = item.val().trim();
							if(v.length &amp;amp;&amp;amp; !pattern.test(v)) {
								validArray[index] = showError(item, '格式不正确');
							}
						}
					});
				}

				//所有的:input输入时都要隐藏可能存在的错误提示框
				function removeErrorInput() {
					var error = validArray[index];
					if(error) {
						hideError(error);
						validArray[index] = null;
					}
				}
				if(window.addEventListener) {
					this.addEventListener('input', removeErrorInput, false);
				}
				else {
					this.attachEvent('onpropertychange', removeErrorInput);
				}
			});

			form.submit(function() {
				inputs.blur(); //全部触发可能存在的校验
				var validResult = true,
					first;
				validArray.forEach(function(item) {
					if(item) {
						validResult = false;
						shake(item);
						//focus到第一个错误:input
						if(!first) {
							first = true;
							item.data('html5form_node').focus();
						}
					}
				});
				//本身通过html5校验，如有传入callback，返回callback的值
				if(validResult &amp;amp;&amp;amp; $.isFunction(cb)) {
					validResult = cb.call(this) !== false;
				}
				return validResult;
			});
		});
		return this;
	}

})();&lt;/pre&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/580668186/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668186/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://army8735.org/2011/02/28/950.html/feed</wfw:commentRss><slash:comments>1</slash:comments><description>http://www.matiasmancini.com.ar/jquery-plugin-ajax-form-validation-html5.html
前阵子在这个地址发现了jq的html5form插件，api设计得不错，功能上稍有欠缺，于是乎借鉴了思想重新写了一个：
http://army8735.org/Ai/html5form.html
暂时提取了较为常用的html5表单属性做成了jq插件，样式自己先凑合的，如此可以节省和统一大量的重复校验和表现工作。那些错误以及提示信息均为新生成的绝对定位节点。
input类型有：email、url、number、date、time、search、color几种类型，这些类型根据不同浏览器的支持表现各不相同。

比如number在webkit下支持非常好，输入框尾部有微调按钮；
color和date在opera下支持非常好，直接内置弹出一个选择框用鼠标点一下即可选择； 在不支持的比如ie下，它会默认解读为type=”text”，无任何影响。

较为常用的属性有：placeholder、autofocus、novalid、required、pattern、maxlength。

placeholder在chrome下支持最好，占位符和输入文字自动用2种颜色表示，其它的webkit用同一种颜色表示；
autofocus也是chrome支持最好，ie等需模拟，多个autofocus将以最后一个为准；
novalid指明这个表单无需验证便可提交；
required表明这个input必须填写；
pattern是自定义正则验证，比如示例中自定义的中文输入框，必须输入中文；
maxlength指定最大输入文字长度，在webkit中超过了就无法输入（safari没校验输入法，chrome没校验回车），其它的不行。textarea上使用了这一属性，在输入时会自动提示长度；
step、max、min等均为新特性，高级浏览器中会体现到，低级浏览器中不出现，渐进增强吧。

这些属性可以组合起来使用，用firebug查看下源码，看看input上的属性即可理解。
&amp;#8212;
API： $(‘form’).html5form(callback);
Callback: 一个回调function，可省略，在form的submit通过html5校验之后触发，this指向form本身，返回值为form.submit的返回值（return false阻止默认提交行为）。
源码，还只是个雏形：
(function() {

	var body = $(document.body),
		PLACE_HOLDER_CLASS = 'td_placeholder',
		ERROR_CLASS = 'td_error',
		TIP_CLASS = 'td_tip',
		TYPE_VALID = {
			'url': {
				pattern: /^[a-zA-z]+:\/\/[^\s]*$/,
				message: 'url格式不合法'
			},
			'email':...&lt;img src=&quot;http://www1.feedsky.com/t1/580668186/army8735/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/army8735/~8113855/580668186/5961215/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>html5form</category><category>前端开发</category><category>jquery</category><pubDate>Mon, 28 Feb 2011 18:16:19 +0800</pubDate><author>army</author><comments>http://army8735.org/2011/02/28/950.html#comments</comments><guid isPermaLink="false">http://army8735.org/?p=950</guid><dc:creator>army</dc:creator><fs:srclink>http://army8735.org/2011/02/28/950.html</fs:srclink><fs:srcfeed>http://army8735.org/feed</fs:srcfeed><fs:itemid>feedsky/army8735/~8113855/580668186/5961215</fs:itemid></item></channel></rss>
