打造自己的reset.css

0,引言
每每有新项目,第一步就是应当使用一个reset.css来重置样式。滥用不如不用,直接拿个现成的reset.css过来将导致后期各种离奇bug的发生。所以最好还是自己写一个reset.css,并且要明白每一条reset都是用来做什么的。reset.css本意就是重置样式,我始终建议把.clearfix放入layout.css,而把h1、h2之类的定义放进typography.css。 具体如何规划网站CSS结构,不在文本讨论之列,可以参考Smashing Magazine上的文章,国内有差强人意的中文译版。注意,本文把reset分成了两个部分,一个是纯reset.css,可以用于任何项目。另一个是用于特定项目的“reset”,自定义修改的内容,这些内容可以放在layout.css、typography.css之类的文件中,他们共同导入到一个base.css形成一个项目的基础样式。本文就是来介绍如何写一个合适所有项目的通用的reset.css,以及介绍在设置玩reset.css之后需要针对不同项目要首先要设置的内容。

1,基础
牛顿是站在巨人伽利略的肩膀上的,我们也可以这么做。首先我们要选定一个前进的基础。
请永远不要使用

  1. * { margin: 0; padding: 0; }

这问题太多了,在此不多加表述。

目前比较流行的有Eric Meyer的重置样式和YUI的重置样式。另有Condensed Meyer Reset简化Eric Meyer的样式。有趣的是,Eric的重置样式也是源于YUI的。而那份简化版又把Eric的样式简化回YUI的样式了 。但同时,糟糕的是,网上流传的比较广的(尤其是国内)都不是最新的版本。上面两个页面里直接看到的都不是最新的,Eric专门为有一个reset.css页面。而YUI当前版本(2.7.0)的reset.css实际地址里,比上面的页面中还多一些东西。此外,我们还可以基于一些常见的框架,比较著名的比如Blueprint或者Elements CSS Framework(这个的reset也是源自于Eric Meyer的)。OK,准备工作就差不多了。以上这些都可以作为参考资料来组织我们自己的reset。我这里主要采用YUI,兼带Eric的reset。

2,默认色彩
对于页面是不是有默认背景色和前景色,YUI和Eric有着不同的看法。
YUI重置背景色为白色而文字颜色为黑色。

  1. html {
  2.     color: #000;
  3.     background: #FFF;
  4. }

而Eric在当前最新版中让所有颜色为透明,他认为透明才是最原始的颜色。虽然他曾一度认为也应当设置白色背景色、黑色文字颜色。至于最后为什么改了,Eric并没有给出具体理由。

这个问题我基本认为是用户自定义的更重要还是你的设计更重要的问题。我个人的观点是,如果你的设计本身就是白色背景,那么不要设置背景。一小部分中高水平的用户,他们会自定义网页默认背景色。设置成他们喜欢的背景色,比如浅蓝色。基本常见的浏览器都提供了这个简单的功能。而我们的背景色重置则会破坏用户的选择——尽管这样能保证你的设计原汁原味的呈现给所有用户。当然我知道,更高端的用户会用Stylish之类的Firefox扩展来自定义页面。但不得不说,只会用“选项”来调背景色的用户更多,不是么?而同时,如果设计本身就有其他背景色,比如黑色、蓝色、绿色之类的,OK,这些设计当然可以设置背景色。但请不要放进reset.css里。这里是重置样式的地方,不是你设计的地方。请把你的设计放在更广袤的土地上。
所以,简单说来,NO,不要在reset中设置背景色。

那么,文字颜色呢?原则上来说,也是不应该设置文字颜色的。但是IE中的表单元素中legend这个对象比较特别,跟主题结合的比较紧密。legend会默认有自己的颜色(跟当前的主题有关)而不会继承父元素的颜色(即便设了color:inherit;)。
从某些角度来说,可以想当然地认为设置字体颜色人数远小于设置背景色的人数;以及认为就算设置了背景色,人们看到legend元素是黑色的也不会觉得奇怪。因此,YUI在其reset中设置了legend {color: #000;}是无可厚非的。
但反过来说,把这个放到typography.css或者form.css里岂不是更好?不同的页面设计,其对legend的色彩要求很可能是不同的,放在reset.css里重复定义是没有必要的。因此这条CSS规则可以作为在reset.css之后首先应当设置的规则。

3,padding和margin
曾经一度流行的* { margin: 0; padding: 0; }也就是出于这个目的。让各个元素的padding和margin都归零,尤其是那些h1和p以及ul/ol/li之类的元素,还有,body本身也是有margin的。清除元素的padding和margin是很有用的。
YUI这样做:

  1. body, div, dl, dt, dd, ul, ol, li,
  2. h1, h2, h3, h4, h5, h6, pre, code,
  3. form, fieldset, legend, input, button,
  4. textarea, p, blockquote, th, td {
  5.     margin: 0;
  6.     padding: 0;
  7. }

而Eric这样做:

  1. html, body, div, span, applet, object, iframe,
  2. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  3. a, abbr, acronym, address, big, cite, code,
  4. del, dfn, em, font, img, ins, kbd, q, s, samp,
  5. small, strike, strong, sub, sup, tt, var,
  6. b, u, i, center,
  7. dl, dt, dd, ol, ul, li,
  8. fieldset, form, label, legend,
  9. table, caption, tbody, tfoot, thead, tr, th, td {
  10.     margin: 0;
  11.     padding: 0;
  12.     border: 0;
  13.     outline: 0;
  14.     font-size: 100%;
  15.     vertical-align: baseline;
  16.     background: transparent;
  17. }

可以看到,Eric把几乎所有的元素都写上了规则。而YUI只把有padding和margin的元素清空样式,而其他元素则不动。我个人比较偏好YUI的做法,因为他这样可以避免给一些无关元素带上不必要的样式。导致元素过多时的性能下降。但Eric的也有可取之处,他这样写,整个reset.css可以小上不少字节,对服务器的压力会小一些。但进一步想,这种做法跟用 * 来选择所有元素还有什么区别呢?这已经几乎囊括了所有元素了!你怎么用呢?看你自己喜好了。

4,边框
YUI里:

  1. fieldset, img {
  2.     border: 0;
  3. }
  4. abbr, acronym {
  5.     border: 0;
  6.     font-variant: normal;
  7. }

Eric已经在上一条中把所有的边框都清掉了,还是推荐用YUI的,理由同上。

5,外边框(outline)
这个就是元素获取焦点时的虚线框,在ie之外的浏览器上可以像下面Eric做的那样,通过设置outline来消除。

  1. /* remember to define focus styles! */
  2. :focus {
  3.     outline: 0;
  4. }

而YUI则没有设置这一条。而在Eric的样式中,可以看到Eric的提醒:务必重新定义获取焦点后的样式!
这点其实很重要,出于可访问性的角度出发,那些不便于使用鼠标的人基本上都是用tab导航来浏览网页的。获取焦点的元素有特定样式的话可以极大帮助这类群体的用户,通常建议设置成跟:hover一样。经常设计上会因为这个虚线框而大打折扣。因此这条保留在reset中,并且作为reset.css之后及早定义的规则。

另外,对于在Firefox之类的支持outline的浏览其中,除了获取焦点的元素外,浏览器本身并没有给元素设置outline属性,所以,像Eric那样把所有元素的outline设成0,我就觉得没有太大必要了。

6,字体样式(font style/weight/size/variant)
YUI里,分成了多条:

  1. address, caption, cite, code, dfn,
  2. em, strong, th, var, optgroup {
  3.     font-style: inherit;
  4.     font-weight: inherit;
  5. }
  6.  
  7. h1, h2, h3, h4, h5, h6 {
  8.     font-size: 100%;
  9.     font-weight: normal;
  10. }
  11. abbr, acronym {
  12.     border: 0;
  13.     font-variant: normal;
  14. }
  15.  
  16. input, button, textarea,
  17. select, optgroup, option {
  18.     font-family: inherit;
  19.     font-size: inherit;
  20.     font-style: inherit;
  21.     font-weight: inherit;
  22. }
  23.  
  24. /*@purpose To enable resizing for IE */
  25. /*@branch For IE6-Win, IE7-Win */
  26. input, button, textarea, select {
  27.     *font-size: 100%;
  28. }

Eric则在他最终版的reset中去掉了关于这些的样式重置,只保留了 font-size: 100%; 同样他没有给出具体理由。
但通常情况下,我认为还是重置一下这些样式好,比如strong元素,很多时候只是语义而已,并非希望他真的加粗。可能会有背景色或者其他方式来强调。而之所以这里都用了inherit这个继承属性而不是定义 font-weight: normal; 可以在 Eric 先前的reset文章中看到。这是为了防止——父元素字体加粗了,而没有一个子元素继承加粗属性(因为设置了normal)——这种情况的发生。所以把YUI中设置h1-h6的样式以及abbr和acronym的两句样式都改成inherit会比较好。

此外,对于h1-h6的字体大小定义,建议放到专门的typography.css里,不建议放在reset.css里。所以这里我同样倾向于用YUI的策略,全部重置。

但是很不幸,在ie6/ie7当中,不论是strong还是h1-h6,亦或是em等元素,设置了inherit均无法继承父元素属性,依然保持自己的特色。这就带来了浏览器差异,样式重置本身是为了避免浏览器差异的,但现在带来了浏览器差异,是万万不可取的。对于这个问题我考虑了很久,到底是为了统一所有浏览器都重置成normal(YUI的想法),还是放弃重置这些元素,让他们顺其自然,来保证在所有浏览器中样式一样(Eric的想法)。我最后决定采用YUI的做法。因为,无论重置成normal还是不重置,这些元素都无法继承父元素属性。既然如此,那么退而求其次,保证这些元素都恢复到普通外观,避免在设计的时候还要重置样式。
不得不说,这种妥协是仅仅针对IE6和IE7的,也许在5年后,老板和客户都不要求支持IE7的时候,我们可以放心大胆得使用inherit了。

此外,YUI并没有给code kbd samp tt 这几个元素重置字体大小。但实际上在IE中,他们都会被缩小显示。所以此处应当给予重置font-size: 100%;

7,行高(line-height)
对于行高,YUI并没有给出重置定义,而Eric则给出了重置:

  1. body {
  2.     line-height: 1;
  3. }

行高默认所有元素都会继承的,所以给body设置行高为1就足够了。通常行高设为1时候,英文照常阅读,但中文就无法阅读了,行间距过于紧密导致容易看错行。通常在中文环境下得设置1.4到1.5才能是用户正常阅读。我建议是1.5,这样算出来的值也是整数。比如字体大小12px的时候行高是18px,字体大小16px时行高24px。看起来也会比较舒服。此外,还有一个不设置成1的重要原因是:IE下,行高为1时,中文字顶部会被削掉几像素,字体加粗时尤为明显。所以,重置的原则是好的,但切不可重置为1。

8,列表样式
YUI用了:

  1. li {
  2.     list-style: none;
  3. }

Eric用了:

  1. ol, ul {
  2.     list-style: none;
  3. }

尽管我没有测试出YUI的有什么问题,但我始终觉得设置ol和ul会比较稳妥。而且,波及的元素更少,性能应该更高一点。虽然下载量会多3字节。

9,表格元素
在表格方面,都比较统一。均是:

  1. /* tables still need 'cellspacing="0"' in the markup */
  2. table {
  3.     border-collapse: collapse;
  4.     border-spacing: 0;
  5. }

Eric还提醒到,需要在html中设置cellspacing="0″ 来达到完美重置效果。
但此外YUI还设置了

  1. caption, th {
  2.     text-align: left;
  3. }

让caption和th元素不要居中。作为重置,是可取的。建议添加此规则。

10,上下标以及baseline
YUI写成

  1. sup {
  2.     vertical-align: baseline;
  3. }
  4.  
  5. sub {
  6.     vertical-align: baseline;
  7. }

似乎没有优化,不知道为何没有写到一起去。而Eric则在最开始那条中就已经定义。而其中的问题是,YUI这样定义了,但没有重置字体大小,这点是有所遗憾的。既然是重置样式,就彻底一些,所以建议改成这样的:

  1. sup, sub {
  2.     font-size: 100%;
  3.     vertical-align: baseline;
  4. }

同样对于Eric把所有元素都放到了Baseline上,包括上标下标。Eric的解释是,强制让设计师精确定位这些元素的垂直偏移。

11,插入和删除(ins/del)
对于这个问题,YUI直接清除了ins的下划线和del的删除线这两个文本装饰:

  1. del, ins {
  2.     text-decoration: none;
  3. }

而Eric保留了删除线:

  1. /* remember to highlight inserts somehow! */
  2. ins {
  3.     text-decoration: none;
  4. }
  5. del {
  6.     text-decoration: line-through;
  7. }

如何取舍?我选择Eric的,为什么我这里不追求完美的样式重置了呢?很简单,我这个reset的目标是为了让我们写页面的时候尽量避免浏览器默认样式,以及不同浏览器之间默认样式差异带来的问题。而del元素删除线的文本装饰,我相信没有人会反对的。有人会加上其他样式,比如字体变淡之类的,但对于del如此强语义的元素来说,没有什么比用删除线更能表达含义的了。而不像上面那个focus样式,未必人人喜欢虚线框。但似乎又没有什么浏览器默认不给del元素加删除线,故这条可以省略。
所以,这里我只重置ins样式,别忘了给ins元素在等下也添加一些样式。

12,引用元素的引号
某些浏览器中,q或者blockquote前后会出现引号。这个并不是谁都喜欢的。所以需要重置他。
YUI的比较简单,只重置了q:

  1. q:before,
  2. q:after {
  3.     content: '';
  4. }

而Eric则比较周到,把q和blockquote都重置了。

  1. blockquote, q {
  2.     quotes: none;
  3. }
  4. blockquote:before, blockquote:after,
  5. q:before, q:after {
  6.     content: '';
  7.     content: none;
  8. }

OK,就决定用Eric的了,对于样式重置,细致一点周到一点总没有错。

13,链接
对于链接,YUI和Eric都没有采取样式重置,但从我思考许久后还是决定把链接样式重置放进来。究其原因,还是因为样式重置一来要彻底,二来对于链接样式并非所有设计师都喜欢用下划线装饰。因此,我还是建议把链接的下划线重置掉。

  1. a {
  2.     text-decoration: none;
  3. }

但这样做有点粗糙。真正有下划线样式的其实只有 :link和:visited所以改成下面这样比较好:

  1. :link, :visited {
  2.     text-decoration: none;
  3. }

此外,对于链接颜色,可以作为reset后急需设置的规则来处理。直接放入reset.css中不是很合适。

14,我的重置样式
总结上面种种规则,这里给出一下我的CSS重置规则,BSD协议发布,请随意使用。测试样本(这个是从YUI那里复制过来的,感谢YUI为此做出的贡献。)
下载:reset.css reset-min.css

  1. /*
  2. Copyright (c) 2009, Shawphy(shawphy.com). All rights reserved.
  3. http://shawphy.com/2009/03/my-own-reset-css.html
  4. Based on YUI http://developer.yahoo.com/yui/reset/
  5. and Eric Meyer http://meyerweb.com/eric/tools/css/reset/index.html 
  6. Licensed under the BSD License:
  7. http://creativecommons.org/licenses/BSD/
  8. version: 1.1 | 20090303
  9. */
  10.  
  11. body, div, dl, dt, dd, ul, ol, li,
  12. h1, h2, h3, h4, h5, h6, pre, code,
  13. form, fieldset, legend, input, button,
  14. textarea, p, blockquote, th, td {
  15.     margin: 0;
  16.     padding: 0;
  17. }
  18. fieldset, img {
  19.     border: 0;
  20. }
  21. /* remember to define focus styles! */
  22. :focus {
  23.     outline: 0;
  24. }
  25. address, caption, cite, code, dfn,
  26. em, strong, th, var, optgroup {
  27.     font-style: normal;
  28.     font-weight: normal;
  29. }
  30.  
  31. h1, h2, h3, h4, h5, h6 {
  32.     font-size: 100%;
  33.     font-weight: normal;
  34. }
  35. abbr, acronym {
  36.     border: 0;
  37.     font-variant: normal;
  38. }
  39.  
  40. input, button, textarea,
  41. select, optgroup, option {
  42.     font-family: inherit;
  43.     font-size: inherit;
  44.     font-style: inherit;
  45.     font-weight: inherit;
  46. }
  47. code, kbd, samp, tt {
  48.     font-size: 100%;
  49. }
  50. /*@purpose To enable resizing for IE */
  51. /*@branch For IE6-Win, IE7-Win */
  52. input, button, textarea, select {
  53.     *font-size: 100%;
  54. }
  55. body {
  56.     line-height: 1.5;
  57. }
  58. ol, ul {
  59.     list-style: none;
  60. }
  61. /* tables still need 'cellspacing="0"' in the markup */
  62. table {
  63.     border-collapse: collapse;
  64.     border-spacing: 0;
  65. }
  66. caption, th {
  67.     text-align: left;
  68. }
  69. sup, sub {
  70.     font-size: 100%;
  71.     vertical-align: baseline;
  72. }
  73. /* remember to highlight anchors and inserts somehow! */
  74. :link, :visited , ins {
  75.     text-decoration: none;
  76. }
  77. blockquote, q {
  78.     quotes: none;
  79. }
  80. blockquote:before, blockquote:after,
  81. q:before, q:after {
  82.     content: '';
  83.     content: none;
  84. }

15,完成一个初步的CSS框架
之前提到了,样式重置作为一个所有项目可以使用的共性存在,而不同的项目应当有其个性。当然还有其他一些共性,不属于样式重置的部分,但同样重要。再往下讲就可以做一个CSS框架了。CSS框架所要考虑的内容远比一个CSS Reset要考虑的多很多,这里只是点到为止,不做更多展开。

layout.css
首先除了reset.css之外要建立的layout.css,这里目前主要推荐放入.clearfix。清除浮动很重要。但这不属于样式重置,放在布局当中正合适。

  1. .clearfix:after { 
  2.     content: ".";
  3.     display: block;
  4.     height: 0;
  5.     clear: both;
  6.     visibility: hidden;
  7. }
  8. .clearfix {display: inline-block;}
  9.  
  10. /* Hides from IE-mac \*/
  11. * html .clearfix {height: 1%;} 
  12. .clearfix {display: block;} 
  13. /* End hide from IE-mac */

此外,layout.css中还可以放入自己常用的布局,比如 #wrap{margin:0 auto;width:960px;}之类的规则。看个人喜好而定。

typography.css
这里可以放置很多规则,非常重要的是以下三个:
:focus, a, ins
这三个是被重置掉的,但又很重要的内容,建议在reset之后立即在typography中设定全站样式,保持样式统一。
ins可以单独设置, :focus 最好设置成跟 :hover一样,而a的样式还是按照LoVe,HAte的法则来设置。

h1-h6系列也是之前被重置掉的。可以考虑在这里设置样式。按站点特性来定。我个人是不喜欢全局定义hx系列的字体大小的,统一为100%我觉得挺好。

接下来要设置的是font-family属性,可以参考射雕的文章。另外,小麦的文章中提到,表单元素的字体在IE中都不能继承父元素的字体,所以要单独设置。

至于其他需要全局设置的,可以参考前文中的叙述,找到相应的部分添加到typography.css中即可。这样就可以在保证reset.css通用性的情况下,使不同的项目又有个性。尽量保证reset.css在所有项目中都是一样的。有利于项目的开发。最后不要忘记在写表格的时候加cellspacing="0″ 来达到完美重置效果。

16,探讨
文章写的比较仓促,也受限与本人能力所限,只能写到这里。欢迎留言探讨,也可发邮件或上Twitter找我。以便进一步完善这个reset。谢谢。

Posted in CSS | 45 Comments

限定字符长度,截断中文字符

今日遇到个麻烦事。input限定输入字节数是8,中文自然算两个字节。本来一路顺利,keyup keydown keypress事件挨个试过去,把中文用正则替换成两个英文字符,超过8的就return false。ie下表现超级完美。
这个时侯Firefox下麻烦事就开始了,ie下,中文输入法状态下他也是能捕获键盘事件的。但ff下却无法捕获输入法状态下的键盘事件,比如我搜狗,他只能识别到最后那次空格……一恼火,干脆换条思路,直接截断字符来解决。效果感觉还行,总比没有好,此方法也适用于复制进去的文本。

  1. $("input").bind("keyup",function() {
  2.     var str=this.value;
  3.     while (str.replace(/[^\x00-\xFF]/g,"aa").length>8) {
  4.         str=str.substr(0,str.length-1);
  5.     }
  6.     this.value=str;
  7. });

代码很简单,也很安全。想封装成其他形式请自便。

我这里用的是减法,对于input这种很合适。因为不会多出去很多字符的。
这里我事后搜到一个做加法的,也不错,可以参考一下。只是不建议像他这样直接给原生对象做扩展,容易冲突。放到自己的私有对象下会比较好。

Posted in jQuery | 7 Comments

我又回来啦

经历了一系列的波折,我的博客又开咯。考虑了半天,还是放在国外安全。就算被墙了,我的数据还能翻墙捞回来。国内就难说了。不想多提了。谨以此悼念……

应Ben所求,我放上博客服务器提供商 WOPUS IDC
国内有不少博客都是用他的,我是从 saywp.com这里看来的。
服务挺好的,速度也挺快。算是拿人手短吃人嘴短地推荐一下吧。

=============
Update
大概在09年7月左右,由于发现这个速度也比较慢,所以我后来就直接去Hostmonster买了空间,不再通过国内的代理商了。
我也建议有信用卡的同学直接去美国找服务商,而不要找中间代理商。毕竟中间隔了一层会比较麻烦一点。

Posted in 本站动态 | 8 Comments

侧边栏的twitter

最近开始用twitter了(彻底放弃饭否,用饭否的同学别伤心啊~),顺便在侧边栏放了一个用于显示tw更新的小面板~常来看的同学可能已经发现了侧边栏的小变化了~~(哦?你是订RSS的?非常支持!那麻烦你点一下本文链接就能看到啦,哈)

跑到 http://twitter.com/badges一路next后得到了一串代码

  1. <div id="twitter_div">
  2. <h2 class="sidebar-title">Twitter Updates</h2>
  3. <ul id="twitter_update_list"></ul>
  4. <a href="http://twitter.com/Shawphy" id="twitter-link" style="display:block;text-align:right;">follow me on Twitter</a>
  5. </div>
  6. <script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
  7. <script type="text/javascript" src="http://twitter.com/statuses/user_timeline/Shawphy.json?callback=twitterCallback2&amp;count=5"></script>

到wp后台建了两个小文本,一个用于存放上面的ul,另一个用于放js,由于twitter的js加载速度实在糟糕,我不得不分开放,把js放在侧边栏最底下的地方,这样好不影响页面加载。(其实还是影响到了footer,但我都不在乎,你在乎么? XD)

ok,你玩twitter么?玩的话follow me~

Posted in jQuery | 9 Comments

jQuery 1.2.6和jQuery 1.3.1的特殊字符选择器极限测试

心血来潮,把键盘上能按出来的特殊字符都按了个遍
依次是:
~`!@#$%^&*()_+{}|":?><,./;'[]\
其中<和"不能放到id里,页面显示不全之外其他都可以哦~
分别放在中间,结尾和开头,比如te[st、te[、[st这种。
好孩子不要学哦~
W3C规定

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

ID和NAME必须由字母([A-Za-z]) 开头,之后可以跟任意数量的字母、数字([0-9])、短横("-")、下划线("_")、冒号(":")和点(".")。

实验结果表明,jQuery 1.3.1的选择器对于这些BT的特殊字符没有jQuery 1.2.6强劲,jQuery 1.2.6基本上是getElementById能搞定的他都能搞定,而1.3.1中的Sizzle选择器却没这么强悍,当然这纯属测试而已,同时提醒各位同学,一定要尊崇标准啊……不要随便乱来……我知道某些会输出诸如foo[bar]之类的ID,不可取啊,不符合标准的啊……虽然#foo\\[bar\\]是能成功匹配的,但#foo\\[bar就不行。总之注意别用这些离奇的符号做ID就差不多不会有问题了。

测试页面在这里:
http://shawphy.com/demo/selector/jQuery-1-2-6-selector-test.html
http://shawphy.com/demo/selector/jQuery-1-3-1-selector-test.html

测试结果,
1.2.6:三个失败

te\st
te\
\st

1.3.1:一坨……

te~st
te(st
te+st
te[st
te\st
te>st
te,st
te~
te(
te+
te[
te\
te>
te,
~st
(st
+st
[st
\st
>st
,st
================
dev maillist发了邮件,John大回复说似乎可以解决,期待一下吧。

Posted in jQuery | 3 Comments

jQuery 中文文档XML版以及CHM版发布

我相信很多人在等待CHM版的发布。
这次发布采用了XML版生成分散的文件。由于花了点时间在原先的HTML转XML上,以及一揪回家等因素,这次的CHM版姗姗来迟。但值得庆祝的是,以后的CHM版会很轻松地发布~

如果有兴趣看我如何把jQuery文档从HTML转成XML的,可以看这个jqapi2xml
需要Firefox 1.5以上或者使用Mozilla Gecko 1.8以上引擎的浏览器或者其他直接支持E4X的浏览器才能使用。

新的XML版文档可以点击查看XML版。我简单写了一个XSL。其他同学如果有需要可以自行拿这个XML写其他的XSL。
这里是英文的XML版文档。使用了同一个XSL,只是语言不同而已。可以发现这回不再是双语版了,对双语版有爱的同学我只能说对不起了,由于精力有限,无法同时维护中文版以及双语版中的英文部分。如果实在有爱,可以写脚本把上述英文版XML中说明加入中文的XML之中,并自行修改XSL。

最后,CHM版可以直接从Google Code下载:
http://code.google.com/p/jquery-api-zh-cn/downloads/list

CHM版和XML版均提供查找更新功能~
HTML版今日(2009-1-29)发布最后一版,增加2个函数以及修正些小问题。也可以从上面的地址下载。以后不再更新,请同学将收藏夹中的地址改成上述的XML版地址。

另,据测试下来,可能有些同学会出现点击任何页面都出现下载的情况。如果这样请先使用HTML版。如果情况比较多,下一版将会采用XML+XSLT转HTML后再编译成CHM格式。据网友汇报,确认下HKEY_CLASSES_ROOT\.xml 下的Content Type是否是text/xml 再试试找到文件夹选项,文件类型里的XML处,点"还原",可以解决这个问题

Posted in jQuery | 18 Comments

关于jQuery xml版英文文档的一些事

其实去年年底,jQuery 1.3尚未发布的时候就已经盘算着将中文文档以xml的形式发布了。这样有个好处,就是页面结构可以用xsl随便换。各位同学想做不同的发行版可以随便换着玩~实际上我现在愈发觉得css的局限性了,很多时候所谓的css为了后期维护方便,可以任意修改布局而无需动页面结构之类的话语已经觉得难以置信了。我就不信有多少同学遇到过改版的时候只改css而不改html的。当然也有可能是我的局限性而非css的局限性。

所谓的圣杯布局双飞翼布局确实在很大程度上能解决布局(Layout)上的问题,但别忘了,开发工作可不只是布局,还有排版(Typography),数据结构和页面表现结构交织在一起的时候,想崩溃都觉得老板会从地域里拖你起来。

xml+xslt这种手段其实我几年前就看到过,当时也曾为之心动,无奈当时技术水平有限无法体会其中精妙。然借此jQuery 1.3文档大改之际便又萌发了尝试的冲动。

xml+xslt好吗?很好!居然ie 5就开始支持了,ie 6支持的程度也很不错,基本上没有遇到什么兼容性问题,比起万恶的ie6对css的支持度好多了。目前我除了发现document()函数在ie中表现的跟其他浏览器不一致之外,以及Firefox居然不支持disable-output-escaping="yes",并且争论长达7年多尚未有解决的迹象。除此之外似乎没发现更多问题。

实际上让一部分处理页面的逻辑放到了前端来做,后台只负责输出数据,这种数据(XML),结构(XSLT),表现(CSS),行为(JS)4者相对分离的状态是十分有利于这个前端产业工业化发展的。随着前端工种的进一步细分,我觉得这里大有可挖。好处显而易见,如果要大面积改版(即便是小范围),由于后台只负责输出数据而没有HTML格式,高度分离的情况下,基本上只需要前端小组改一下即可。即便是对后台语言完全不了解都可以(我承认这不好)。
此外,xslt支持include/import等语句,包括上面提到的document(),可以很方便的实现页面各个部分的模块化。

但随之带来的问题也显而易见,数据过于结构化,页面内容轻易被人抓取而后分析(都不用分析……直接解析……)
此外,很多pda,手机之类的可能对xslt无法解析,但我估计屏幕阅读器应该没问题,因为很多屏幕阅读器都是基于现有浏览器的,也就是说现有浏览器支持,他也就支持。
还有上面提到的模块化问题,一不小心就可能导致连接数过多。每个模块的粒度得把握好。

解决这些问题的一个简单途径是,xml+xslt在服务器端解析生成。服务器端可以通过检测浏览器来判断直接输出xml+xslt还是输出生成的页面。这对于pda和手机之类的能提高很大兼容性。而对于一般浏览器又无需消耗服务器资源。
网上有篇流传甚广的文章XML在B/S架构开发中的应用,正是描述了此类情景。我考据下来可能是原著地址(我找到个更早的地址但上面的写的作者也是他,请宽恕我的网络考古情结)。

其中也提到了http://xml.apache.org/cocoon/ 似乎可以直接使用,没深究。

好了,得回到正题了。jQuer现在弄了个专门是放api的地址:http://api.jquery.com。说实话,我一直很不喜欢他现在弄的样子,当我需要在不同的方法之间切换的时候很不方便。有喜欢的可以自己尝试。另外,分析代码发现原来这个api也是从wiki里扣出来的xml进行解析得来的。另有air版,喜欢的可以自己下。扣的程序是Python 2.4写的,遗憾我这里只有Py3k环境,执行失败,且自己道行过浅,无法改成3.0版以供自己用。忘有此能力的同学能帮我改一下,可直接从jq的svn里拿到,点击下载。没有达人帮忙其实也没事,见到还有地址可以在线生成,前面在线生成的地址如果不加参数则可以直接查看这个生成器的文档。用urllib.request.urlretrieve(url,path)直接下载真的是很惬意的事情,Python真的是很强悍啊……
我随便写了个xslt,可以直接浏览jQuery 的英文文档。暂不提供下载,喜欢的就自己另存为吧……不喜欢的就自己写一套吧……
暂时计划是将中文文档转换成xml(这步已经在前天完成,转的我残念……请原谅我能力有限只能用这么离奇的办法转格式……)。不过之前写这个的时候还没有看到上面那个wiki2xml生成器(其实早就见过了,被我无视了而已……),所以对应的标签以及格式还不是很对上号。改天整整。另外,单个xml拆分成散件的xml的py脚本也写完了,实验成功,现在生成chm版的文档只差单文件xml的校对和chm文件的目录以及索引之类的编辑工作了。不用太期待……一揪回家了……新年饭局又多……饿……大半夜的吐槽可真不好……睡去了……

Posted in jQuery | 5 Comments

我为什么使用Google CDN

自从之前jQuery 1.3版起,就已经没有提供pack版了,而我也十分赞成使用Google CDN进行代码托管。

这样做有以下几个好处:
1,更小下载量。
都知道jQuery 1.3 pack后有38k之多,如果当然可以删除版权注释以获得更小的代码,遗憾的是这不仅无耻且只节约1个k都不到。而同样利用Google APIs 提供的GZip过的Min版,只有18k,对用户来说下载量更小。

2,减轻服务器压力。
虽然现代浏览器都有了缓存,但以前我看到过资料说某大型网站发现他们70%的访客缓存都是空的(哪位同学能帮忙找到资料请下面留言,不胜感激~)。所以,让Google为我们提供服务,而不用自己操心自己的流量~少个库可以少个连接数,何乐而不为。

3,多个网站共享缓存。

如果用户访问的多家网站都使用Google提供的jQuery,那么对于用户来说,只需要缓存一次后即可只读取缓存中的数据!而不是每个网站都要重新下载一份。对此进一步加快用户访问速度。

4,更快执行速度。
jQuery 1.3.1发布的发布信息中,为jQuery不提供pack版给出了官方的解释。除了不易debug,在Adobe AIR和Caja-capable等环境下无法使用之外,更重要的是因为执行速度问题。随着jQuery逐渐变“胖”,用pack压缩后在浏览器端“解压缩”所需要的资源越来越大。想象一个超大的字符串多次replace后再eval的情景……这不比直接读取一个不需要解压缩的min版来得快。John给出了一些数据,有兴趣的同学可以看看。

反对的声音:
“不安全”、“没安全感”、“放别人的机器太危险了”、“他们服务器倒了呢?”、“以前刚开始的时候就down过”

我认为(晕……怎么我觉得我在写四六级作文……)Google服务器down的几率与我们自己服务器down的几率不会有显著性差异(抱歉,我又空口无凭说话了……不过如果哪位同学能给出数据来拒绝我的零假设,认可备选假设的,欢迎提供,再次不胜感激~)。所以就放他们那边吧,挺安全的。

另外我还听到关于不能让整个世界为着Google转,Google阴谋论,Google威胁论的声音。实际上Google确实正朝这个方向发展,让整个互联网围着他转。可以看他提供的一些服务,什么云计算,什么App Engine之类的,都企图让人们的应用都建立在Google至上,当Google成为了空气的时候,他已经无处不在了。这点来说,值得担忧。

Posted in jQuery | 15 Comments

万恶的弹窗广告

或许是我孤陋寡闻,但我在国内第一次看到弹窗的复兴是从淘宝开始的。在各大浏览器纷纷将未经用户交互而弹出的广告封杀的时候,淘宝采用了给document绑定click事件的方式调用window.open来弹出广告。

当然,淘宝还算文明,弹窗放到了后头,并且似乎一天只弹一次。我这里也不是为了谴责淘宝的前端们,也能理解他们也实属无奈。

自从那时起,神州大地便四处开花。各个网站的站长似乎找到了救命稻草,弹窗广告又活了!大有“我胡汉三又回来啦”的气势。我见过最离谱的是直接给document的mousemove事件帮上弹窗广告,你鼠标只要移到页面内就会弹窗!而不像淘宝那样等你点击了才弹窗。

注意,我写此文的并非告诉各位同学新式弹窗的秘诀。相信各位同学也都是非常反感弹窗的。如果哪位擅自将上述秘籍用于实际项目必将遭受广大群众的谴责!请三思。

此问真正的缘由是:近日我经常光顾一些垃圾站点,弹窗之猖獗实属罕见,一怒之下写了脚本将window.open劫持,看谁还敢弹广告~嗯哼~

Continue reading

Posted in jQuery | 8 Comments

jQuery 1.3 升级指南

jQuery 1.3提供了很多新特性,不少同学也纷纷更新到了jQuery 1.3,也有同学升级后发现有些功能失效了。这里就简单写一下jQuery 1.3的升级指南。如果这里没有提到的而你却遇到了并且解决了,欢迎留言告诉更多人。如果没,所好能写个简单测试样例以说明问题。

这里不涉及任何新增特性,只有关于修改过的内容。要看新增特性,请参考这里

翻译了通篇文档,主要发现以下几点容易导致升级失败:

1,取消了属性选择器的@前导符号。这点会造成升级失败。虽然这个@符号在jQuery 1.2中已经不推荐使用了,但由于种种历史原因还是有很多人用。修复这个问题的方法很简单,只需要简单删除那个@符号即可。

2,trigger()方法触发的事件会冒泡了。这点可能在某些重要的功能上发生偏差。尤其是一些大项目上。要解决这个问题,需要在事件处理函数里加上e.stopPropagation() 或者函数返回false即可。

3,这点实际上并没有在发布信息中提到,但却也是很重要的问题。[attribute!=value]这个属性选择器在jQuery 1.3之前是这样的:"匹配那些没有指定的属性的元素,或者指定的属性不等于特定值的元素。",这等价于:not([attr=value])。而在jQuery 1.3中是这样的:匹配所有含有指定的属性,但属性不等于特定值的元素。
这个改动是为了符合w3c的标准。虽然有点绕……
要解决这个问题,上面也已经提到了,有选择得使用:not([attr=value])代替即可。(但目前这个似乎在ie下有bug,依然跟以前的表现一样,ff和chrome下符合这个描述)

1.3.1中又改回来了……[attribute!=value]依然等价于:not([attr=value])。如果要找含有特定属性且不等于指定值的请继续使用[attr]:not([attr= value])

更多的问题尚未发现,如果各位同学遇到了请不要吝惜提出来~谢谢。

Posted in jQuery | 13 Comments