PHP5研究室 - 国内Android用户的第一选择! http://www.phpv.net/ 为Android手机提供免费应用软件,ROM,免费游戏,破解刷机,汉化工具! 同时为Android开发者提供交流平台. Wed, 17 Jan 2018 18:14:07 +0000 Chiron ver1.0 zh-cn hourly 1 JavaScript可否多线程? 深入理解JavaScript定时机制 http://www.phpv.net/html/1700.html http://www.phpv.net/html/1700.html#comment Sun, 27 Sep 2009 11:41:00 +0000 admin http://www.phpv.net/html/1700.html JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如

setTimeout( function(){ alert(’你好!’); } , 0);
setInterval( callbackFunction , 100);

认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaScript API文档明确定义第二个参数意义为隔多少毫秒后,回调方法就会被执行. 这里设成0毫秒,理所当然就立即被执行了.
同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不疑!

但随着JavaScript应用开发经验不断的增加和丰富,有一天你发现了一段怪异的代码而百思不得其解:

div.onclick = function(){
setTimeout( function(){document.getElementById(’inputField’).focus();}, 0);
};

既然是0毫秒后执行,那么还用setTimeout干什么, 此刻, 坚定的信念已开始动摇.

直到最后某一天 , 你不小心写了一段糟糕的代码:

setTimeout( function(){ while(true){} } , 100);
setTimeout( function(){ alert(’你好!’); } , 200);
setInterval( callbackFunction , 200);

第一行代码进入了死循环,但不久你就会发现,第二,第三行并不是预料中的事情,alert问候未见出现,callbacKFunction也杳无音讯!

这时你彻底迷惘了,这种情景是难以接受的,因为改变长久以来既定的认知去接受新思想的过程是痛苦的,但情事实摆在眼前,对JavaScript真理的探求并不会因为痛苦而停止,下面让我们来展开JavaScript线程和定时器探索之旅!

拔开云雾见月明

出现上面所有误区的最主要一个原因是:潜意识中认为,JavaScript引擎有多个线程在执行,JavaScript的定时器回调函数是异步执行的.

而事实上的,JavaScript使用了障眼法,在多数时候骗过了我们的眼睛,这里背光得澄清一个事实:

JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序.

JavaScript引擎用单线程运行也是有意义的,单线程不必理会线程同步这些复杂的问题,问题得到简化.

那么单线程的JavaScript引擎是怎么配合浏览器内核处理这些定时器和响应浏览器事件的呢?
下面结合浏览器内核处理方式简单说明.

浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假如某一浏览器内核的实现至少有三个常驻线 程:javascript引擎线程,界面渲染线程,浏览器事件触发线程,除些以外,也有一些执行完就终止的线程,如Http请求线程,这些异步线程都会产 生不同的异步事件,下面通过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通信的.虽然每个浏览器内核实现细节不同,但这其中的 调用原理都是大同小异.


由图可看出,浏览器中的JavaScript引擎是基于事件驱动的,这里的事件可看作是浏览器派给它的各种任务,这些任务可以源自 JavaScript引擎当前执行的代码块,如调用setTimeout添加一个任务,也可来自浏览器内核的其它线程,如界面元素鼠标点击事件,定时触发 器时间到达通知,异步请求状态变更通知等.从代码角度看来任务实体就是各种回调函数,JavaScript引擎一直等待着任务队列中任务的到来.由于单线 程关系,这些任务得进行排队,一个接着一个被引擎处理.

上图t1-t2..tn表示不同的时间点,tn下面对应的小方块代表该时间点的任务,假设现在是t1时刻,引擎运行在t1对应的任务方块代码内,在这个时间点内,我们来描述一下浏览器内核其它线程的状态.

t1时刻:

GUI渲染线程:

该线程负责渲染浏览器界面HTML元素,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行.本文虽然重 点解释JavaScript定时机制,但这时有必要说说渲染线程,因为该线程与JavaScript引擎线程是互斥的,这容易理解,因为 JavaScript脚本是可操纵DOM元素,在修改这些元素属性同时渲染界面,那么渲染线程前后获得的元素数据就可能不一致了.

在JavaScript引擎运行脚本期间,浏览器渲染线程都是处于挂起状态的,也就是说被”冻结”了.

所以,在脚本中执行对界面进行更新操作,如添加结点,删除结点或改变结点的外观等更新并不会立即体现出来,这些操作将保存在一个队列中,待JavaScript引擎空闲时才有机会渲染出来.

GUI事件触发线程:

JavaScript脚本的执行不影响html元素事件的触发,在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成 一个鼠标点击事件,由图可知,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标 点击事件正在等待处理.

定时触发线程:

注意这里的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就计不了时,它必须依赖外部来计时并触发定时,所以队列中的定时事件也是异步事件.

由图可知,在这t1的时间段内,继鼠标点击事件触发后,先前已设置的setTimeout定时也到达了,此刻对JavaScript引擎来说,定时触发线程产生了一个异步定时事件并放到任务队列中, 该事件被排到点击事件回调之后,等待处理.
同理, 还是在t1时间段内,接下来某个setInterval定时器也被添加了,由于是间隔定时,在t1段内连续被触发了两次,这两个事件被排到队尾等待处理.

可见,假如时间段t1非常长,远大于setInterval的定时间隔,那么定时触发线程就会源源不断的产生异步定时事件并放到任务队列尾而不管它 们是否已被处理,但一旦t1和最先的定时事件前面的任务已处理完,这些排列中的定时事件就依次不间断的被执行,这是因为,对于JavaScript引擎来 说,在处理队列中的各任务处理方式都是一样的,只是处理的次序不同而已.

t1过后,也就是说当前处理的任务已返回,JavaScript引擎会检查任务队列,发现当前队列非空,就取出t2下面对应的任务执行,其它时间依此类推,由此看来:

如果队列非空,引擎就从队列头取出一个任务,直到该任务处理完,即返回后引擎接着运行下一个任务,在任务没返回前队列中的其它任务是没法被执行的.

相信您现在已经很清楚JavaScript是否可多线程,也了解理解JavaScript定时器运行机制了,下面我们来对一些案例进行分析:

案例1:setTimeout与setInterval

setTimeout(function(){
/* 代码块... */
setTimeout(arguments.callee, 10);
}, 10);

setInterval(function(){
/*代码块... */
}, 10);

这两段代码看一起效果一样,其实非也,第一段中回调函数内的setTimeout是JavaScript引擎执行后再设置新的setTimeout 定时, 假定上一个回调处理完到下一个回调开始处理为一个时间间隔,理论两个setTimeout回调执行时间间隔>=10ms .第二段自setInterval设置定时后,定时触发线程就会源源不断的每隔十秒产生异步定时事件并放到任务队列尾,理论上两个setInterval 回调执行时间间隔<=10.

案例2:ajax异步请求是否真的异步?

很多同学朋友搞不清楚,既然说JavaScript是单线程运行的,那么XMLHttpRequest在连接后是否真的异步?
其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即还是单线程运行 onreadystatechange所设置的函数.

]]>
为什么设计师应该学习编写代码 http://www.phpv.net/html/1694.html http://www.phpv.net/html/1694.html#comment Wed, 08 Jul 2009 17:30:52 +0000 admin http://www.phpv.net/html/1694.html 通常,在完成了一件网页设计后,设计师的无知都会显露无遗而备受指责。他们把创建网页代码的繁重工作都留给了程序员们。这种现象不只出现在网络开发行业,在软件及游戏开发业也是如此。

残酷的事实就是:开发进度可能会因设计师而停滞不前。为了追求最佳效率,设计师不仅需要描描画画,还需要能把它做出来!本文中,我想与读者分享一些为什么设计师需要学习编写代码的理由。

做现实可行的设计

有了一个最终产品将如何实现的明确印象,设计师将拿出更多实际可行的概念。作为开发进程中不可或缺的一份子,设计师肩负着确保他们的设计能够顺利转 移到网络介质上,同时还要考虑其可用性,网页易读性和可实现性。一个对用户友好的网站不仅有简洁清晰的浏览顺序逻辑,还向用户提供一切所需的信息而不会显 得咄咄逼人或是杂乱无章。想要知道一种 Web 布局是否可行的唯一途径就是亲自去了解如何建立一个网页。

使沟通更轻松

在几乎所有的设计与实现各自独立的产品中,设计组和实现组从没有满足过对方的期望,尤其是那些无形的产品,比如网站,软件和游戏。这通常归结于产品的期望和产品可行性的相互妥协,目前看来,这是难以完美统一的。解决之道是:设计师应该亲身尝试设计作品的实现,以避免沟通中的混淆,误解和误传。

方便的迭代开发过程

一个实践中的设计不应是绝对的。我的意思是,设计应该是灵活友好的,能够在修改以迎合系统技术限制的同时不扭曲其原有内涵。这些重复但必要的改动只 能由原设计师来实现。一个设计师/开发者能够比开发人员把设计重提到设计师手里进行改动更加高效。而且设计师和开发者之间——事实上经常如此——会产生摩 擦。

更好更和谐的结果

我常常喜欢把软件,网络或是游戏开发想成是管弦乐,而设计师是作曲家,开发者是乐团的指挥家。想象一下二者是同一个人将会怎样?交响曲将会是令人惊叹的,迷人的,纯正的!不仅是大师的神作,而且还是其本人亲自指挥的!

缩短开发时间

设计师同时充当程序员的角色意味着设计和编码的进度即使不是同时的也是连续的。结果就是开发周期的缩短——谁会不关心效率呢?

设计师更加市场化

现代的设计师需要提升自身的能力以保持个人价值,有一套技能是远远不够的,我们往往需要戴着不同的头衔:设计师,前端开发者,文章作者和项目经理。

通过学习实现你自己的设计,而不是让设计成为开发者手中的孤儿——你提升了自身价值。毕竟,在简历中提到设计和编码技能不会有坏处。相反,在这个金融危机时代的企业重组(参见:大规模裁员)和缩减开支的环境下,还能够强调一个人的重要性而免遭解雇。

然而,即使有这么多的理由支持设计师学习编写代码,这里还是有反对的声音。

引用 Lukas Mathis 的一篇有争议性的文章“设计师不是程序员”(注1)

如果设计师实现自己的设计,他会受制于两个不同的目标:代码的整洁和良好的用户体验。这两个目标是相互矛盾的。如果你要实现你自己的设计,你必然会为了代码的质量而妥协,这是不利于交互设计的。

实现自己设计的设计师面临着两个问题:他们知道一个很棒的新思路会建立混乱的代码,他们也知道如果改进用户体验,现有的代码会被打乱。这两者相互矛盾,因为用户体验都在于小的细节,而这些小细节最终毁于他们的不忍心使代码变得混乱。

这恰如其分的总结了“Web 开发纯化者”们所采取的强硬立场。他们是守旧派,倡导在设计和开发之间划清界限。显然,设计师为人类创作,开发者为机器创作。因此,用户体验设计师们应该设计出最可行的用户界面并让开发者做出最可行的编程决策。虽然这有一定的道理,但当我研究一个用户界面的时候,我从代码中寻找灵感的努力却以失败而告终。总之,在头脑中有一个技术及可用性限制的正确观念还是更有好处。

写在最后

归根结底,所开发项目的规模可能最终决定着设计师和开发者的角色。一个小型的应用可以由一个项目经理(注2)一手掌控,而一个大型的系统必然需要不同的专业人才!

注1 Mathis-Lukas——“Designers are not Programmers”——ignore the code

注2 Spolsky-Joel——描述了一个叫做“设计师兼程序员”的职位——“How to be a program manager”——Joel on Software

作者 John Urban 是加州大学的大二学生,主修计算机科学。

英文原文 http://sixrevisions.com/web_design/why-designers-should-learn-how-to-code/


转自:http://ineu.org.cn/blog/index.php/archives/431 ]]>
WEB标准之CSS: 打造自己的reset.css http://www.phpv.net/html/1672.html http://www.phpv.net/html/1672.html#comment Sun, 01 Mar 2009 17:23:44 +0000 抽烟的蚊子 http://www.phpv.net/html/1672.html 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,外边框
这个就是元素获取焦点时的虚线框,在ie之外的浏览器上可以像下面Eric做的那样,通过设置outline来消除。

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

而YUI则没有设置这一条。而在Eric的样式中,可以看到Eric的提醒:务必重新定义获取焦点后的样式!
这点其实很重要,出于可访问性的角度出发,那些不便于使用鼠标的人基本上都是用tab导航来浏览网页的。获取焦点的元素有特定样式的话可以极大帮助这类群 体的用户。

从通用性角度来说,YUI那样不加这条比较好,毕竟没多少人会自定义焦点样式。但从一个reset.css来说,应当还是加上去比较好。毕竟是 为了重置所有样式而写的reset.css,不能留下缺憾。因此这条可以作为reset.css之后及早定义的规则。

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)——这种情况的发生。

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

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。看起来也会比较舒服。

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样式,未必人人喜欢虚线框。
所以,这里我考虑采纳Eric的重置样式。同时别忘了给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的了,对于样式重置,细致一点周到一点总没有错。

今天太晚了,已经四点了,等会睡觉起床接着更新我用的reset.css,以及写完reset.css后立即需要写的几个规则。

]]>
优化网站性能 提高网站速度访问速度的14条实践 http://www.phpv.net/html/1660.html http://www.phpv.net/html/1660.html#comment Wed, 07 Jan 2009 17:57:54 +0000 admin http://www.phpv.net/html/1660.html 相信互联网已经越来越成为人们生活中不可或缺的一部分。ajax,flex等等富客户端的应用使得人们越加“幸福”地体验着许多原先只能在C/S实 现的功 能。比如Google机会已经把最基本的office应用都搬到了互联网上。当然便利的同时毫无疑问的也使页面的速度越来越慢。自己是做前端开发的,在性能方面,根据yahoo的调查,后台只占5%,而前端高达95%之多,其中有88%的东西是可以优化的。

以上是一张web2.0页面的生命周期图。工程师很形象地讲它分成了“怀孕,出生,毕业,结婚”四个阶段。如果在我们点击网页链接的时候能够意识到 这个过程而不是简单的请求-响应的话,我们便可以挖掘出很多细节上可以提升性能的东西。今天听了淘宝小马哥的一个对yahoo开发团队对web性能研究的 一个讲座,感觉收获很大,想在blog上做个分享。

相信很多人都听过优化网站性能的14条规则。更多的信息可见developer.yahoo.com

1. 尽可能的减少 HTTP 的请求数 [content]
2. 使用 CDN(Content Delivery Network) [server]
3. 添加 Expires 头(或者 Cache-control ) [server]
4. Gzip 组件 [server]
5. 将 CSS 样式放在页面的上方 [css]
6. 将脚本移动到底部(包括内联的) [javascript]
7. 避免使用 CSS 中的 Expressions [css]
8. 将 JavaScript 和 CSS 独立成外部文件 [javascript] [css]
9. 减少 DNS 查询 [content]
10. 压缩 JavaScript 和 CSS (包括内联的) [javascript] [css]
11. 避免重定向 [server]
12. 移除重复的脚本 [javascript]
13. 配置实体标签(ETags) [css]
14. 使 AJAX 缓存


在firefox下有一个插件yslow,集成在firebug中,你可以用它很方便地来看看自己的网站在这几个方面的表现。

这是对用yslow对我的网站西风坊测评的结果,很遗憾,只有51分。呵呵。中国各大网站的分值都不高,刚测了一下,新浪和网易都是31分。然后yahoo(美国)的分值确实97分!可见yahoo在这方面作出的努力。从他们总结的这14条规则,已经现在又新增加的20个点来看,有很多细节我们真得是怎么都不会去想,有些做法甚至是有些“变态”了。

第一条、尽可能的减少 HTTP 的请求数Make Fewer HTTP Requests

http请求是要开销的,想办法减少请求数自然可以提高网页速度。常用的方法,合并css,js(将一个页面中的css和js文件分别合并)以及 Image maps和css sprites等。当然或许将css,js文件拆分多个是因为css结构,共用等方面的考虑。阿里巴巴中文站当时的做法是开发时依然分开开发,然后在后台 对js,css进行合并,这样对于浏览器来说依然是一个请求,但是开发时仍然能还原成多个,方便管理和重复引用。yahoo甚至建议将首页的css和js 直接写在页面文件里面,而不是外部引用。因为首页的访问量太大了,这么做也可以减少两个请求数。而事实上国内的很多门户都是这么做的。

而css sprites是指只用将页面上的背景图合并成一张,然后通过css的background-position属性定义不过的值来取他的背景。淘宝和阿里巴巴中文站目前都是这样做的。有兴趣的可以看下淘宝和阿里巴巴的背景图

http://www.csssprites.com/ 这是个工具网站,它可以自动将你上传的图片合并并给出对应的background-position坐标。并将结果以png和gif的格式输出。

第二条、使用CDN(内容分发网络): Use a Content Delivery Network

说实话,对于CDN这一块自己并不是很了解,简单地讲,通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的 cache服务器内,通过DNS负载均衡的技术,判断用户来源就近访问cache服务器取得所需的内容,杭州的用户访问近杭州服务器上的内容,北京的访问 近北京服务器上的内容。这样可以有效减少数据在网络上传输的时间,提高速度。更详细地内容大家可以参考百度百科上对于CDN的解释。Yahoo!把静态内容分布到CDN减少了用户影响时间20%或更多。

CDN技术示意图:



CDN组网示意图:

第三条、 添加Expire/Cache-Control 头:Add an Expires Header

现在越来越多的图片,脚本,css,flash被嵌入到页面中,当我们访问他们的时候势必会做许多次的http请求。其实我们可以通过设置Expires header 来缓存这些文件。Expire其实就是通过header报文来指定特定类型的文件在览器中的缓存时间。大多数的图片,flash在发布后都是不需要经常修 改的,做了缓存以后这样浏览器以后就不需要再从服务器下载这些文件而是而直接从缓存中读取,这样再次访问页面的速度会大大加快。一个典型的HTTP 1.1协议返回的头信息:
HTTP/1.1 200 OK
Date: Fri, 30 Oct 1998 13:19:41 GMT
Server: Apache/1.3.3 (Unix)
Cache-Control: max-age=3600, must-revalidate
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT
ETag: “3e86-410-3596fbbc”
Content-Length: 1040
Content-Type: text/html

其中通过服务器端脚本设置Cache-Control和Expires可以完成。

如,在php中设置30天后过期:

<!--pHeader("Cache-Control: must-revalidate");
$offset = 60 * 60 * 24 * 30;
$
ExpStr = "Expires: " . gmdate("D, d M Y H:i:s"time() + $offset) . " GMT";
Header($ExpStr);-->

也可以通过配置服务器本身完成,这些偶就不是很清楚了,呵呵。想了解跟多的朋友可以参考http://www.web-caching.com/

据我了解,目前阿里巴巴中文站的Expires过期时间是30天。不过期间也有过问题,特别是对于脚本过期时间的设置还是应该仔细考虑下,不然相应的脚本功能更新后客户端可能要过很长一段时间才能“感知”到这样的变化。以前做[suggest项目] 的时候就遇到过这个问题。所以,哪些应该缓存,哪些不该缓存还是应该仔细斟酌一番。

第四条、启用Gzip压缩:Gzip Components

Gzip的思想就是把文件先在服务器端进行压缩,然后再传输。这样可以显著减少文件传输的大小。传输完毕后浏览器会 重新对压缩过的内容进行解压缩,并执行。目前的浏览器都能“良好”地支持 gzip。不仅浏览器可以识别,而且各大“爬虫”也同样可以识别,各位seoer可以放下心了。而且gzip的压缩比例非常大,一般压缩率为85%,就是 说服务器端100K的页面可以压缩到25K左右再发送到客户端。具体的Gzip压缩原理大家可以参考csdn上的《gzip压缩算法 这篇文章。雅虎特别强调, 所有的文本内容都应该被gzip压缩: html (php), js, css, xml, txt… 这一点我们网站做得不错,是一个A。以前我们的首页也并不是A,因为首页上还有很多广告代码投放的js,这些广告代码拥有者的网站的js没有经过gzip压缩,也会拖累我们网站。

以上三点大多属于服务器端的内容,本人也是粗浅地了解而已。说得不对的地方有待各位指正。

第五条、将css放在页面最上面 ( Put Stylesheets at the Top)

将css放在页面最上面,这是为什么?因为 ie,firefox等浏览器在css全部传输完全之前不会去渲染任何的东西。理由诚如小马哥说得那样很简单。css,全称Cascading Style Sheets (层叠样式表单)。层叠即意味这后面的css可以覆盖前面的css,级别高的css可以覆盖级别低的css。在[css之!important] 这篇文章的最下面曾简单地提到过这层级关系,这里我们只需要知道css可以被覆盖的。既然前面的可以被覆盖,浏览器在他完全加载完毕之后再去渲染无疑也是合情合理的很多浏览器下,如IE,把样式表放在页面的底部的问题在于它禁止了网页内容的顺序显示。浏览器阻止显示以免重画页面元素,那用户只能看到空白页了。Firefox不会阻止显示,但这意味着当样式表下载后,有些页面元素可能需要重画,这导致闪烁问题。所以我们应该尽快让css加载完毕

顺着这层意思,如果我们再细究的话,其实还有可以优化的地方。比如本站上面包含的两个css文件,<link rel=“stylesheet” rev=“stylesheet” href=“http://www.space007.com/themes/google/style/google.css” type=“text/css” media=“screen” /> 和<link rel=“stylesheet” rev=“stylesheet” href=“http://www.space007.com/css/print.css” type=“text/css” media=“print” />。 从media就可以看出第一个css是针对浏览器的,第二个css文件是针对打印样式的。从用户的行为习惯上来将,要打印页面的动作一定是发生在页面页面 显示出来之后的。所以比较好的方法应该是在页面加载完毕之后再动态地为这张页面加上针对打印设备的css,这样又可以提高一点速度。(哈哈)

第六条、将script放在页面最下面 (Put Scripts at the Bottom )

将脚本放在页面最下面的目的有那么两点: 1、 因为防止script脚本的执行阻塞页面的下载。在页面loading的过程中,当浏览器读到js执行语句的时候一定会把它全部解释完毕后在会接下来读下 面的内容。不信你可以写一个js死循环看看页面下面的东西还会不会出来。(setTimeout 和 setInterval的执行有点类似于多线程,在相应的响应时间之前也会继续下面的内容渲染。)浏览器这么做的逻辑是因为js随时可能执 行 location.href或是其他可能完全中断此页面过程的函数,即如此,当然得等他执行完毕之后再加载咯。所以放在页面最后,可以有效减少页面可 视元素的加载时间。        2、脚本引起的第二个问题是它阻塞并行下载数量。HTTP/1.1规范建议浏览器每个主机的并行下载数不超过2个(IE只能为2个,其他浏览器如ff等都是默认设置为2个,不过新出的ie8可以达6个)。因此如果您把图像文件分布到多台机器的话,您可以达到超过2个的并行下载。但是当脚本文件下载时,浏览器不会启动其他的并行下载。

当然对各个网站来说,把脚本都放到页面底部加载的可行性还是值得商榷的。就比如阿里巴巴中文站的页面。很多地方有内联的js,页面的显示严重依赖于此,我承认这和无侵入脚本的理念相差甚远,但是很多“历史遗留问题”却不是那么容易解决的。

第七条、避免在CSS中使用Expressions (Avoid CSS Expressions )

不过这样就多了两层无意义的嵌套,肯定不好。还需要一个更好的办法。

第八条、把javascript和css都放到外部文件中 (Make JavaScript and CSS External )

这点我想还是很容易理解的。不仅从性能优化上会这么做,用代码易于维护的角度看也应该这么做。把css和js写在页面内容可以减少2次请求,但也增 大了页面的大小。如果已经对css和js做了缓存,那也就没有2次多余的http请求了。当然,我在前面中也说过,有些特殊的页面开发人员还是会选择内联 的css和js文件。

第九条、减少DNS查询 (Reduce DNS Lookups)

在 Internet上域名与IP地址之间是一一对应的,域名(kuqin.com)很好记,但计算机不认识,计算机之间的“相认”还要转成ip地址。在网络 上每台计算机都对应有一个独立的ip地址。在域名和ip地址之间的转换工作称为域名解析,也称DNS查询。一次DNS的解析过程会消耗20-120毫秒的 时间,在dns查询结束之前,浏览器不会下载该域名下的任何东西。所以减少dns查询的时间可以加快页面的加载速度。yahoo的建议一个页面所包含的域 名数尽量控制在2-4个。这就需要对页面整体有一个很好的规划。目前我们这点做的不好,很多打点的广告投放系统拖累了我们。

第十条、压缩 JavaScript 和 CSS (Minify JavaScript )

压缩js和css的左右很显然,减少页面字节数。容量小页面加载速度自然也就快。而且压缩除了减少体积以外还可以起到一定的保护左右。这点我们做得不错。常用的压缩工具有JsMin、YUI compressor等。另外像http://dean.edwards.name/packer/还给我们提供了一个非常方便的在线压缩工具。你可以在jQuery的网页看到压缩过的js文件和没有压缩过的js文件的容量差别:

当然,压缩带来的一个弊端就是代码的可读性没了。相信很多做前端的朋友都遇到过这个问题:看Google的效果很酷,可是去看他的源代码却是一大堆 挤在一起的字符,连函数名都是替换过的,汗死!自己的代码也这样岂不是对维护非常不方便。所有阿里巴巴中文站目前采用的做法是在js和css发布的时候在 服务器端进行压缩。这样在我们很方便地维护自己的代码。

第十一条、避免重定向 (Avoid Redirects )

不久前在ieblog上看到过《Internet Explorer and Connection Limits》这篇文章,比如 当你输入http://www.kuqin.com/ 的时候服务器会自动产生一个301服务器转向 http://www.kuqin.com/ ,你看浏览器的地址栏就能看出来。这种重定向自然也是需要消耗时间的。当然这只是一个例子,发生重定向的原因还有很多,但是不变的是每增加一次重定向就会增加一次web请求,所以因该尽量减少。

第十二条、移除重复的脚本 (Remove Duplicate Scripts )

这点我想不说也知道,不仅是从性能上考虑,代码规范上看也是这样。但是不得不承认,很多时候我们会因为图一时之快而加上一些或许是重复的代码。或许一个统一的css框架和js框架可以比较好的解决我们的问题。小猪的观点很对,不仅是要做到不重复,更是要做到可重用。

第十三条、配置实体标签(ETags) (Configure ETags )

这点我也不懂,呵呵。在inforQ上找到一篇解释得比较详细的说明《使用ETags减少Web应用带宽和负载》,有兴趣的同学可以去看看。

第十四条、使 AJAX 缓存 (Make Ajax Cacheable )

ajax还要去缓存?做ajax请求的时候往往还要增加一个时间戳去避免他缓存。It’s important to remember that “asynchronous” does not imply “instantaneous”.(记住“异步”不是“瞬间”这一点很重要)。记住,即使AJAX是动态产生的而且只对一个用户起作用,他们依然可以被缓 存。

]]>
使用 jQuery,第 3 部分: 用 jQuery 和 Ajax 构建富 Internet 应用程序 http://www.phpv.net/html/1652.html http://www.phpv.net/html/1652.html#comment Mon, 15 Dec 2008 21:17:42 +0000 esayr http://www.phpv.net/html/1652.html 2008 年 12 月 12 日

jQuery 是一种 JavaScript 库,它是开发人员简化动态富 Internet 应用程序的创建过程的最佳选择。随着基于浏览器的应用程序不断代替桌面应用程序,这些库的使用将越来越广泛。您将通过本系列文章中了解 jQuery,并学习如何在 Web 应用程序项目中实现 jQuery。

简介

最 近这几个月以来,JQuery 受欢迎的指数迅速攀升,现已成为 Web 开发人员首选的 JavaScript 库。与此同时,人们对富 Internet 应用程序(Rich Internet Application,RIA)的应用和需求也在迅速增长,并期待用基于浏览器的应用程序代替桌面应用程序。无论是电子表格,还是薪水册和电子邮件应用 程序,现在都在浏览器中再现了类似于桌面的体验。随着这些应用程序数量的增多和功能的日益复杂,JavaScript 库将会变得越来越重要,因为它是构建这些应用程序的坚实基础。JQuery 无疑成为了开发人员最佳选择。本系列文章深入探索了 jQuery,并提供了坚实的基础。开发人员借助这个基础就可以快速轻松地构建自己的 RIA。

在本系列 之前的一篇文章 中,您了解了用来构建 RIA 以及为页面添加交互性的三个基本组件。第一个模块是 Event 模块,借助此模块,能捕获用户对页面的任意交互并以编程的方式进行响应。比如,您可以向按钮点击、鼠标移动等事件附加代码。下一个模块是 Attributes 模块,它解释了如何在页面元素上获得/设置值,以及如何将其作为带有变量的数据对象。这些值包含了决定为用户提供何种响应的大部分信息。最后,您还看到了 如何进行 CSS 处理,以及如何在不重新加载页面的情况下更改页面上任意元素的布局、颜色、字体等。了解这三个模块之后,就等于掌握了交互 Web 页面的三个基本元素 — 获取用户交互(Event)、收集信息(Attribute)以及在事件和信息基础上提供反馈(CSS)。

在 本文中,将对交互 Web 页面的这三个基本元素进行更进一步的探究,提供当今高级 Web 应用程序必备的 “酷” 效果和特征。这些附加的模块对提供 RIA 而言并不是至关重要的,但这些效果和特征会给用户留下深刻印象,并且还会极大地扩展 RIA 的可用范围和特性。您将看到的第一个模块是 Effects 模块,它包含很多特性,比如隐藏元素、随处移动元素、淡入淡出元素等。换言之,这些都是让 Web 页酷起来的 “亮点”。最后一个要讨论的模块是 Asynchronous JavaScript + XML (Ajax) 模块。大多数人都将该模块等同为 RIA。Ajax 让 Web 应用程序无需重载页面就能与服务器进行交互、向服务器传递信息并从中获取信息(与 Web 上的一些意见相反,Ajax 单纯是一个很酷的 JavaScript 动画工具)。您将发现 jQuery 提供了极其简单易用的 Ajax 工具。实际上,jQuery 使 Ajax 的使用与调用其他 JavaScript 方法一样简单。

本文中的示例应用程序是个总结,展示了 Effects 和 Ajax 模块如何融入到这个示例 Web 邮件应用程序中。我将向这个示例程序添加一些效果使其更加漂亮,而且更重要的一点是,我将添加一些 Ajax 代码,以便无需重载页面邮件应用程序就能显示信息。

Effects 模块

从 其名字往往容易得出这样的结论,Effects 模块只包含一些动画和效果,而这些动画和效果往往是一些 “正规” 的 Web 页面所竭力避免的。但实际情况并非如此。几乎所有的应用程序都会遇到这样的情况,即某个页面元素需要隐藏或其视图应该根据另一个页面元素的状态进行切换。 这类更改对于一个 RIA 而言非常重要,因为它们让您能够加载某个页面的所有页面元素,然后通过隐藏/显示特定的元素只显示所需的信息。重载页面的方式并不可取。比如一个具有两个 选项的组合框,一个选项是隐藏 div,一个选项是显示此 div。很显然,与更改组合框并重载页面隐藏/显示 div 相比,用客户端代码隐藏/显示此 div 更简单和高效。而仅隐藏/显示还是要让它淡入/淡出,则完全取决于您。

如上所述,最基本的效果函数是 show()hide() 函数。这非常直观;它们可分别用来显示和隐藏页面上的某个元素。


清单 1. 隐藏和显示函数
				
// shows every <p> on the page
$("p").show();

// hides every <p> on the page
$("p").hide();

// hides every other <p> on the page
$("p:odd").hide();

除了这些基本操作,利用 show()hide() 这两个函数,还能更多地控制页面元素如何显示和隐藏。相关文档将 hide() 描述为 “优美” 的显示/隐藏,对于 show(),就是综合淡入和滑出的效果。

在开始深入探讨一些例子之前,不妨回过头来看看传递给这些效果函数的参数。每个函数(除了通用的 show()hide() 函数之外)都允许在效果完成时传入要调用的速度和函数。速度用来控制效果出现的快慢。这个参数可以是一个 "slow""fast""normal" 字符串。此外,如果需要精确控制动画时间,那就需要用参数指定毫秒数。Effects 函数的第二个参数本身就是一个函数,此函数在效果完成后调用。如果想要将几个效果组合成一个较大规模的效果,这一点将非常重要,因为利用它,能够可靠地控 制一个效果何时完成,下一个效果何时开始。


清单 2. 复合效果
				
// the img with an ID of "picture" should start hidden
// when the "showPicture" button is pressed, show the img with an ID of "picture"
// and animate it, so it appears quickly in a fade In and slide out, and when
// it's done being shown, show the caption of the picture, which is
// always in the span right after the <img> tag

<input type="button" id="showPicture">

<img src="/pic.jpg" id="picture"><span>This is the picture's caption</span>

// jQuery code inside the document.ready() function

$("#picture").hide().next().hide();
$("#showPicture").click(function(){
$("#picture").show("fast", function(){
$("#picture").next().show();
});
});

// notice how it took more text to describe what you want to happen than it took
// to actually code it!

Effects 模块还有其他一些函数,它们与 show()hide() 非常类似,并且最终所实现的功能也基本相同;只不过实现的方式不同。slideDown()slideUp() 函数分别用来显示和隐藏一个页面元素。不过,这是通过将该元素滑下或滑上的动画效果实现的(从其名称中不难看出这一点)。与我刚刚提到的增强了的 hide()show() 函数类似,您也可以控制滑动的速度以及在效果完成时要调用的函数。此外,要显示/隐藏页面元素还有另一种选择,即 fadeIn()fadeOut() 函数,正如其名字所示,这两个函数用来淡入页面元素直至该元素透明,然后使该元素消失。它们允许在效果完成时定制速度和要调用的函数。

有一个很有趣的函数,它可部分隐藏和显示页面元素,此函数是 fadeTo(), 它能让页面元素部分透明。我认为此函数对 RIA 很重要,因为透明性是突出页面上某个元素的一种很好的方式,并可用来显示页面的禁用区域。例如,页面上有几个选项卡,可以让所有未被选中的选项卡呈现一些 透明性来突出其未被选中。或者,在一个页面表单上,可以让所有没有焦点的元素呈现一些透明性以向用户突出哪个 Form 元素当前具有焦点。此外,透明性本身就很酷。在进行设计时,不妨遵循这样一条通用的箴言 “如果苹果公司这么设计,效果一定很酷”。


清单 3. 使用 fadeTo() 增添很酷的效果
				
// make all the Form elements on the page show transparency at 60%, except
// the one that currently has focus, which will not have any transparancy.
// This is Apple cool!

$(":input").fadeTo("fast", .60);
$(":input").focus(function(){
$(this).fadeTo("fast", 1);
});
$(":input").blur(function(){
$(this).fadeTo("fast, .60);
});

我 想要强调的 Effects 模块内的最后一个函数是最酷也是最容易出错的。它是一种定制动画的方法,允许您定义动画的所有参数,而剩下的工作则由 jQuery 负责处理。您负责提供一个参数数组以及这些参数的最终值,jQuery 负责决定这些参数的当前值。而且,动画的速度也可指定,这能使页面元素动画的运行比较平稳,直至达到您所提供的最终值。清单 4 给出了此定制动画方法的一个例子。显然,该函数提供很多可能性,如果您想要自己定制动画,不妨多进行练习。


清单 4. 定制动画的方法
				
// when the button is clicked, make the div with an ID of "movingDiv"
// have the custom animation provided.
$("#myButton").click(function(){
$("#movingDiv").animate({
// will increase the width, opacity, and fontSize of "movingDiv"
// and do it in 5 seconds
width: 700;
opacity: 0.5;
fontSize: "18px";
}, 5000);
});

Ajax

当 前,与 Web 页面有关的最流行的一句话就是 “它用到 Ajax 了吗”,但是,是不是每个人都能真正理解 Ajax 的含义呢?在 Google 上搜索 “Ajax” 将会出现数百万个搜索结果(与大多数搜索一样),但是,这么多结果似乎表明对术语 Ajax 真正含义的理解还存在一些含糊不清之处。Ajax 并不是 某些页面上出现的一些很酷的动画,也不是弹出窗口下一个很酷的阴影效果。Ajax 很酷,但并不意味着 Web 页上的任何一个令人耳目一新的东西都是 Ajax 的成果。Ajax 的核心是在不重载页面的情况下客户端 Web 页面能与服务器来回传递信息。所以,虽然 Ajax 并不能提供页面上的绚丽效果,但利用 Ajax 却能使 Web 应用程序真实模仿桌面应用程序。所以,围绕 Ajax 沸沸扬扬的现象是有其根源的 —— Ajax 的广泛应用直接导致了目前 RIA 的迅速发展。

jQuery 则让使用 Ajax 变得异常简单!我并不是夸大其词。在没有 JavaScript 库的情况下使用过 Ajax 的人都知道,他们必须处理 XMLHttpRequests、处理 XMLHttpRequest 的 Microsoft® 和 Firefox 版本间的差异、必须解析全部返回代码等,而 jQuery 则让使用 Ajax 简单到进行一次函数调用即可。这是真的!原先需要 100 行代码才能完成的功能现在只需 3 或 4 行代码就可以了。这节省了多少时间啊!就我个人而言,获悉 jQuery 之前,若想添加 Ajax 函数往往需要大量工作。现在,有了 jQuery,这变得极其简单,并能让我的应用程序充分利用 Ajax 提供的全部益处。如果 Ajax 的使用能简单到一个常规的函数调用,那为什么不使用它呢?

现在来看看您最有可能在自己的 Ajax 需求中用到的两个函数:post()get() 方法。这些函数的运作与其他的 jQuery 函数没有太大差别,它们均允许指定要调用的 URL 以及要传递的参数,并指定 Ajax 方法返回时的函数。在这种意义上,这两个方法设置的方式使得在 jQuery 调用 Ajax 方法与在 jQuery 调用其他方法基本相同。参见清单 5。


清单 5. Post 和 get Ajax 方法
				
// this code would be in a php file named myTest.php
// why did I switch to PHP for the Ajax examples? Java/JSP gets tough because
// you need to show the code in the Servlet, which isn't necessary with PHP. The
// functions work equally well in both PHP and Java/JSP though.
<?php
echo "This is my return String";
?>

// here's how simple the Ajax calls are in jQuery
// This is a post function
$.post("myTest.php", {}, function(data){
$("p").text(data);
});

$.get("myTest.php", {}, function(data){
$("p").text(data);
});

正 如这两个示例所示,这些函数与其他 jQuery 函数相同,因此比不带 JavaScript 库的情况更容易使用。有几个参数可用来扩展 Ajax 调用的函数。第一个参数很显然是要调用的 URL。这可以是 PHP 文件、一个 JSP 文件或 Servlet — 通常可以是处理此请求的任何东西。它甚至可以不响应此请求(正如您在以后的示例应用程序中看到的一样)。第二个参数是可选的,用来传递 post/get 的数据。一般采用数组格式。通常,需要传递在 Form 元素中包含的信息以及来自页面的 userID 信息等。基于服务器文件的所有东西都要处理此请求。第三个参数也是可选的,是 Ajax 函数成功返回时所要执行的函数。该函数一般包含用来处理由服务器传递回的信息结果的代码。清单 6 给出了这三个参数的一些例子,我随后还会介绍第四个参数。


清单 6. 用可选参数进行 post
				
// place a username and password input field on the page
<input type=text id="username">
<input type=password id="pass">

// call a server-based PHP file that will process the information passed to it
$.post("myFormProcessor.php", {username: $("#username").val(),
password: $("#pass").val()});

// conversely, this PHP file could also return information to the function, from which
// you could process the results
$.post("myFormProcessor.php", {username: $("#username").val(),
password: $("#pass").val()},
function(data){
// the data variable contains the text returned from the server, you don't
// have to set anything up ahead of time, jQuery will do it all for you
if (data != "ERROR")
$("#responseDiv").text(data);
}
);

不 难看出,在 jQuery 内处理 Ajax 非常直观和容易。不过,如果处理来自服务器的比文本字符串复杂的信息时,这些函数可以变得很复杂。在较多涉及 Ajax 调用的一些更为复杂的 Web 页面内,返回的数据结果通常都是 XML 格式的。返回的数据也可以是 JSON 对象格式的(JSON 是用来定义 JavaScript 对象的一种协议)。jQuery 还允许 get/post 方法有可选的第四个参数,以便提前就能指定由服务器返回值的类型。可以针对 XML 字符串传递 "xml" 字符串、针对 HTML 字符串(或纯文本)传递 "html"、针对 JavaScript 代码传递 "script"、针对 JSON 传递 "json"。所以,例如通过将返回对象指定为 "json" 类型,jQuery 将能自动将来自服务器的响应字符串转换成 JSON 对象,使您能够立即引用它。


清单 7. 指定 Ajax 内的返回类型
				
// specify the return object to be a type JSON object, and process the
// return object as a JSON object, referencing fields in it without
// casting it to any object or evaluating it

$.post("myFormProcessor.php", {username: $("#username").val(),
password: $("#pass").val()},
function(data){
// jQuery has already converted the data response into a JSON object, so
// you can immediately reference its fields, providing cleaner-looking code
// and allowing future changes, and in my opinion, making it easier to work
// with than XML responses
$("#username").text(data.username);
$("#address").text(data.address);
$("#phone").text(data.phone);
},
"json" // here you specify that the return type is JSON
);

我想花些时间讲述的另一个 Ajax 函数是 load(), 它允许用户加载一个特定的页面并获取 HTML 作为结果。从这样的描述看起来,它并不那么吸引人。事实上,与在启动时解析 Web 页一样,您还需要解析使用 jQuery 代码返回的信息。这是什么意思呢?简单来说,如果能加载任何 Web 页面,继而又能用 jQuery 对之进行解析,也就实现了一个非常高效且易于编程的页面 scraper,借助这个 scraper,可以从所有页面搜集各类信息。让我们详细看看。


清单 8. load() 函数的示例应用程序
				
// create a very primitive stock price quote by calling Yahoo's stock quote, and then
// scraping the information from their pages.
// in this case, look up IBM's stock price, and place it in the text field with an ID of
// "stockPrice"
// the span with the ID of "yfs_l90_ibm" contains the stock price
$("#stockPrice").load("http://finance.yahoo.com/q?s=ibm #yfs_l90_ibm").text();

接下来我要介绍的 Ajax 模块的最后两个函数是两个真正的实用函数,它们非常有助于 Ajax 的使用。正如我已经多次指出的,客户机和服务器间的很多交互都会涉及到表单以及其中所包含的元素。由于这类通信很常见,所以在 jQuery 内已经有两个实用函数可用来协助构造传递给服务器的参数,参数可以是 HTTP 查询字符串的格式也可以是 JSON 字符串格式。可以使用这两个实用函数来为您的 Ajax 需求提供帮助。这两个函数的使用很方便,因为这二者均能封装整个表单,而不管在开发期间有多少元素被添加/删除/更改。清单 9 给出了这样一个例子。


清单 9. serialize()serializeArray() 函数
				
// the serialize function will look at every Form element inside the specified element
// and automatically construct an HTTP String that contains all the information
// of the elements, in the form of <element name>=<element value>&
// for example, "firstname=Michael&lastname=Abernethy"
// this can then be attached to the URL to pass the information via an Ajax call
$.post("myFormProcessor.php?" + $("#myForm").serialize());

// further, a similar thing could be done with the serializeArray function
// which will convert a Form into its JSON equivalent
$.post("myFormProcessor.php", {json: $("#myForm").serializeArray()});

综合学到的知识

要 将本系列的所有课程综合起来,需要用到在前两个课程中都谈及的这个示例 Web 邮件应用程序。我将添加从客户端到服务器端的多个 Ajax 调用以收集信息。我还将使用 Ajax 来获得您读取消息时的消息信息,并利用 Ajax 方法来删除消息。之后,我会将一些效果融入其中以便当用户删除消息时,这些消息会立即从屏幕中删除,即便用户并没有重新加载此页面,而且实际的删除也是通 过 Ajax 调用异步发生的。在本文结束之际,您将能再次感受到在 Web 应用程序中使用 Ajax 调用是多么容易,并了解到如何利用这些调用来实真实模仿桌面应用程序,以及如何利用 Effects 来增强应用程序的可用性。


清单 10. 示例 Web 应用程序 - 删除消息
				
// First, let's look at how you handle deleting a message.

// The first step is to create a button that will actually delete messages
<input type=button id="delete" value="Delete">

// next, you'll add a checkbox in each row of the table, so that users can select
// which messages they want to delete. You'll use these checkboxes later, and
// the information contained in them is equally important (that's called
// foreshadowing!)
// Notice how the value of each checkbox is the message.id!

<tr class="messageRow" id="<%=message.id %>">
<input type=checkbox name="delId" value="<%=message.id%>" class=selectable>

// Now that the HTML is complete, look at the jQuery code to execute these deletes

// First, attach an event to the delete button, so when it's pressed, it will
// start deleting the checked messages

$("#delete").click(function() {
deleteMessages();
});

// Finally, let's define the deleteMessage() function, because that contains the meat of
// today's lessons.
// Because this is the culmination of every lesson, let's look at everything I did to
// get this working!
// Note 1 - I loop through each of the checkboxes that are checked by passing in a very
// specific search parameter, to find only the members of the "selectable" class that
// are checked.
// Note 2 - because the value of the checkbox is the same as the ID of the table row in
// which it is contained, you can use the Effects module to hide the entire table row,
// by passing in the value of the checkbox, and getting the table row back, and then
// hiding it.
// Note 3 - I make an Ajax call to actually delete the message from the DB. I have
// to pass the messageID to the server so that it knows which one to delete. That
// information is contained in the checkboxes value, which I pass with the Ajax call.
// Because I don't really care if it's successful or not, I ignore any reply from
// the server.

function deleteMessages()
{
$(".selectable:checked").each(function() {
$("#"+$(this).val()).remove();
$.post("<%=HtmlServlet.DELETE_MESSAGES%>.do", {delId: $(this).val()});
});
}

在第 2 个示例中,看一看如何读消息,这展示了如何在 jQuery 中使用 Ajax:


清单 11. 示例 Web 应用程序 - 读取消息
				

// You've seen most of this code previously in the example from last article, so let's
// focus on the Ajax portion of the code.
// Note 1 - I make an Ajax call with all 4 arguments defined. I have to pass two
// variables to the server in order to read the message. The first is the message
// ID number, because I need to know which message I want to read. The second is
// the current view...for reasons I can't recall (not important really).
// Note 2 - The fourth argument into the Ajax function is "json", indicating that
// I expect a JSON object back from the Ajax call. jQuery will automatically
// convert the response String into a JSON object.
// Note 3 - Notice that I handle the JSON object directly, without using an
// eval() function, because jQuery has already created the object. I can
// reference its fields directly.
$(".messageRow").dblclick(function() {
if ($(this).hasClass("mail_unread"))
{
$(this).removeClass("mail_unread");
}
$.post("<%=HtmlServlet.READ_MESSAGE%>.do", {messageId: $(this).attr("id"),
view: "<%=view %>"},
function(data){
if (data != "ERROR")
{
// using JSON objects
$("#subject").val(data.subject);
$("#message").val(data.message);
$("#from").val(data.from);
}
}, "json");
$.blockUI(readMess, {width:'540px', height:'300px'});
});

结束语

随 着应用程序不断从桌面向浏览器转移,像 jQuery 这样的 JavaScript 库的将越来越重要。应用程序越来越复杂,这就使跨浏览器的 jQuery 成为所有 Web 应用项目的必要工具。由于易于使用和功能完备,jQuery 逐渐从其他 JavaScript 库中脱颖而出,成为很多开发人员的最佳选择。

通过这个 jQuery 系列的第三篇文章,您接触到了另外两个模块,利用它们能为应用程序真正添加丰富性,并进一步模糊桌面应用程序和 Web 应用程序间界限。本课程中功能最强大的一个模块是 Ajax 模块,该模块能极大地简化 Ajax 的使用,使用它与进行其他 jQuery 方法调用一样简单直观。您还通过几个例子进一步领略了 Ajax 的强大功能并知道了 Ajax 是个很酷的工具,可在不重载页面和延迟的情况下加快应用程序的响应速度。此外,您了解了 Effects 包。并且知道,如果正确使用动画和隐藏/显示页面元素,将能大大增强 UI 设计。不仅如此,若能有效地综合使用,Ajax 和 Effects 还能极大地增加 Web 站点的动态性。

最后,您再次重温了这个示例 Web 应用程序,并体会了增加了 Ajax 模块后,您将能在无需重载页面的情况下读取和删除消息。然后您还看到了如何在 Web 应用程序中删除消息,并且通过综合 Ajax 和 Effects,还能从用户页面和 DB 删除消息,而这一切均无需重载此页面。对于用户而言,消息的删除是个透明的过程,而且您能通过编程实现此目的。

至此,与 JQuery 发布版一并提供的核心库相关的系列 JQuery 文章就结束了。这三篇文章为您一一展示了 jQuery 所包含的每个模块,让您看到了使用 jQuery 是多么容易和直观。此外,您还应该知道不管您所面对的是哪种 Web 应用程序,jQuery 应该都可以用来将其转变成任何类型的 RIA,因为 jQuery 是所有 JavaScript 需求的坚实基础。通过本系列文章对 jQuery 的介绍,您应该有信心在自己的代码中使用 jQuery。本系列的 第一篇文章 向您展示了 jQuery 是如何工作的,以及如何用它来搜索页面元素、循环遍历这些元素并像 Array 对象那样访问这些元素。本系列的 第二篇文章 向您介绍了对提供丰富性至关重要的三个模块。最后的这篇文章则给出了生成一个完整、复杂的 Web 应用程序所需的最后几个要素。



下载

描述名字大小下载方法
包含示例应用程序的 Zip 文件jquery.zip69KBHTTP
]]>
使用 jQuery 简化 Ajax 开发 http://www.phpv.net/html/1637.html http://www.phpv.net/html/1637.html#comment Sun, 26 Oct 2008 20:12:29 +0000 抽烟的蚊子 http://www.phpv.net/html/1637.html jQuery 是什么?

jQuery 由 John Resig 创建于 2006 年初,对于任何使JavaScript 代码的程序员来说,它是一个非常有用的 JavaScript 库。无论您是刚刚接触 JavaScript 语言,并且希望获得一个能解决文档对象模型(Document Object Model,DOM)脚本和 Ajax 开发中一些复杂问题的库,还是作为一个厌倦了 DOM 脚本和 Ajax 开发中无聊的重复工作的资深 JavaScript 专家,jQuery 都会是您的首选。

jQuery 能帮助您保证代码简洁易读。您再也不必编写大堆重复的循环代码和 DOM 脚本库调用了。使用 jQuery,您可以把握问题的要点,并使用尽可能最少的代码实现您想要的功能。

毫无疑问,jQuery 的原理是独一无二的:它的目的就是保证代码简洁并可重用。当您理解并体会这一原理后,便可以开始学习本教程了,看看 jQuery 对我们的编程方式有多少改进吧。





一些简单的代码简化

下面是一个简单示例,它说明了 jQuery 对代码的影响。要执行一些真正简单和常见的任务,比方说为页面的某一区域中的每个链接附加一个单击(click)事件,您可以使用纯 JavaScript 代码和 DOM 脚本来实现,如 清单 1 所示。


清单 1. 没有使用 jQuery 的 DOM 脚本
                
var external_links = document.getElementById('external_links');
var links = external_links.getElementsByTagName('a');
for (var i=0;i < links.length;i++) {
var link = links.item(i);
link.onclick = function() {
return confirm('You are going to visit: ' + this.href);
};
}

清单 2 显示了使用 jQuery 实现的相同的功能。


清单 2. 使用了 jQuery 的 DOM 脚本
                
$('#external_links a').click(function() {
return confirm('You are going to visit: ' + this.href);
});

是不是很神奇? 使用 jQuery,您可以把握问题的要点,只让代码实现您想要的功能,而省去了一些繁琐的过程。无需对元素进行循环,click() 函数将完成这些操作。同样也不需要进行多个 DOM 脚本调用。您只需要使用一个简短的字符串对所需的元素进行定义即可。

理解这一代码的工作原理可能会有一点复杂。首先,我们使用了 $() 函数 —— jQuery 中功能最强大的函数。通常,我们都是使用这个函数从文档中选择元素。在本例中,一个包含有一些层叠样式表(Cascading Style Sheet,CSS)语法的字符串被传递给函数,然后 jQuery 尽可能高效地把这些元素找出来。

如果您具备 CSS 选择器的基本知识,那么应该很熟悉这些语法。在 清单 2 中,#external_links 用于检索 idexternal_links 的元素。a 后的空格表示 jQuery 需要检索 external_links 元素中的所有 <a> 元素。用英语说起来非常绕口,甚至在 DOM 脚本中也是这样,但是在 CSS 中这再简单不过了

$() 函数返回一个含有所有与 CSS 选择器匹配的元素的 jQuery 对象。jQuery 对象 类似于数组,但是它附带有大量特殊的 jQuery 函数。比方说,您可以通过调用 click 函数把 click 处理函数指定给 jQuery 对象中的所有元素。

还可以向 $() 函数传递一个元素或者一个元素数组,该函数将把这些元素封装在一个 jQuery 对象中。您可能会想要使用这个功能将 jQuery 函数用于一些对象,比方说 window 对象。例如,我们通常会像下面这样把函数分配给加载事件:

window.onload = function() {
// do this stuff when the page is done loading
};

使用 jQuery 编写的功能相同的代码:

$(window).load(function() {
// run this when the whole page has been downloaded
});

您可能有所体会,等待窗口加载的过程 是非常缓慢而且令人痛苦的,这是因为必须等整个页面加载完所有的内容,包括页面上所有的的图片。有的时候,您希望首先完成图片加载,但是在大多数情况下, 您只需加载超文本标志语言(Hypertext Markup Language,HTML)就可以了。通过在文档中创建特殊的 ready 事件,jQuery 解决了这个问题,方法如下:

$(document).ready(function() {
// do this stuff when the HTML is all ready
});

这个代码围绕 document 元素创建了一个 jQuery 对象,然后建立一个函数,用于在 HTML DOM 文档就绪的时候调用实例。可以根据需要任意地调用这个函数。并且能够以真正的 jQuery 格式,使用快捷方式调用这个函数。这很简单,只需向 $() 函数传递一个函数就可以了:

$(function() {
// run this when the HTML is done downloading
});

到目前以止,我已经向大家介绍了 $() 函数的三种用法。第四种方法可以使用字符串来创建元素。结果会产生一个包含该元素的 jQuery 对象。清单 3 显示的示例在页面中添加了一个段落。


清单 3. 创建和附加一个简单的段落
                
$('<p></p>')
.html('Hey World!')
.css('background', 'yellow')
.appendTo("body");

在前一个例子中您可能已经注意到,jQuery 中的另一个功能强大的特性就是方法链接(method chaining)。每次对 jQuery 对象调用方法时,方法都会返回相同的 jQuery 对象。这意味着如果您需要对 jQuery 对象调用多个方法,那么您不必重新键入选择器就可以实现这一目的:

$('#message').css('background', 'yellow').html('Hello!').show();







使 Ajax 变得简单

使用 jQuery 将使 Ajax 变得及其简单。jQuery 提供有一些函数,可以使简单的工作变得更加简单,复杂的工作变得不再复杂。

Ajax 最常见的用法就是把一块 HTML 代码加载到页面的某个区域中去。为此,只需简单地选择所需的元素,然后使用 load() 函数即可。下面是一个用于更新统计信息的示例:

$('#stats').load('stats.html');

通常,我们只需简单地把一些参数传递给服务器中的某个页面。正如您所预料的,使用 jQuery 实现这一操作非常地简单。您可以使用 $.post() 或者 $.get(),这由所需的方法决定。如果需要的话,您还可以传递一个可选的数据对象和回调函数。清单 4 显示了一个发送数据和使用回调的简单示例。


清单 4. 使用 Ajax 向页面发送数据
                
$.post('save.cgi', {
text: 'my string',
number: 23
}, function() {
alert('Your data has been saved.');
});

如果您确实需要编写一些复杂的 Ajax 脚本,那么需要用到 $.ajax() 函数。您可以指定 xmlscripthtml 或者 json,jQuery 将自动为回调函数准备合适的结果,这样您便可以立即使用该结果。还可以指定 beforeSenderrorsuccess 或者 complete 回调函数,向用户提供更多有关 Ajax 体验的反馈。此外,还有一些其它的参数可供使用,您可以使用它们设置 Ajax 请求的超时,也可以设置页面 “最近一次修改” 的状态。清单 5 显示了一个使用一些我所提到的参数检索 XML 文档的示例。


清单 5. $.ajax() 使 Ajax 由复杂变简单
                
$.ajax({
url: 'document.xml',
type: 'GET',
dataType: 'xml',
timeout: 1000,
error: function(){
alert('Error loading XML document');
},
success: function(xml){
// do something with xml
}
});

当 success 回调函数返回 XML 文档后,您可以使用 jQuery 检索这个 XML 文档,其方式与检索 HTML 文档是一样的。这样使得处理 XML 文档变得相当地容易,并且把内容和数据集成到了您的 Web 站点里面。清单 6 显示了 success 函数的一个扩展,它为 XML 中的每个 <item> 元素都添加了一个列表项到 Web 页面中。


清单 6. 使用 jQuery 处理 XML 文档
                
success: function(xml){
$(xml).find('item').each(function(){
var item_text = $(this).text();

$('<li></li>')
.html(item_text)
.appendTo('ol');
});
}







为 HTML 添加动画

可以使用 jQuery 处理基本的动画和显示效果。animate() 函数是动画代码的核心,它用于更改任何随时间变化的数值型的 CSS 样式值。比方说,您可以变化高度、宽度、不透明度和位置。还可以指定动画的速度,定为毫秒或者预定义的速度:慢速,中速或快速。

下面是一个同时变化某个元素高度和宽度的示例。请注意,这些参数没有开始值,只有最终值。开始值取自元素的当前尺寸。同时我也附加了一个回调函数。

$('#grow').animate({ height: 500, width: 500 }, "slow", function(){
alert('The element is done growing!');
});

jQuery 的内置函数使更多常见的动画更容易完成。可以使用 show()hide() 元素,立即显示或者以特定的速度显示。还可以通过使用 fadeIn()fadeOut(),或者 slideDown()slideUp() 显示和隐藏元素,这取决于您所需要的显示效果。下面的示例定义了一个下滑的导航菜单。

$('#nav').slideDown('slow');







DOM 脚本和事件处理

或许 jQuery 最擅长的就是简化 DOM 脚本和事件处理。遍历和处理 DOM 非常简单,同时附加、移除和调用事件也十分容易,且不像手动操作那样容易出错。

从本质上说,jQuery 可以使 DOM 脚本中的常用操作变得更加容易。您可以创建元素并且使用 append() 函数把它们与其它的一些元素链接到一起,使用 clone() 复制元素,使用 html() 设置内容,使用 empty() 函数删除内容,使用 remove() 函数删除所有的元素,即便是使用 wrap() 函数,用其他元素将这些元素包装起来。

通过遍历 DOM,一些函数可以用于更改 jQuery 对象本身的内容。可以获得元素所有的 siblings()parents()children()。还可以选择 next()prev() 兄弟元素。find() 函数或许是功能最强大的函数,它允许使用 jQuery 选择器搜索 jQuery 对象中元素的后代元素。

如果结合使用 end() 函数,那么这些函数将变得更加强大。这个函数的功能类似于 undo 函数,用于返回到调用 find()parents() 函数(或者其它遍历函数)之前的 jQuery 对象。

如果配合方法链接(method chaining)一起使用,这些函数可以使复杂的操作看上去非常简单。清单 7 显示了一个示例,其中包含有一个登录表单并处理了一些与之有关的元素。


清单 7. 轻松地遍历和处理 DOM
                
$('form#login')
// hide all the labels inside the form with the 'optional' class
.find('label.optional').hide().end()

// add a red border to any password fields in the form
.find('input:password').css('border', '1px solid red').end()

// add a submit handler to the form
.submit(function(){
return confirm('Are you sure you want to submit?');
});

不管您是否相信,这个示例只是一行满是空白的被链接的代码。首先,选择登录表单。然后,发现其中含有可选标签,隐藏它们,并调用 end() 返回表单。然后,我创建了密码字段,将其边界变为红色,再次调用 end() 返回表单。最后,我在表单中添加了一个提交事件处理程序。其中尤为有趣的就是(除了其简洁性以外),jQuery 完全优化了所有的查询操作,确保将所有内容很好地链接在一起后,不需要对一个元素执行两次查询。

处理常见事件就像调用函数(比方说 click()submit()mouseover())和为其传递事件处理函数一样简单。此外,还可以使用 bind('eventname', function(){}) 指定自定义的事件处理程序。可以使用 unbind('eventname') 删除某些事件或者使用 unbind() 删除所有的事件。有关这些函数的使用方法的完整列表,请参阅 参考资料 中的 jQuery 应用程序编程接口(Application Program Interface,API)文档。







释放 jQuery 选择器的强大能量

我们经常会使用 ID 来选择元素,比如 #myid,或者通过类名,比如 div.myclass 来选择元素。然而,jQuery 提供了更为复杂和完整的选择器语法,允许我们在单个选择器中选择几乎所有的元素组合。

jQuery 的选择器语法主要是基于 CSS3 和 XPath 的。对 CSS3 和 XPath 了解的越多,使用 jQuery 时就越加得心应手。有关 jQuery 选择器的完整列表,包括 CSS 和 XPath,请参阅 参考资料 中的链接。

CSS3 包含一些并不是所有浏览器都支持的语法,因此我们很少使用它。然而,我们仍然可以在 jQuery 中使用 CSS3 选择元素,因为 jQuery 具备自己的自定义选择器引擎。比方说,要在表格中的每一个空列中都添加一个横杠,可以使用::empty 伪选择器(pseudo-selector):

$('td:empty').html('-');

如果需要找出所有含特定类的元素呢? CSS3 同样提供了一个语法可以完成这个目的,使用 :not 伪选择器: 如下代码显示了如何隐藏所有不含 required 类的输入内容:

$('input:not(.required)').hide();

与在 CSS 中一样,可以使用逗号将多个选择器连接成一个。下面是一个同时隐藏页面上所有类型列表的简单示例:

$('ul, ol, dl').hide();

XPath 是一种功能强大的语法,用于在文档中搜寻元素。它与 CSS 稍有区别,不过它能实现的功能略多于 CSS。要在所有复选框的父元素中添加一个边框,可以使用 XPath 的 /.. 语法:

$("input:checkbox/..").css('border', '1px solid #777');

jQuery 中也加入了一些 CSS 和 XPath 中没有的选择器。比方说,要使一个表更具可读性,通常可以在表格的奇数行或偶数行中附加一个不同的类名 —— 也可以称作把表分段(striping)。使用 jQuery 不费吹灰之力就可以做到这点,这需要归功于 odd 伪选择器。下面这个例子使用 striped 类改变了表格中所有奇数行的背景颜色:

$('table.striped > tr:odd').css('background', '#999999');

我们可以看到强大的 jQuery 选择器是如何简化代码的。不论您想处理什么样的元素,不管这个元素是具体的还是模糊的,都有可能找到一种方法使用一个 jQuery选择器对它们进行定义。







使用插件扩展 jQuery

与大多数软件不同,使用一个复杂的 API 为 jQuery 编写插件并不是非常困难。事实上,jQuery 插件非常易于编写,您甚至希望编写一些插件来使代码更加简单。下面是可以编写的最基本的 jQuery 插件:

$.fn.donothing = function(){
return this;
};

虽然非常简单,但是还是需要对这个插件进行一些解释。首先,如果要为每一个 jQuery 对象添加一个函数,必须把该函数指派给 $.fn。第二,这个函数必须要返回一个 this(jQuery 对象),这样才不至于打断 方法链接(method chaining)

可以轻松地在这个示例之上构建。要编写一个更换背景颜色的插件,以替代使用 css('background'),可以使用下面的代码:

$.fn.background = function(bg){
return this.css('background', bg);
};

清注意,可以只从 css() 返回值,因为已经返回了 jQuery 对象。因此,方法链接(method chaining)仍然运作良好。

我建议在需要重复工作的时候使用 jQuery 插件。比方说,如果您需要使用 each() 函数反复执行相同的操作,那么可以使用一个插件来完成。

由于 jQuery 插件相当易于编写,所以有上百种可供你选择使用。jQuery 提供的插件可用于制表、圆角、滑动显示、工具提示、日期选择器,以及我们可以想到的一切效果。有关插件的完整列表,请参阅 参考资料

最 为复杂、使用最为广泛的插件要属界面(Interface),它是一种动画插件,用于处理排序、拖放功能、复杂效果、以及其它有趣和复杂的用户界面 (User Interface,UI)。界面对于 jQuery 来说就如 Scriptaculous 对于 Prototype 一样。

表单插件也同样流行且非常有用,通过它可以使用 Ajax 在后台中轻松地提交表单。这个插件用于处理一些常见的情况:您需要截获某个表单的提交事件,找出所有不同的输入字段,并使用这些字段构造一个 Ajax 调用。







结束语

我 只是简要地介绍了使用 jQuery 可能完成的任务。jQuery 使用起来非常有趣,因此我们总是能学到看上去很简单的新技巧和新特性。从刚开始使用 jQuery 的那一刻起,jQuery 便可以完全简化您的 JavaScript 和 Ajax 编程;每学会一点新知识,您的代码就会更简单一点。

学习了 jQuery 之后,我在使用 JavaScript 语言进行编程的同时也获得了许多的乐趣。不用操心所有无聊的内容,我可以专注地编写有趣的内容。使用 jQuery 后,我几乎就告别了编写 for 循环代码的时代。甚至在想到要使用其它 JavaScript 库时,不禁会有所畏缩不前。jQuery 确确实实改变了我对 JavaScript 编程的看法。



参考资料

学习
  • 您可以参阅本文在 developerWorks 全球网站上的 英文原文

  • Ajax 技术资源中心:developerWorks 上所有有关 Ajax 的问题都可以在这里找到解答。

  • developerWork 中国网站 XML 专区:了解 XML 的方方面面。

  • jQuery API 文档:通过一些教程和 API 参考资料的链接,研究完整的 jQuery 的文档。

  • jQuery 教程:参阅各种不同语言的 jQuery 教程,包括 40 篇英语文章。

  • 可视化 jQuery:阅读这个交互式的、易于导航的 jQuery API 参考资料。

  • IBM XML 认证:看看如何才能成为一名 IBM 认证的 XML 及相关技术的开发人员。

  • XML 技术文档库:developerWorks XML 专区提供了大量技术文章、提示、教程、标准以及 IBM 红皮书。


获得产品和技术
  • jQuery:访问 jQuery 主页并下载源代码。

  • 选择器:获取在 jQuery 中可以使用的选择器的完整列表,包括 CSS3 和 XPath 选择器。

  • jQuery 插件:获取可以使用的 jQuery 插件的完整列表。

  • Interface:尝试使用 jQuery 最基本的插件,可用于动画、显示效果、拖放功能和用户界面(UI)。

  • Form 插件:获取 jQuery 插件,它可用于使用 Ajax 提交表单。


讨论


关于作者

Photo of Jesse Skinner

Jesse Skinner 是一名自由的 Web 开发人员,致力于 JavaScript 和 CSS 的开发。他从加拿大移居到德国,主要研究如何使 Web 使用起来更加有趣,并解开了由来已久的 CSS 浏览器兼容性难题。如果想进一步了解 Jesse 或者阅读更多有关 Web 开发的内容,请参阅他的博客 The Future of the Web

]]>
最常用和实用的CSS技巧 http://www.phpv.net/html/1629.html http://www.phpv.net/html/1629.html#comment Wed, 03 Sep 2008 18:29:35 +0000 抽烟的蚊子 http://www.phpv.net/html/1629.html 下面是CSS最常用和实用的技巧。 


1.重置浏览器的字体大小
 
重置浏览器的默认值 ,然后重设浏览器的字体大小你可以使用雅虎的用户界面重置的CSS方案 ,如果你不想下载9MB的文件,代码如下: 
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,
blockquote,th,td {margin:0; padding:0; }
table { border-collapse:collapse; border-spacing:0; }
fieldset,img { border:0; }
address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
ol,ul { list-style:none; }
caption,th { text-align:left; }
h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; }
q:before,q:after { content:”; }
abbr,acronym { border:0; }

其次,我们重设浏览器字体的大小为10像素,使用如下: 
html {font-size: 62.5%;}

这个大小基本合适,然后您可以根据自己的需要调整大小,如 标题1为120像素: 
h1 {font-size: 2em;}


2.设置水平居中
 
大多数的网站目前都是固定宽度的。CSS代码如下: 
div#container {margin: 0 auto;}


3.控制位置:绝对位置,相对位置 
假如有两个div 
<div id='parent'>
<div id='son'></div>
</div>

div有left和top属性,是用来定位的. 
如果内层的div的position属性是absolute.那他就是相对于文档的左上角的位置.. 
如果内层的div(id为son的那个)position属性为relative,那它的left和top值就是相对于外层的div的左上角的距离. 


4.将重要元素放置在屏幕中央
 
如果你希望将您想要的东西放在最中央,可以使用以下CSS: 
div.popup { height:400px; width:500px; position: absolute; top: 50%; left: 50%;}
div.popup { margin-top: -200px; margin-left: -250px;}

您必须明确的指定宽度和高度,再把top和left属性设为他们的一半,这样就可以是这个部分回到屏幕的中心。 


5.可以重复利用的规则
 
.left {float: left;}
.right {float: right;}
img .left { border:2px solid #aaaaaa; margin: 0 10px 0 0;}
img .right { border:2px solid #aaaaaa; margin: 0 0 0 10px; padding: 1px;}

设置自己的CSS样式表,就可以在您需要的时候直接的添加标记即可。 
 


6. 解决IE6 的浮动元素的双倍边距问题
 
对一个div设置了float:left 和 margin-left:100px 那么在IE6中,这个bug就会出现。您只需要多设置一个display即可,代码如下: 
div {float:left;margin:40px;display:inline;}



7.简单的导航菜单
 
在您的设计中预设一个导航栏是非常有益的。可以让别人对你网页的主要内容有一个大致的了解。第一次来的XHTML: 
<div id=”navbar”>
<ul>
<li><a href=”http://www.peakflowdesign.com”>Peakflow Design</a></li>
<li><a href=”http://www.google.com”">Google</a></li>
<li><a href=”http://zenhabits.net/”>Zen Habits</a></li>
</ul>
</div>

CSS代码: 
#navbar ul li {display:inline;margin:0 10px 0 0;}
#navbar ul li a {color: #333;display:block;float:left;padding:5px;}
#navbar ul li a:hover {background:#eee;color:black;}


8.不使用table的form表单
 
正如我们现在进行网站设计的table-free,把重点是放在使用DIVs上。不再对表的列和域进行约束,所以我们需要一些好用的CSS,在JeddHowden.com 发现 
XHTML:
<form action=”form.php” method=”post”>
<fieldset>
<legend>Personal Information</legend>
<div>
<label for=”first_name”>First Name:</label>
<input type=”text” name=”first_name” id=”first_name” size=”10″ value=”" />
</div>
<div>
<label for=”last_name”>Last Name:</label>
<input type=”text” name=”last_name” id=”last_name” size=”10″ value=”" />
</div>
<div>
<label for=”postal”>Zip/Postal Code:</label>
<input type=”text” name=”postal” id=”postal” size=”10″ value=”" />
</div>
</fieldset>
</form>


CSS:
form div {clear:left;display:block;width:400px;zoom:1;margin:5px 0 0 0;padding:1px 3px;}
form div label {display:block;float:left;width:130px;padding:3px 5px;margin: 0 0 5px 0;text-align:right;}


9.让footer总是停留在页面的底部
 
在网页的底部总是保留着公司的版本信息,如何是这部分信息来实现呢?这是一个很古老的技术,这都要归功于The Man in Blue  
XHTML:
<body>
<div id=”nonFooter”>
<div id=”content”> *Place all page content here* </div>
</div>
<div id=”footer”> *Place anything you want in your footer here*
</div>
</body>

CSS:
html, body { height: 100%; }
#nonFooter { position: relative; min-height: 100%; }
* html #nonFooter { height: 100%; }
#content { padding-bottom: 9em; }
#footer { position: relative; margin-top: -7.5em; }

10.在同一元素上使用多种类 
随着有用的功能越来越多的,大多数的人都忽略了内部CSS的选择。一个元素可以套用很多的类,例如: 
.red {color: red;}
.bold {font-weight: strong;}

我们可以运用它: 
<p class=”red bold”>This text will be red yet also bold!</p>

希望这些能对您有所帮助! 
]]>
推荐17个节省时间的CSS工具 http://www.phpv.net/html/1603.html http://www.phpv.net/html/1603.html#comment Fri, 06 Jun 2008 00:35:33 +0000 抽烟的蚊子 http://www.phpv.net/html/1603.html 原文作者:Brett
原文链接:14 CSS Tools to Save you Time
译者:Chada

作为一个网站设计/开发人员,你必须不断寻找方法来减少设计/开发过程中所花费的时间。这对于提高你的工作效率并最大化你的利润是非常重要的。下面介绍的按功能分类的CSS工具可以有效地节省你设计网站的时间。Chada在这基础上增加了三个自己曾经介绍过的工具。

优化/格式化类

1、CSSTidy - CSS Tidy是一个开源的CSS分析和优化工具;
2、CleanCSS - CleanCSS是一个基于CSS Tidy的强大的CSS优化和格式化工具。Chada曾经介绍过这个在线工具,在这里
3、CSS Optimizer - CSS Optimizer可以通过优化压缩CSS样式文件大小。
4、CSS Analyzer - CSS Analyzer可以帮助你检查你的CSS样式是否符合W3C的认证。

字体类

1、Em Calculator - EM Calculator可以帮助你计算px与em之间的转换。
2、CSS Font and Text Style Wizard - 这个小工具可以很方便地将你的CSS样式呈现出来。

表格类

1、CSS Form Code Maker - 很方便地生成“五颜六色的BOX布局”的表格。
2、JotForm - JotForm是一个“所见即所得”的表格生成器。

导航/按钮类

1、CSS Buttons - CSS按钮和文本在线生成工具。
2、CSS Menu Generator - CSS Menu Generator可以同时生成基于CSS和HTML代码的漂亮的按钮。

生成器

1、CSS Creator - Css Creator是一个可以创建自适应宽度或者是固定宽度的浮动布局生成器,可以生成带有Header和Footer的三栏布局。
2、QrONE CSS Designer - QrONE是一个CSS在线生成与编辑器。
3、Web 2.0 Generator - Web 2.0 Generator可以利用HTML和CSS生成一个完整的网站布局。
4、CSS Mate - CSS Mate是一个在线CSS编辑器。

除了上面译文中的14个小工具外,Chada还介绍过如下几款小工具,它们也是非常棒的,你可以打开下面的文章看它们的详细介绍:

1、CSS Menu Maker - 在线生成丰富多样的CSS导航按钮。
2、CSS Type Set - 在线轻松调试CSS文本样式。
3、CSS Frame Generator - 写好DIV架构之后,使用这个在线工具可以很快生成CSS样式结构表。

如果你有知道的其他可以节省时间的CSS在线工具,欢迎写下评论把它[们]介绍给Chada。

--------------------------------------------------------------------

另外:本站支持评分和评论了.
再另外:如果有好的文章,欢迎投递.


]]>
Ajax+PHP简单入门教程 http://www.phpv.net/html/1594.html http://www.phpv.net/html/1594.html#comment Fri, 14 Mar 2008 11:08:48 +0000 抽烟的蚊子 http://www.phpv.net/html/1594.html Ajax 由 HTML、JavaScript™ 技术、DHTML 和 DOM 组成,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序。对于Ajax,最核心的一个对象是XMLHttpRequest,所有的Ajax操作都离不开对这个对象的操作。

首先我们来了解怎么在javascript中创建这个对象:

var xmlHttp = new XMLHttpRequest();

这行简单的代码在 Mozilla、Firefox、Safari、Opera 以及基本上所有以任何形式或方式支持 Ajax 的非 Microsoft 浏览器中,创建了 XMLHttpRequest 对象。但是对于市场占有率达到70%的IE来说,这种方法是不行的,而不同的IE版本还有不同的创建方法,所以我们需要在IE下面使用下面两种创建对象的办法:

try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");//针对较新的浏览器
} catch (err) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");//针对较老的浏览器
} catch (err2) {
xmlHttp = false;
}
}

即使这样,我们也无法预料有些浏览器可能无法创建这个对象,所以在创建不成功的情况下,我们还要加上一句:

if (!xmlHttp){
alert("无法创建 XMLHttpRequest 对象!");
}

结合起来就是:

var xmlHttp = false;
try {
xmlHttp = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
xmlHttp = false;
}
}
}
if (!xmlHttp){
alert("无法创建 XMLHttpRequest 对象!");
}

然后,让我们建立一个函数getInfo(),打开异步请求:

function getInfo() {
var num = document.getElementById("num").value;//获得表单的数据
var url = "/ajax/1.php?n=" + escape(num);
xmlHttp.open("GET", url, true);//这里的true代表是异步请求
}

一旦用 open() 配置好之后,就可以发送请求了。虽然可以使用 send() 发送数据,但也能通过 URL 本身发送数据。事实上,在大部分GET 请求中,用 URL 发送数据要容易得多,所以这里用null作为send()的参数就可以了。url地址里面的php文件是被请求来处理所需要数据的php文件,就像我们平时用PHP的时候一样,后面的参数可以加多个,并用&分隔开来。

xmlHttp.send(null);

在发送了数据之后,我们需要用回调方法来获得服务器的状态,所以就用到了onreadystatechange 属性。

xmlHttp.onreadystatechange = updatePage;

此语句已经要放在send()语句前面,这样才会有效,后面的updatePage是处理返回信息的一个函数。完整的getInfo()如下:

function getInfo() {
var num = document.getElementById("num").value;//获得表单的数据
var url = "/ajax/1.php?n=" + escape(num);
xmlHttp.open("GET", url, true);//这里的true代表是异步请求
xmlHttp.onreadystatechange = updatePage;
xmlHttp.send(null);
}

我们还需要在html里面来触发这个函数:

<input name="num" id="num" onblur="getInfo()" type="text" />

下面我们需要来编写updatePage()这个函数:

function updatePage(){
if (xmlhttp.readyState == 4) {
var response = xmlhttp.responseText;
document.getElementById("city").value = response;
}
}

上面这段代码里面的readyState是服务器返回的一个状态,4这个状态表示请求已经发送,并处理完毕。responseText是获得服务器返回的信息,然后通过javascript赋给ID为city的表单。

到此,一个简单的Ajax程序就完成了,完整的javascript代码如下:

var xmlHttp = false;
try {
xmlHttp = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
xmlHttp = false;
}
}
}
if (!xmlHttp){
alert("无法创建 XMLHttpRequest 对象!");
}
 
function getInfo() {
var num = document.getElementById("num").value;//获得表单的数据
var url = "/ajax/1.php?n=" + escape(num);
xmlHttp.open("GET", url, true);//这里的true代表是异步请求
xmlHttp.onreadystatechange = updatePage;
xmlHttp.send(null);
}
 
function updatePage(){
if (xmlhttp.readyState == 4) {
var response = xmlhttp.responseText;
document.getElementById("city").value = response;
}
}

这里还缺一个php文件,由于处理的方式不一样,写法也不一样,而且这不是Ajax的主要部分,所以这里就不放代码了。只要记住php是输出并返回所需要的数据就可以了。


好久没更新,今天看到这教程,对初学者挺适合.

]]>
JavaScript程序编码规范 中文版 http://www.phpv.net/html/1591.html http://www.phpv.net/html/1591.html#comment Wed, 23 Jan 2008 15:08:05 +0000 抽烟的蚊子 http://www.phpv.net/html/1591.html 前言

Any violation to this guide is allowed if it enhances readability.

所有的代码都要变成可供他人容易阅读的。

软件的长期价值直接源于其编码质量。在它的整个生命周期里,一个程序可能会被许多人阅读或修改。如果一个程序可以清晰的展现出它的结构和特征,那就能减少在以后对其进行修改时出错的可能性。

编程规范可以帮助程序员们增加程序的健壮性。所有的 JavaScript 代码都是暴露给公众的。所以我们更应该保证其质量。保持整洁很重要。

JavaScript文件

JavaScript 程序应独立保存在后缀名为 .js 的文件中。

JavaScript 代码不应该被包含在 HTML 文件中,除非这是段特定只属于此部分的代码。在 HTML 中的JavaScript代码会明显增加文件大小,而且也不能对其进行缓存和压缩。

filename.js 应尽量放到 body 的后面。这样可以减少因为载入脚本而造成其他页面内容载入也被延迟的问题。也没有必要使用 language 或者 type 属性。MIME 类型是由服务器而非 scripttag 来决定的。(手气不错:个人认为按照 Web 标准而言,建议指定 type 属性,并将 <script> 放到页面的 <head> 中。)

缩进

缩进的单位为四个空格。避免使用 Tab 键来缩进。因为始终没有个统一的 Tab 长短标准。虽然使用空格会增加文件的大小,但在局域网中几乎可以忽略,且在最小化过程中也可被消除掉。

每行长度

避免每行超过 80 个字符。当一条语句一行写不下时,请考虑折行。在运算符号,最好是逗号后换行。在运算符后换行可以减少因为复制粘贴产生的错误被分号掩盖的几率。

注释

不要吝啬注释。给以后需要理解你的代码的人们(或许就是你自己)留下信息是非常有用的。注释应该和它们所注释的代码一样是书写良好且清晰明了。偶尔的小幽默就更不错了。记得要避免冗长或者情绪化。

及时地更新注释也很重要。错误的注释会让程序更加难以阅读和理解。

让注释有意义。重点在解释那些不容易立即明白的逻辑上。不要把读者的时间浪费在阅读类似于:

i = 0; // 让 i 等于 0

使用单行注释。块注释用于注释正式文档和无用代码。

变量声明

所有的变量必须在使用前进行声明。JavaScript 并不强制必须这么做,但这么做可以让程序易于阅读,且也容易发现那些没声明的变量(它们会被编译成全局变量)。

将 var 语句放在函数的首部。

最好把每个变量的声明语句单独放到一行,并加上注释说明。所有变量按照字母排序。

var currentEntry; // 当前选择项
var level; // 缩进程度
var size; // 表格大小

JavaScript 没有块范围,所以在块里面定义变量很容易引起 C/C++/Java 程序员们的误解。在函数的首部定义所有的变量。

尽量减少全局变量的使用。不要让局部变量覆盖全局变量。

函数声明


所有的函数在使用前进行声明。 内函数的声明跟在 var 语句的后面。这样可以帮助判断哪些变量是在函数范围内的。

函数名与“(”(左括号)之间不应该有空格。“)”(右括号)与开始程序体的“{”(左大括号)之间应插入一个空格。函数程序体应缩进四个空格。“}”(右大括号)与声明函数的那一行代码头部对齐。

function outer(c,d) {
var e = c * d;

function inner(a, b) {
return (e * a) + b;
}

return inner(0, 1);
}

下面这种书写方式可以在 JavaScript 中正常使用,因为在 JavaScript 中,函数和对象的声明可以放到任何表达式允许的地方。且它让内联函数和混合结构具有最好的可读性。

function getElementsByClassName(className) {

var results = [];

walkTheDOM(document.body, function (node) {

var a; // array of class names

var c = node.className; // the node's classname

var i; // loop counter

// If the node has a class name, then split it into a list of simple names.

// If any of them match the requested name, then append the node to the set of results.

if (c) {

a = c.split(' ');

for (i = 0; i < a.length; i += 1) {

if (a[i] === className) {

results.push(node);

break;

}

}

}

});

return results;

}



如果函数是匿名函数,则在 function 和 “(”(左括号)之间应有一个空格。如果省略了空格,否则会让人感觉函数名叫作 function。


div.onclick = function (e) {

return false;

};

that = {

method: function () {

return this.datum;

},

datum: 0

};

尽量不使用全局函数。

命名


变量名应由 26 个大小写字母(A..Z,a..z),10 个数字(0..9),和 “_”(下划线)组成。避免使用国际化字符(如中文),因为它们不是在任何地方都可以被方便的阅读和理解。不要在命名中使用 “$”(美元符号)或者 “”(反斜杠)。

不要把 “_”(下划线)作为变量名的第一个字符。它有时用来表示私有变量,但实际上 JavaScript 并没提供私有变量的功能。如果私有变量很重要,那么使用 私有成员 的形式。应避免使用这种容易让人误解的命名习惯。

大多数的变量名和方法命应以小写字母开头。

必须与 new 共同使用的构造函数名应以大写字母开头。当 new 被省略时 JavaScript 不会有任何编译错误或运行错误抛出。忘记加 new 时会让不好的事情发生(比如被当成一般的函数),所以大写构造函数名是我们来尽量避免这种情况发生的唯一办法。

全局变量应该全部大写。(JavaScript 没有宏或者常量,所以不会因此造成误会)

语句

简单语句

每一行最多只包含一条语句。把 “,” (分号)放到每条简单语句的结尾处。注意一个函数赋值或对象赋值语句也是赋值语句,应该以分号结尾。

JavaScript 可以把任何表达式当作一条语句。这很容易隐藏一些错误,特别是误加分号的错误。只有在赋值和调用时,表达式才应被当作一条单独的语句。

复合语句


复合语句是被包含在 “{ }”(大括号)的语句序列。

被括起的语句必须多缩进四个空格。

“{”(左大括号)应在复合语句其实行的结尾处。

“}”(右大括号)应与“{”(左大括号)的那一行的开头对齐。

大括号应该在所有复合语句中使用,即使只有一条语句,当它们是控制结构的一部分时,比如一个 if 或者 for 语句。这样做可以避免以后添加语句时造成的错误。

标示

语句标示是可选的,只有以下语句必须被标示:while、do、for、switch。

return 语句

一条有返回值的 return 语句不要使用“( )”(括号)来括住返回值。如果返回表达式,则表达式应与 return 关键字在同一行,以避免误加分号错误。

if 语句

if 语句应如以下格式:

if (condition){

statements;

}

if (condition) {

statements;

} else {

statements;

}

if (condition) {

statements;

} else if (condition) {

statements;

} else {

statements;

}

for 语句

for 语句应如以下格式:

for (initialization;condition; update) {

statements;

}



for (variable in object) if (filter) {

statements;

}

第一种形式的循环用于已经知道相关参数的数组循环。

第二种形式应用于对象中。Object 原型中的成员将会被包含在迭代器中。通过预先定义 hasOwnProperty方法来区分真正的 object 成员是个不错方法:

for (variablein object) if (object.hasOwnProperty(variable)){

statements;

}

while 语句

while 语句应如以下格式:

while (condition){

statements;

}

do 语句

do 语句应如以下格式:

do {

statements;

} while (condition);

不像别的复合语句,do 语句总是以 “;”(分号)结尾。

switch 语句

switch 语句应如以下格式:

switch (expression){

case expression:

statements;

default:

statements;

}

每个 case 与 switch 对齐。这可避免过分缩进。

每一组 statements(除了default 应以 break,return,或者 throw 结尾),不要让它顺次往下执行。

try 语句


try 语句应如以下格式:

try {

statements;

} catch (variable){

statements;

}



try {

statements;

} catch (variable){

statements;

} finally {

statements;

}

continue 语句

避免使用 continue 语句。它很容易使得程序的逻辑过程晦涩难懂。
with 语句

不要使用 with 语句。

空白


用空行来将逻辑相关的代码块分割开可以提高程序的可读性。空格应在以下情况时使用:

跟在“(”(左括号)后面的关键字应被一个空格隔开。

while (true) {

函数参数与“(”(左括号)之间不应该有空格。这能帮助区分关键字和函数调用。所有的二元操作符,除了“.”(点) 和“(”(左括号)和 “[”(左方括号)应用空格将其与操作数隔开。

一元操作符与其操作数之间不应有空格,除非操作符是个单词,比如 typeof。

每个在控制部分,比如 for 语句中的 “;”(分号)后须跟一个空格。

每个 “,”(逗号)后应跟一个空格。

另外的建议


{} 和[]

使用 {} 代替 new Object()。使用 [] 代替 new Array() 。

当成员名是一组有序的数字时使用数组来保存数据。当成员名是无规律的字符串或其他时使用对象来保存数据。

,(逗号)操作符

避免使用逗号操作符,除非在特定的 for 语句的控制部分。(这不包括那些被用在对象定义,数组定义,var 语句,和参数列表中的逗号分隔符。)

作用域

在 JavaScript 中块没有域。只有函数有域。不要使用块,除非在复合语句中。

赋值表达式

避免在 if 和 while 语句的条件部分进行赋值。

if (a = b) {

是一条正确语句? 或者

if (a == b) {

才是对的? 避免这种不容易判断对错的结构。

=== 和 !== 操作符。

使用 === 和 !== 操作符会相对好点。== 和 != 操作符会进行类型强制转换。 特别是, 不要将 == 用于与错值比较(false,null,undefined,“”,0,NaN)。

令人迷惑的加号和减号


小心在 + 后紧跟 + 或 ++。这种形式很容易仍人迷惑。应插入括号以便于理解。

total = subtotal + +myInput.value;

最好能写成

total = subtotal + (+myInput.value);

这样 + + 不会被误认为是 ++。

eval 是恶魔

eval 是 JavaScript 中最容易被滥用的方法。避免使用它。

eval 有别名。不要使用 function 构造器。不要给 setTimeout 或者 setInterval 传递字符串参数。


英文版:http://javascript.crockford.com/code.html
翻译:手气不错
整理日期:2008年01月22日

]]>
Web开发设计的五大准则 http://www.phpv.net/html/1588.html http://www.phpv.net/html/1588.html#comment Wed, 02 Jan 2008 23:39:55 +0000 抽烟的蚊子 http://www.phpv.net/html/1588.html 如果仓促而为,设计一个专题或者网站一定会成为恶梦。Web设计需要遵循一些准则并有计划地去做。

规则 #1 : 先出设计图

这是必须的。不要假设设计图在你的头脑中就开始设计web,必须要放到纸上。可以这样做:

1,  拿尺子、笔和纸,按照具体的尺寸一行一行地画下来;

2,  记得考虑分界线的长度等,这样才能符合CSS的像素;

3,  记下设计的每一个细节免得忘记,如果把所有细节都累积到最后将是巨大的麻烦。

规则 #2 :配色

这是设计的核心部分,只有颜色搭配合适才能使你的网页看起来不错。首先要决定的是主色,也即你在网页中多数使用的颜色;然后选择跟主色调搭配的第二颜色;不要选择超过三种颜色不然你的设计看起来会很乱。如果你想要更多的颜色,可以使用浅色或者深色的阴影来搭配主色调。

1,  浏览十个跟你网页有同样主色调的网页;

2,  给几个人看你的配色方案并取得反馈;

3,  从浏览的网页和反馈你将更好地完善你的颜色搭配。

规则 #3 : 从基本的版块开始构建

定下配色和设计图之后,从最基本的框架开始构建——我的意思是说不添加任何文本。因为在版面中加入文本会使得架构混乱。方法如下:

1,  每一个版块设定边界线,这样能够看到具体的尺寸和位置;

2,  对不同的版块使用不同的颜色,在完成版块后再改成你想要的颜色。

规则 #4 : 理清CSS

不要在你的HTML文件中将styling元素搞得太复杂,不然等到你修改的时候你就不得不到处搜索。所以将所有styling元素归置在一个单独的CSS文档中。

在styling之前理清你的CSS免得太过杂乱导致你多次重复同一件事。CSS支持继承,也即parent block的style可以用于child block.,充分利用这条特性。命名CSS分类名也要易懂易记。比如使用“main_content”而不是“div_1”。

规则 #5 : 制订多重 CSS 文档

我们都知道,使用浏览器可以轻易地看到网页的输出,但使用另一浏览器的时候则可能发现输出不正常。这不是什么稀奇事儿,因为每个浏览器对HTML和CSS的处理方式都不一样。

为避免这种情况,每个浏览器准备一个CSS文档,这样所有浏览器都可以正常浏览。虽然这有一定的难度,但是记着指望一个CSS文档来满足所有浏览器是不可能的。



原文作者:nitinpai
原文链接:5 Rules For A Good Web Design
译者:小猪哥

]]>
给网站开发和设计者的10点建议 http://www.phpv.net/html/1556.html http://www.phpv.net/html/1556.html#comment Tue, 11 Sep 2007 11:17:25 +0000 抽烟的蚊子 http://www.phpv.net/html/1556.html 给网站开发和设计者的10点建议

作者:Chrys Bader
翻译:htmlor

1. 使用Firefox

Firefox是你触手可及的最重要的平台,网站开发时必不可少。并不是说你非得把它作为默认浏览器――平时上网时,你想用哪个都行。

自Firefox问世,就有一些居家旅行必备扩展随之产生。如果你想事半功倍立竿见影,快用它们。

必备扩展

Web Developer (Chris Pederick)

这个扩展有很多功能,虽然多数已被FireBug(下文会谈到)涵盖,还是有一些颇为好用的。其中包括:

  • 缩放浏览器窗口
    简单迅速的缩放窗口,800×600、1024×768… 任何指定的尺寸。使用此功能,可以查看各种分辨率下网站的表现。到你的Google Analytics帐户里看看哪种分辨率的访问者最多吧,然后重点为它设计。(FireBug没这个功能)
    My Visitors' Resolutions
  • 编辑CSS/HTML无需刷新
    使用此功能,不必刷新页面即可修改CSS,并将结果实时呈现于页面。太节省时间了。(Firebug里有类似功能,但没这么方便)
    (htmlor注:靠,用了这么久居然都没发现这个好东西,真是太逊了~)
  • 查看页面加载的所有Javascript
    使用此功能,可以在一个页面内查看所有已加载的JS。查看自己或别人的JS代码,方便的很。(Firebug能显示出所有JS名称,但代码没有摆在一起,不方便查询)
  • 查看生成的源代码
    如果你有用AJAX或者Javascript改变页面内容,此功能绝对实用。因为通常的“查看源文件”模式下,是看不到动态生成的HTML代码的。(Firebug也有此功能)

Firebug (Joe Hewitt)

在办公室里,我们常常会问:“还记得没有Firebug时怎么过么?”它确实改变了我的生活。其主要好处如下:

  • 检阅DOM
    点击“Inspect”,然后鼠标放到页面元件上,就能看到此元件的HTML和CSS代码。
  • 显示样式继承的实时CSS编辑
    简直就是钱啊――这大大节省了布局设计的时间。例如,在Firebug里可以选择一个DIV标记,点击margin属性后手工调整,上下键为加减1个像素,上下翻页键为加减10个像素。(htmlor注:任何数值属性都可以这样调整)还可以在当前样式添加新属性。效果满意之后,再把修改的CSS代码贴到实际文件中去。
  • 详尽的Javascript调试
    这里的JS控制台比Firefox自带的稍好。它更详尽,是默认控制台不错的替代品。
  • 查看页面加载的所有文件及总字节数
    对于优化站点加载时间来说,这很关键。你可以测试单个文件会加载多久,图片,JS文件,AJAX调用等。在“Net”部分的最后一行,可以看到页面加载文件的总字节数。

2. 保持兼容性

保持跨浏览器的兼容性很重要。对我来说,这是不怎么好玩的一件事。我之前说过最好在Firefox下开发,但也别忘了检查一下页面在IE6、 IE7、Safari(或者还有Opera)中的表现。还有,到Google Analytics里看看你的访问者都用什么浏览器。他们用哪些,你就得重点照顾哪些。

My Visitors' Browsers

在自己网站的Google Analytics帐户里,我亲眼目睹了IE6占浏览器比例的下滑,持续下滑。等到哪天它跌破5%时,我会开个party庆祝一下――因为再也用不着支持它了。

想要不那么费事的实现兼容,那就简单一点。比如你为了某种效果在一个浏览器里百般调试、费尽周折,它却很可能在另外的浏览器里不好好表现。这就要说到下一建议:少即多。

3. 少即多

把握好分寸。图形设计,编程,页面布局,任何事情都需如此。简单一点。

  • 图形设计
    现在有一种滥用渐变、斜角和阴影的态势。有时候事情如果没搞好,很可能是东西太多了。简简单单、大方得体就好。
  • 花哨的Javascript
    用一些很酷的JS效果增强用户界面很好,不过另一方面,它会造成用户的负担,尤其是那些没有像你一样拥有超级电脑的用户。此外,还有跨浏览器不兼容的麻烦。再强调一次,不要对JS倚重太过,什么事都靠它。如果实在想用JS,我强烈推荐jQuery

4. Javascript?就用jQuery

Javascript用来显示/隐藏信息很棒,它让页面空间开阔,不会挤成一堆。想以一种更新更酷更简单的方式操控JS?一定要试试jQuery。

jQuery

jQuery的主要优点之一:兼容性已广受各大浏览器的考验。也就是说,其所有方法都能保证正常运行。优点之二:极其易用。

jQuery使用CSS的选择器操作对象,让你随心所欲的控制它们,一切尽在掌握。例如:

隐藏id为myDiv的DIV里所有的段落

$('#myDiv p').hide();
$('#myDiv p').hide('slow'); // 动画效果隐藏
$('#myDiv p').toggle(); // 点击显示,再点击隐藏

这里了解更多jQuery。

其他类似的Javascript库也不少,有mootoolsprototypescriptaculous等。

5. AJAX要因地制宜

Web 2.0大潮中,AJAX炙手可热。很多人都问我“你懂AJAX吗?”,好像它是种独立的编程语言似的。说白了,AJAX只是一种手段而已,它通过与服务器端交互,无需刷新页面就能获取和更新数据。

我注意到最近有一种趋势:无论干什么都用AJAX。这并不总是明智的选择。原因?

  • 访问量。全盘应用AJAX,会损失掉宝贵的PV。
  • 可用性。这一点会有争议,但我认为大多数用户(可能不包括你)仍旧有个习惯:他们依然把页面刷新当作某些事件(如表单提交、页面跳转等)发生的迹象。

AJAX绝对有用武之地,而且某些情况下非它不可。不过重申一遍,少即多。把握分寸,适度使用Javascript和AJAX就好。

6. 搜索引擎喜欢结构化代码

现在有种风潮,人们想尽办法让自己的关键字在搜索结果中名列前茅。作为开发者,你有责任因势利导,用结构化代码尽可能优化网站以适应搜索引擎。

以下是一些重要的结构化标记

  • H1 - 最重要的标题,搜索引擎最重视它。
  • H2,H3,H4,H5 - 重要性依次递减的标题。用它们恰当的传递信息,搜索引擎会根据字号给予相应的关照。
  • A - 链接。通常给它个TITLE属性比较好。
    <a href="http://blog.htmlor.com/" title="htmlor's blog">htmlor's blog</a>
  • IMG - 古老的图像标记。给它个ALT属性比较好,搜索引擎会把其属性值当作关键字。另外,当图像无法显示时,访问者会看到替代文字。

还有一些重要的标记:

  • TITLE - 此标记会作为搜索引擎查询结果的标题显示,应该认真对待。
  • META - 最好完善一下keywords和description,搜索引擎还是会读取这两项老掉牙的信息的。
    <meta name="keywords" content="编程,设计,武侠,小说,足球" />
    <meta name="description" content="关注新技术,趣文章,足坛风云;偶尔抒抒情,搞搞笑,装装深沉。" />

7. 布局用DIV 别用TABLE

其实这条我们都已习惯了,现在还用TABLE布局是会被人极度鄙视的。在列举表式数据时用用还差不多。

搞定DIV布局需要很多实践,不过一旦你掌握诀窍,它将变得俯首帖耳。由此获得的灵活性,比你能想到的还要多。

其实它非常简单,就好像 float 和 width 一样。

我在Virb写了个很简单的两栏布局教程,有兴趣就看看吧。

8. 少用行内样式

写代码时,通常会直接在元件标记上加几句样式,这比往CSS文件里加个Class或属性简单顺手一点。不过,最好别这么做,因为代码需要可维护性

某些时候,你将不得不面对自己以前写的代码。自己的床自己得睡,自己犯懒自己遭罪。10年来,我认识到一个道理:现在额外花时间,将来特别省时间。这就说到了下一个建议:代码要考虑将来。

不好的

<p style="font-size:14px;margin-bottom:0;">第一个标题</p>
<p>正文内容</p>
<p style="font-size:14px;margin-bottom:0;">第二个标题</p>

好的

<style type="text/css" media="screen">
p.header{
  font-size:14px;
  margin-bottom:0;
}

</style>
<p class="header">第一个标题</p>
<p>正文内容</p>
<p class="header">第二个标题</p>

9. 代码要考虑将来

要给代码写注释。整洁,有序,别偷懒。如果觉得匆匆忙忙没心思,休息一会儿再回来写。

某些情况下(比如你的网站将来成功了),别人会来看的代码。而有时候,这个人会是你。

几年之后,看到自己当年没有注释、乱做一团的代码,你肯定悔不当初。为了避免将来的自怨自艾,现在就把复杂的代码注释一下吧。

注释也不要太多。那些简单到一目了然的代码根本没必要说明,否则泥沙俱下,真正有用的注释会淹没在重重文字之中。

10. 了解标准,但不必束手束脚

别再使用SMALL、CENTER、FONT等不推荐使用的标记了,这样不好。

听说SMALL标记还没被弃用――不过抱歉,我肯定它没几天了。

网站上的有效XHTMLCSS标志告诉人们,你遵守了某些规则。也许这让你感觉与众不同,但是,网站质量与此无关。去看看哪个成功的大网站能完全通过HTML标准验证? 所谓标准,其实跟不上新方法新技术的发展。

开发网站时,要尽量遵循HTML标准。不过有时候,可能需要跳出标准去实现某个功能,这样才能兼容所有浏览器。对此不必太过介怀,说到底,功能才是网站的根本。

如果实在想的话,可以用W3HTML验证器检查你的代码。

讲完了

考虑一下上述建议吧,我推荐的工具可以开始上手了。祝你好运!

(完)

]]>
web2.0网站如何设计UE/UI http://www.phpv.net/html/1551.html http://www.phpv.net/html/1551.html#comment Fri, 06 Jul 2007 01:38:17 +0000 easy http://www.phpv.net/html/1551.html 这些天总有些负责网站界面的设计人员找我咨询,怎么做用户访谈才感觉不像聊天,怎么样让用户参与到设计中来,得到更多的意见而不是简单的一句还可以或不错之类的评语,原型的改进花费时间总是太长怎么能缩短,设计的时候没什么把握,诸如此类的问题。。我想对此在msn上做的指导大量重复,需要在这里做一些入门级的解释了。。

Q1:首先,用户为中心的设计环节包括哪些活动?
答案:设计--〉原型--〉测试--〉再改进设计--〉原型--〉测试 --〉。。。看出来了吧,这是个迭代过程。。。你的设计没有把握,那么使用测试来验证,发现问题,再快速改进。。

Q2:这样的迭代,什么时候中止,递交给开发呢?
答案:没有完美的设计的,递交给开发前,保证你的设计没有一级易用性问题。否则上线的产品用户骂声一片。。但是还有一些小的bug好改的都改掉,不能改的下一版本吧。什么时候中止,那要看口袋里的钱,还剩的时间和人力等资源限制咯。看得出来吧,这里面肯定有很多的Tradeoff(妥协)的,做UE的和做开发的一定要搞好关系哦,这样,可以多改掉几个bug

Q3: 用户什么时候接触?他们最理想的介入时期是什么时候?
答案:作为UE/UI要记得,永远和用户保持紧密联系。不管项目进展到什么时刻,你都要思考,用户要干嘛,喜欢怎么干,这样的设计他们会不会觉得舒服流畅。要验证答案,那就赶紧去接触他们吧。

Q4:我知道在开发前期的设计工作,要做一些用户研究,问卷调查,用户访谈之类的,到底要研究些什么,出来些什么结果呢?
答案:在设计之前,你要明白的一件事情就是,为谁而设计。围绕这个谁,你需要回答:

1.他们的基本特征,比如年龄段分布,性别特征,家庭,行业,电脑经验,上网经验,收入阶层等等。。

2.你需要找到他们中间最典型的人群,需求最强烈的人群是怎样的一个形象。这个在UCD里面叫做角色提炼(Personas setting)。也许为10万个人设计,你什么都靠猜的,没可能满足10万个人的要求。但是你为这一个或者两个角色来设计吧,他们最典型,他们的需求满足好了,你就离成功不远了。

3.用户在使用你的网站到底舒服不,流畅不,主要是看他的操作习惯,行为方式和网站设计的是不是很匹配。你要研究什么,根本就是典型用户的操作习惯,行为方式,最后获得一个用户模型(User Model)。网站要创造出的用户体验,不是用户对你说,我要怎么样怎么样的,也不是设计者自己在那里想,嗯,这么设计比较容易,两步就能完成,一定很好。。两步就一定好么,你的用户很可能就习惯了走某固定的三步来完成,你的两步,很可能让他们满腹狐疑,忧心忡忡了。。

ok,现在你知道了,出来的结果是什么,用户群特点,典型用户的形象即角色(Persona),然后就是用户模型。。

Q5:知道研究什么呢,该怎么开展研究呢?
答案:用户研究的方法可以很灵活的,常常见到类似聊天一样的,一个问,一个来答,叫用户访谈。还有一些方法,比如问卷调查,焦点小组,数据分析等等。。根据不用的研究内容,还有时间,技术,成本来决定。。
至于怎么研究,一个前提就是,目的性明确。不管你做访谈也好,问卷也好,漫无目的,只会让你对这些形式的有效性产生怀疑。。比如问卷,设计多少个问题,设计哪些问题,你要规划好了。。问卷设计哪几个纬度,每个纬度需要几个问题可以得到结果,什么样的量表合适。。

Q6:项目已经进入开发了,做用户研究来不及了啊。
答案:嗬嗬,来得及来得及,只是要让你的第一批用户多多忍耐了。UCD是迭代过程嘛,已经开发了,你就研究着,准备对第一版本的产品进行测试评估和改进吧。。慢慢来,一个一个的改。

Q7:你所在的team(UI)是怎样跟一个团队(产品策划,程序员等)沟通合作的,又怎样更好的融入到产品的整个过程中的呢?
答:经历过很多种不同的Team,他们处在不同的位置上,常常承担的责任也不一样,因此作事情的方式也完全不一样了。UE在整个产品开发过程中的位置把握准确,相当的重要。关于位置怎么最合适,日后我再专门阐述。目前接触到较理想的工作方式,如何沟通合作,是和产品设计决策者一起工作,将你获得的研究或者评估结果,直接变成设计或建议,传递给产品设计决策者,判断问题的重要性,有哪几种可行的方案,如何改最合适,你们一起探讨。常常,在研究方案是否可行时,你需要跟程序员沟通,提出你的想法,询问是否能实现,实现难度,大致的时间。这样能够保证你方案的可快速执行。这存在很多的沟通技巧。最好的情况就是你, UE人员,要把以用户为中心的思想灌输给他,让他进入你设定的情景,站在你的立场去考虑问题,这样程序员会增加工作的责任感,他甚至可能发挥主观能动性,帮你想到更好的实现方法。。。这样的一种氛围中,整个的团队就像一根绳子往一个方向使劲,都全力想让产品做好,想想,那样的工作多让人充满激情吧。

这只是其中一部分,在你和产品决策者沟通时,甚至还有市场部门的同事参与,一方面,你要代表用户的利益,另一方面,你要试图了解公司希望创造的商业价值,从中找到一个平衡点。这种设计才最容易获得上层的支持,以最快的速度推行下去。可以看看偶翻译的用户体验设计师的职责那片文章。

Q8:界面(原型+设计),交互(包括js),测试等都由一个人做吗?如果不是的话,那么对用户体验的研究又怎样能证明自己的作用?
答:这些工作我都做过,一个人做这种情况其实非常的常见。但是一个人,并不理想,最好,还是培养一个团队。而且有些工作,一个人做不了,必须有协助。这主要看公司的不同状况了。如果是一个人,评估用户体验研究的效果,就可以对你的成绩进行评判了。
如何是一个Team,是好几个人协作完成,如何证明每一部份的工作成效?iceshow是问这个吧。
老实说,我对这个问题没有把握。因为UE的日常工作就是设计-原型-测试评估,是完整的流程,对工作的评估,只能考核整个流程下来的结果。单独一部份工作做得如何,我还没有研究过。。

白鸦在blog里面特意的提到我这个系列,标题的web2.0,应该改掉。我倒不想,出于UE知识的普及,这样的标题适合目标用户群-- web2.0用户体验实践者,可以抓住他们的眼球。这一群能人帮助只是迅速传播普及。另外在用户体验设计方面,之前3篇完全适用web2.0..

今天说说web2.0和1.0在用户体验方面的不同之处,但是,这只是我浅薄的理解,希望可以得到各位资深的实践者们的提点。其实以我的积累,应该是远远不够的。

用户体验包括四个因素:品牌,功能,usability和内容。现在大家常常误认为:用户体验=易用性(或者可用性/usability)。其实不然。

web2.0最不缺的是功能,每一个创业者都是认为自己发现了用户的某一种需求,而市场上没有任何产品可以去满足,因此觉得自己可以开发出具备某些功能的2.0产品。。这方面,不多说什么,只是说一点,细分用户群,必定会成为竞争趋势。。仔细研究了用户群,深入挖掘他们的特点和需求,在最开始就做到高的粘着力,是否更好了?

在品牌上,很多人对这一点的忽略,导致了用户体验的整个盲目。现在我问你,sina,sohu和网易,有什么差别?普通用户可不清楚,都是门户网站。。好像网易开发游戏,sohu还开发了搜索,sina,好像经常做赞助活动。。这就是品牌么?现在问你Nokia和Moto有什么差别?你能回答吧。。品牌和用户体验的关系,是互相影响的。。你用Nokia,发现它简单朴实,好用,还抗摔。就是样子有点。。那么nokia的品牌形象排除了价格因素后就是这样,简单朴实好用机身抗摔,样子一般了点。。现在如果有人推荐你,某个品牌,它是如何的有趣个性时尚,然后你一使用,发现:切,哪点特别的,跟 Nokia差不多,还不如买Nokia。。失败了吧,因为品牌没有独特的个性,带来的用户体验期望值和现实落差,将会让你的目标用户转头而去。。网易相册和其他的相册,有什么差别。。和flikr反正是大大的不同。。

在内容上面。虽然说,web2.0是用户参与,很多网站的内容都是用户来建设。。但是在用户参与之前,你要想,用户为什么要参与。。只因为我没有日记本,你给我一个日记本,我就一定要用你给的这个来写么?用户是否参与,参与程度多少,这些都取决于你现在的内容。。你现在是空的。。鬼知道你这个网站是不是快黄了,我干吗要在这写啊。。你现在很多,但是都是转载的,没几个用户在写。。骗我么?我写了根本就没有几个人看。。好,现在你的内容很多,用户也开始很多了。。但是,天啦,这些内容也未免太广告性了吧。。。或者,用户想,我写了你会不会到处转载啊。。你们这的用户素质怎么样啊。。。而且,形式上,你的品牌,说一点关联性,品牌你标语说时尚个性,网站样子看上去土拉吧唧的,马上用户的信任度就降低了。。

Usability,网站当然要好用了,很迅速的完成内容提交,或者找到目标内容,这是当然的。。但是不是随便一个你觉得交互方式很流畅的网站,都可以完全拷贝复制。幸亏世界如此丰富,不然我们做交互设计的,就跟做数学公式一样了,多没意思,一个套路。。不同的用户,习惯不同的交互方式,他们喜欢什么样子的,这便是用户研究里面要做的一部分工作。。这样的研究结果,帮助你的交互设计具备了自己的个性。。usability测试的结果,是要知道你的目标用户群的看法,发现的问题,而不是科学研究,三步如何变成两步。

]]>
XHTML代码规范 http://www.phpv.net/html/1550.html http://www.phpv.net/html/1550.html#comment Wed, 04 Jul 2007 11:16:05 +0000 easy http://www.phpv.net/html/1550.html 了解这些规范可以帮助你少走弯路,尽快通过代码校验。使我们的代码有一个统一、唯一的标准!

1.所有的标记都必须要有一个相应的结束标记
以前在HTML中,你可以打开许多标签,例如<p>和<li>而不一定写对应的</p>和</li>来关闭它们。但在XHTML中这是不合法的。XHTML要求有严谨的结构,所有标签必须关闭。如果是单独不成对的标签,在标签最后加一个"/"来关闭它。例如:
<br /><img height="80" alt="网页设计师" src="../images/logo_w3cn_200x80.gif" width="200" /> 

2.所有标签的元素和属性的名字都必须使用小写
与HTML 不一样,XHTML对大小写是敏感的,<title>和<TITLE>是不同的标签。XHTML要求所有的标签和属性的名字都必须使用小写。例如:<BODY>必须写成<body> 。大小写夹杂也是不被认可的,通常dreamweaver自动生成的属性名字"onMouseOver"也必须修改成"onmouseover"。

3.所有的XML标记都必须合理嵌套
同样因为XHTML要求有严谨的结构,因此所有的嵌套都必须按顺序,以前我们这样写的代码:
<p><b></p></b> 
必须修改为:
<p><b></b></p> 
就是说,一层一层的嵌套必须是严格对称。

4.所有的属性必须用引号""括起来
在HTML中,你可以不需要给属性值加引号,但是在XHTML中,它们必须被加引号。例如:
<height=80> 
必须修改为:
<height="80"> 
特殊情况,你需要在属性值里使用双引号,你可以用",单引号可以使用',例如:
<alt="say'hello'"> 

5.把所有<和&特殊符号用编码表示
任何小于号(<),不是标签的一部分,都必须被编码为& l t ; 
任何大于号(>),不是标签的一部分,都必须被编码为& g t ; 
任何与号(&),不是实体的一部分的,都必须被编码为& a m p; 
注:以上字符之间无空格。

6.给所有属性赋一个值
XHTML规定所有属性都必须有一个值,没有值的就重复本身。例如:
<td nowrap> <input type="checkbox" name="shirt" value="medium" checked> 必须修改为:
<td nowrap="nowrap"> <input type="checkbox" name="shirt" value="medium" checked="checked">
 
7.不要在注释内容中使“--”
“--”只能发生在XHTML注释的开头和结束,也就是说,在内容中它们不再有效。
例如下面的代码是无效的:
<!--这里是注释-----------这里是注释--> 
用等号或者空格替换内部的虚线。
<!--这里是注释============这里是注释--> 
以上这些规范有的看上去比较奇怪,但这一切都是为了使我们的代码有一个统一、唯一的标准!以便于将来的数据再利用!!]]>
Javascript经典正则表达式 http://www.phpv.net/html/1534.html http://www.phpv.net/html/1534.html#comment Wed, 21 Mar 2007 11:51:07 +0000 easy http://www.phpv.net/html/1534.html 三道测试题:
1, var str=“ abbbbacc”;
var rs=str.replace(“a”,”0”);   
(A)0bbbbacc (B)0bbbb0cc
2,var str=“ abbbbacc”;
var rs=str.replace(“/a/”,”0”);   
(A)0bbbbacc (B)0bbbb0cc
3,var str=“ abbbbacc”;
var rs=str.replace(“/a/g”,”0”);   
(A)0bbbbacc (B)0bbbb0cc
附注:String对象的replace方法签名为:
replace(regx,str)

一,概述

1,正则表达式,可以说是任何一种编程语言都提供的机制,它主要是提供了对字符串的处理能力。
2,正则表达式在页面处理中的使用场景:
1)表单验证。验证某些域符合某种规则,例如邮件输入框必须输入的是邮件、联系电话输入框输入的必须是数字等等
2)处理DOM模型。例如通过表达式定位DOM中的一个对象或一系列对象,一个例子就是定位id属性中含有某个特殊字符的div对象。
3)纯编程逻辑。直接用于编程的逻辑之中。
3,说明:本部分所举的正则表达式的代码片断,都是经过测试的,但有一点需要注意,对于换行的字符串的定义,我们在表述时使用的是类似如下的形式:
var str=“It’s is
 a  beautiful city”;
这种形式直接写在JS代码中是错误的,那如何获取具有换行的字符串呢?简单的办法:在textarea中输入文本并换行,然后将该值赋给JS变量即可。例如:
var str=document.forms[0].mytextarea.value;         

二,语法与使用

1,定义正则表达式

1)定义正则表达式有两种形式,一种是普通方式,一种是构造函数方式。
2)普通方式:var reg=/表达式/附加参数
表达式:一个字符串,代表了某种规则,其中可以使用某些特殊字符,来代表特殊的规则,后面会详细说明。
附加参数:用来扩展表达式的含义,目前主要有三个参数:
g:代表可以进行全局匹配。
i:代表不区分大小写匹配。
m:代表可以进行多行匹配。
上面三个参数,可以任意组合,代表复合含义,当然也可以不加参数。
例子:
var reg=/a*b/;
var reg=/abc+f/g;
3)构造函数方式:var reg=new RegExp(“表达式”,”附加参数”);
其中“表达式”与“附加参数”的含义与上面那种定义方式中的含义相同。
例子:
var reg=new RegExp(“a*b”);
var reg=new RegExp(“abc+f”,”g”);
4)普通方式与构造函数方式的区别
普通方式中的表达式必须是一个常量字符串,而构造函数中的表达式可以是常量字符串,也可以是一个js变量,例如根据用户的输入来作为表达式参数等等:
var reg=new RegExp(document.forms[0].exprfiled.value,”g”);

2,表达式模式

1)表达式模式,是指表达式的表达方式与样式, 即 var reg=/表达式/附加参数 中的“表达式”怎样去描述?
2)从规范上讲,表达式模式分为简单模式和复合模式。
3)简单模式:是指通过普通字符的组合来表达的模式,例如
var reg=/abc0d/;
可见简单模式只能表示具体的匹配。
4)复合模式:是指含有通配符来表达的模式,例如:
var reg=/a+b?w/;
其中的+、?和w都属于通配符,代表着特殊的含义。因此复合模式可以表达更为抽象化的逻辑。
下面我们着重说一下复合模式中各个通配符的含义及其使用。
5)复合模式中特殊字符的讲解:

1>:在许多编程语言里面被用作转义符,一般来说
符号后面如果跟的是普通字符c,那么c就代表特殊的含义,例如n本来代表字符n,但n就代表换行。
符号后面如果跟的是特殊字符c,那么c就代表普通字符c,例如一般用作转义符,但\则调表普通字符。
Javascript的正则表达式中的用法与上面相同,只是不同的编程语言,特殊字符表可能不太一样罢了。

2>^:匹配输入字符串的起始端,如果是多行匹配,即表达式的附加参数中含有m,则也在一个换行符后匹配。
例子:/^B/匹配 “Bab Bc ”中的第一个B
例子2:/^B/gm匹配
          “Badd B
          cdaf
          B dsfB”
          中的第一行第一个B,第三行中的第一个B
         
3>$:匹配输入字符创的尾端,如果是多行匹配,即表达式的附加参数中含有m,则也在一个换行符前匹配。
与^的用法相反。
例子:/t$/匹配“bat”中的t,但是不匹配“hate”中的t
例子2:/t$/匹配
“tag at
bat”
中第一行的最后一个t和第二行的t。

4>*:匹配前一个字符0次或多次。
例子:/ab*/匹配“dddabbbbc”中的“abbbb”,也匹配“ddda”中的“a”

5>+:匹配前一个字符1次或多次。
例子:/ab+/匹配“dddabbbbc”中的“abbbb”,但不匹配“ddda”
与后面的{1,}(原型:{n,})的用法类似

6>?:?的用法比较特殊,一般来说它用来对前一个字符做0次或1次匹配,但是它有另外两种特殊的用法:
如果紧跟在*、+、?和{ }之后,则表示原始匹配的最小次数匹配,例如:
/ba*/本来匹配“bbbaaaa”中的“baaaa”,但是/ba*?/则匹配“bbbaaaa”中的“b”(因为*表示0次或多次匹配,而加?应该表示最少次数匹配,即0次匹配)。
同理:/ba+?/则匹配“baaaa”中的“ba”。
作为语法结构符号,使用于前置断言中,即后面要说到的x(?=y)和x(?!=y)

7>.:小数点中的“.”号,匹配任何一个单独的字符,但是换行符除外。
标准中总共有哪些字符?请参考:字符集
例如:/a.b/匹配“acbaa”中的“acb”,但是不匹配“abbb”。

8>(x):表示匹配x(并非特指字符x或者特指一个字符,x表示一个字符串),而且匹配会被记住,在语法中这种()被称为“capturing parentheses ”,即捕捉用的小括号。
匹配会被记住,是因为在表达式提供的函数中,有些函数返回一个数组,该数组会保存所匹配的所有字符串,例如exec()函数。
另外还要注意()中的x被记住的前提是匹配x。
例子1:
var regx=/a(b)c/;
var rs=regx.exec(“abcddd”);
从上面可以看出,/a(b)c/匹配“abcddd”中的“abc”,因为()的原因,b也会记录下来,因此rs返回的数字内容为:
{abc,b}
例子2:
 var regx=/a(b)c/;
 var rs=regx.exec(“acbcddd”);
 rs返回null,因为/a(b)c/不匹配“acbcddd”,所以()中的b不会被记录下来(尽管字符串中含有b)
 
9>(?:x):匹配x,但不会记住x,这种格式中的()被称为“non-capturing parentheses ”,即非捕捉用的小括号。
例子:
var regx=/a(?:b)c/;
var rs=regx.exec(“abcddd”);
从上面可以看出,/a(?:b)c/匹配“abcddd”中的“abc”,因为(?:)的原因,b不会记录下来,因此rs返回的数字内容为:
{abc}

10>X(?=y):匹配x,仅当后面紧跟着y时。如果符合匹配,则只有x会被记住,y不会被记住。
例子:
var regx=/user(?=name)/;
var rs=regx.exec(“The username is Mary”);
结果:匹配成功,而且rs的值为{user}

11>X(?!y):匹配x,仅当后面不紧跟着y时。如果符合匹配,则只有x会被记住,y不会被记住。
例子:
var regx=/user(?!name)/;
var rs=regx.exec(“The user name is Mary”);
结果:匹配成功,而且rs的值为{user}
例子2:
var regx=/d+(?!.)/;
var rs=regx.exec(“54.235”);
结果:匹配成果,rs的值为{5},不匹配54是因为54后面跟着“.”号,当然235也匹配,但是由于exec方法的行为,235不会被返回

12>x|y:匹配x或y。注意如果x和y都匹配上了,那么只记住x。
例子:
var regx=/beijing|shanghai/;
var rs=regx.exec(“I love beijing and shanghai”);
结果:匹配成功,rs的值为{beijing},虽然shanghai也匹配,但不会被记住。

13>{n}:匹配前一个字符的n次出现。
n必须是一个非负数,当然如果是一个负数或小数也不会报语法错误。
例子:
var regx=/ab{2}c/;
var rs=regx.exec(“abbcd”);
结果:匹配成功,rs的值为:{abbc}。

14>{n,}:匹配前一个字符的至少n次出现。
例子:
var regx=/ab{2,}c/;
var rs=regx.exec(“abbcdabbbc”);
结果:匹配成功,rs的值为:{abbc}。注意为什么abbbc也符合条件为什么没有被记住,这与exec方法的行为有关,后面会统一讲解。

15>{n,m}:匹配前一个字符的至少n次最多m次的出现。
只要n与m为数字,而且m>=n就不会报语法错误。
例子:
var regx=/ab{2,5}c/;
var rs=regx.exec(“abbbcd”);
结果:匹配成功,rs的值为:{abbbc}。
例子2:
var regx=/ab{2,2}c/;
var rs=regx.exec(“abbcd”);
结果:匹配成功,rs的值为:{abbc}。
例子3:
var regx=/ab(2,5)/;
var rs=regx.exec(“abbbbbbbbbb”);
结果:匹配成功,rs的值为:{abbbbb},这说明,如果前一个字符出现多于m次,则只匹配m次。另外:
var regx=/ab(2,5)c/;
var rs=regx.exec(“abbbbbbbbbbc”);
结果:匹配失败,rs的值为:null,为什么匹配失败,因为b多于5个则b(2,5)会匹配前5个b,,而表达式/ab(2,5)c/中b后面是c,但字符串中5个b之后还是b所以会报错。

16>[xyz]:xyz表示一个字符串,该模式表示匹配[]中的一个字符,形式上[xyz]等同于[x-z]。
例子:
var regx=/a[bc]d/;
var rs=regx.exec(“abddgg”);
结果:匹配成功,rs的值为:{abd}
例子2:
var regx=/a[bc]d/;
var rs=regx.exec(“abcd”);
结果:匹配失败,rs的值为:null,之所以失败,是因为[bc]表示匹配b或c中的一个,但不会同时匹配。

17>[^xyz]:该模式表示匹配非[]中的一个字符,形式上[^xyz]等同于[^x-z]。
例子:
var regx=/a[^bc]d/;
var rs=regx.exec(“afddgg”);
结果:匹配成功,rs的值为:{afd}
例子2:
var regx=/a[^bc]d/;
var rs=regx.exec(“abd”);
结果:匹配失败,rs的值为:。

18>[b]:匹配退格键。

19>b:匹配一个词的边界符,例如空格和换行符等等,当然匹配换行符时,表达式应该附加参数m。
例子:
var regx=/bc./;
var rs=regx.exec(“Beijing is a beautiful city”);
结果:匹配成功,rs的值为:{ci},注意c前边的空格不会匹配到结果中,即{ ci}是不正确的。

20>B:代表一个非单词边界。
例子:
var regx=/Bi./;
var rs=regx.exec(“Beijing is a beautiful city”);
结果:匹配成功,rs的值为:{ij},即匹配了Beijing中的ij。

21>cX,匹配一个控制字符。例如, cM 匹配一个 Control-M 或
回车符。 x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一
个原义的 ’c’ 字符。(实际的例子还需补充)

21>d:匹配一个数字字符,等同于[0-9]。
例子:
var regx=/userd/;
var rs=regx.exec(“user1”);
结果:匹配成功,rs的值为:{user1}

22>D:匹配一个非数字字符,等同于[^0-9]。
例子:
var regx=/userD/;
var rs=regx.exec(“userA”);
结果:匹配成功,rs的值为:{userA}

23>f:匹配一个换页符。

24>n:匹配一个换行符。因为是换行符,所以在表达式中要加入m参数。
例子:
var regx=/anbc/m;
       var str=“a
               bc”;
       var rs=regx.exec(str);
       结果:匹配成功,rs的值为:{  },如果表达式为/anrbc/,则不会被匹配,因此在一般的编辑器中一个”Enter”键代表着“回车换行”,而非“换行回车”,至少在textarea域中是这样的。      
25>r:匹配一个回车符

26>s:匹配一个空格符,等同于[ fnrtvu00A0u2028u2029].
例子:
var regx=/si/;
var rs=regx.exec(“Beijing is a city”);
结果:匹配成功,rs的值为:{ i}

27>S:匹配一个非空格符,等同于[ ^fnrtvu00A0u2028u2029].
例子:
var regx=/Si/;
var rs=regx.exec(“Beijing is a city”);
结果:匹配成功,rs的值为:{ei}

28>t:匹配一个tab
例子:
var regx=/atb/;
var rs=regx.exec(“a bc”);
结果:匹配成功,rs的值为: {a       bc}

29>v:匹配一个竖向的tab

30>w:匹配一个数字、_或字母表字符,即[A-Za-z0-9_ ]。
例子:
var regx=/w/;
var rs=regx.exec(“$25.23”);
结果:匹配成功,rs的值为:{2}

31>W:匹配一个非数字、_或字母表字符,即[^A-Za-z0-9_ ]。
例子:
var regx=/w/;
var rs=regx.exec(“$25.23”);
结果:匹配成功,rs的值为:{$}

32>n:注意不是n,这里n是一个正整数,表示匹配第n个()中的字符。
例子:
var regx=/user([,-])group1role/;
var rs=regx.exec(“user-group-role”);
结果:匹配成功,rs的值为:{user-group-role,-},同样对user,group,role的匹配也是成功的,但像user-group,role等就不对了。

33>�:匹配一个NUL字符。

34>xhh:匹配一个由两位16进制数字所表达的字符。

35>uhhhh:匹配一个由四位16进制数字所表达的字符。


3,表达式操作

1)表达式操作,在这里是指和表达式相关的方法,我们将介绍六个方法。
2)表达式对象(RegExp)方法:

1>exec(str),返回str中与表达式相匹配的第一个字符串,而且以数组的形式表现,当然如果表达式中含有捕捉用的小括号,则返回的数组中也可能含有()中的匹配字符串,例如:
var regx=/d+/;
var rs=regx.exec(“3432ddf53”);
返回的rs值为:{3432}
var regx2=new RegExp(“ab(d+)c”);
var rs2=regx2.exec(“ab234c44”);
返回的rs值为:{ab234c,234}
另外,如果有多个合适的匹配,则第一次执行exec返回一个第一个匹配,此时继续执行exec,则依次返回第二个第三个匹配。例如:
var regx=/userd/g;
var rs=regx.exec(“ddduser1dsfuser2dd”);
var rs1=regx.exec(“ddduser1dsfuser2dd”);
则rs的值为{user1},rs的值为{rs2},当然注意regx中的g参数是必须的,否则无论exec执行多少次,都返回第一个匹配。后面还有相关内容涉及到对此想象的解释。

2>test(str),判断字符串str是否匹配表达式,返回一个布尔值。例如:
var regx=/userd+/g;
var flag=regx.test(“user12dd”);
flag的值为true。

3)String对象方法

1>match(expr),返回与expr相匹配的一个字符串数组,如果没有加参数g,则返回第一个匹配,加入参数g则返回所有的匹配
例子:
var regx=/userd/g;
var str=“user13userddduser345”;
var rs=str.match(regx);
rs的值为:{user1,user3}

2>search(expr),返回字符串中与expr相匹配的第一个匹配的index值。
例子:
var regx=/userd/g;
var str=“user13userddduser345”;
var rs=str.search(regx);
rs的值为:0

3>replace(expr,str),将字符串中匹配expr的部分替换为str。另外在replace方法中,str中可以含有一种变量符号$,格式为$n,代表匹配中被记住的第n的匹配字符串(注意小括号可以记忆匹配)。
例子:
var regx=/userd/g;
var str=“user13userddduser345”;
var rs=str.replace(regx,”00”);
rs的值为:003userddd0045
例子2:
var regx=/u(se)rd/g;
var str=“user13userddduser345”;
var rs=str.replace(regx,”$1”);
rs的值为:se3userdddse45
对于replace(expr,str)方法还要特别注意一点,如果expr是一个表达式对象则会进行全局替换(此时表达式必须附加参数g,否则也只是替换第一个匹配),如果expr是一个字符串对象,则只会替换第一个匹配的部分,例如:
var regx=“user”
var str=“user13userddduser345”;
var rs=str.replace(regx,”00”);
rs的值为: 0013userddduser345

4>split(expr),将字符串以匹配expr的部分做分割,返回一个数组,而且表达式是否附加参数g都没有关系,结果是一样的。
例子:
var regx=/userd/g;
var str=“user13userddduser345”;
var rs=str.split(regx);
rs的值为:{3userddd,45}

4,表达式相关属性

1)表达式相关属性,是指和表达式相关的属性,如下面的形式:
var regx=/myexpr/;
var rs=regx.exec(str);
其中,和表达式自身regx相关的属性有两个,和表达式匹配结果rs相关的属性有三个,下面将逐一介绍。
2)和表达式自身相关的两个属性:

1>lastIndex,返回开始下一个匹配的位置,注意必须是全局匹配(表达式中带有g参数)时,lastIndex才会有不断返回下一个匹配值,否则该值为总是返回第一个下一个匹配位置,例如:
var regx=/userd/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex1=regx.lastIndex;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex2=regx.lastIndex;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex3=regx.lastIndex;
上面lastIndex1为9,第二个lastIndex2也为9,第三个也是9;如果regx=/userd/g,则第一个为9,第二个为18,第三个为0。

2>source,返回表达式字符串自身。例如:
var regx=/userd/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var source=regx.source;
source的值为userd
3)和匹配结果相关的三个属性:

1>index,返回当前匹配的位置。例如:
var regx=/userd/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var index1=rs.index;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var index2=rs.index;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var index3=rs.index;
index1为4,index2为4,index3为4,如果表达式加入参数g,则index1为4,index2为13,index3会报错(index为空或不是对象)。

2>input,用于匹配的字符串。例如:
var regx=/userd/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var input=rs.input;
input的值为sdsfuser1dfsfuser2。

3>[0],返回匹配结果中的第一个匹配值,对于match而言可能返回一个多值的数字,则除了[0]外,还可以取[1]、[2]等等。例如:
var regx=/userd/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var value1=rs[0];
rs=regx.exec(“sdsfuser1dfsfuser2”);
var value2=rs[0];
value1的值为user1,value2的值为user2

5,实际应用

1)实际应用一
描述:有一表单,其中有一个“用户名”input域
要求:汉字,而且不能少于2个汉字,不能多于4个汉字。
实现:
<script>
function checkForm(obj){
     var username=obj.username.value;
     var regx=/^[u4e00-u9fa5]{2,4}$/g
     if(!regx.test(username)){
               alert(“Invalid username!”);
               return false;
     }
     return true;
}
</script>
<form name=“myForm”onSubmit=“return checkForm(this)”>
    <input type=“text” name=“username”/>
    <input type=“submit” vlaue=“submit”/>
</form>
2)实际应用二
描述:给定一个含有html标记的字符串,要求将其中的html标记去掉。
实现:
<script>
function toPlainText(htmlStr){
     var regx=/<[^>]*>|</[^>]*>/gm;
     var str=htmlStr.replace(regx,"");
     return str;
}
</script>
<form name=“myForm”>
    <textarea id=“htmlInput”></textarea>
    <input type=“button” value=“submit” onclick=“toPlainText(document.getElementById(‘htmlInput’).value”/>
</form>

三,小结

1,Javascript正则表达式,我想在一般的程序员之中,使用者应该不是很多,因为我们处理的页面一般都不是很复杂,而复杂的逻辑一般我们都在后台处理完成了。但是目前趋势已经出现了扭转,富客户端已经被越来越多的人接受,而Javascript就是其中的关键技术,对于复杂的客户端逻辑而言,正则表达式的作用也是很关键的,同时它也是Javascript高手必须要掌握的重要技术之一。 

2,为了能够便于大家对前面讲述的内容有一个更为综合和深刻的认识,我将前面的一些关键点和容易犯糊涂的地方再系统总结一下,这部分很关键!
总结1:附件参数g的用法
表达式加上参数g之后,表明可以进行全局匹配,注意这里“可以”的含义。我们详细叙述:
1)对于表达式对象的exec方法,不加入g,则只返回第一个匹配,无论执行多少次均是如此,如果加入g,则第一次执行也返回第一个匹配,再执行返回第二个匹配,依次类推。例如
var regx=/userd/;
var str=“user18dsdfuser2dsfsd”;
var rs=regx.exec(str);//此时rs的值为{user1}
var rs2=regx.exec(str);//此时rs的值依然为{user1}
如果regx=/userd/g;则rs的值为{user1},rs2的值为{user2}
通过这个例子说明:对于exec方法,表达式加入了g,并不是说执行exec方法就可以返回所有的匹配,而是说加入了g之后,我可以通过某种方式得到所有的匹配,这里的“方式”对于exec而言,就是依次执行这个方法即可。
2)对于表达式对象的test方法,加入g于不加上g没有什么区别。
3)对于String对象的match方法,不加入g,也只是返回第一个匹配,一直执行match方法也总是返回第一个匹配,加入g,则一次返回所有的匹配(注意这与表达式对象的exec方法不同,对于exec而言,表达式即使加上了g,也不会一次返回所有的匹配)。例如:
var regx=/userd/;
var str=“user1sdfsffuser2dfsdf”;
var rs=str.match(regx);//此时rs的值为{user1}
var rs2=str.match(regx);//此时rs的值依然为{user1}
如果regx=/userd/g,则rs的值为{user1,user2},rs2的值也为{user1,user2}
4)对于String对象的replace方法,表达式不加入g,则只替换第一个匹配,如果加入g,则替换所有匹配。(开头的三道测试题能很好的说明这一点)
5)对于String对象的split方法,加上g与不加g是一样的,即:
var sep=/userd/;
var array=“user1dfsfuser2dfsf”.split(sep);
则array的值为{dfsf, dfsf}
此时sep=/userd/g,返回值是一样的。
6)对于String对象的search方法,加不加g也是一样的。
总结2:附加参数m的用法
附加参数m,表明可以进行多行匹配,但是这个只有当使用^和$模式时才会起作用,在其他的模式中,加不加入m都可以进行多行匹配(其实说多行的字符串也是一个普通字符串),我们举例说明这一点
1)使用^的例子
var regx=/^b./g;
var str=“bd76 dfsdf
         sdfsdfs dffs
         b76dsf  sdfsdf”;
var rs=str.match(regx);
此时加入g和不加入g,都只返回第一个匹配{bd},如果regx=/^b./gm,则返回所有的匹配{bd,b7},注意如果regx=/^b./m,则也只返回第一个匹配。所以,加入m表明可以进行多行匹配,加入g表明可以进行全局匹配,综合到一起就是可以进行多行全局匹配
2)使用其他模式的例子,例如
var regx=/userd/;
var str=“sdfsfsdfsdf
         sdfsuser3 dffs
         b76dsf  user6”;
var rs=str.match(regx);
此时不加参数g,则返回{user3},加入参数g返回{user3,user6},加不加入m对此没有影响。
3)因此对于m我们要清楚它的使用,记住它只对^和$模式起作用,在这两种模式中,m的作用为:如果不加入m,则只能在第一行进行匹配,如果加入m则可以在所有的行进行匹配。我们再看一个^的例子
var regx=/^b./;
var str=“ret76 dfsdf
         bjfsdfs dffs
         b76dsf  sdfsdf”;
var rs=str.match(regx);
此时rs的值为null,如果加入g,rs的值仍然为null,如果加入m,则rs的值为{bj}(也就是说,在第一行没有找到匹配,因为有参数m,所以可以继续去下面的行去找是否有匹配),如果m和g都加上,则返回{bj,b7}(只加m不加g说明,可以去多行进行匹配,但是找到一个匹配后就返回,加入g 表明将多行中所有的匹配返回,当然对于match方法是如此,对于exec呢,则需要执行多次才能依次返回)
总结3:在HTML的textarea输入域中,按一个Enter键,对应的控制字符为“rn”,即“回车换行”,而不是“nr”,即“换行回车”,我们看一个前面我们举过的例子:
var regx=/arnbc/;
var str=“a
         bc”;
var rs=regx.exec(str);
结果:匹配成功,rs的值为:{      },如果表达式为/anrbc/,则不会被匹配,因此在一般的编辑器中一个”Enter”键代表着“回车换行”,而非“换行回车”,至少在textarea域中是这样的。

四,应用案例

1,正则表达式使用场景:
1)登录场景,检查用户输入的用户名,要求:
字符长度在6到18之间
字符必须为字母、数字或者下划线的组合
2)购物场景,对于商品列表的描述(标签、条形码、单价)等有些用户可能会提出下面需求:
希望可以对商品列表的某一列描述进行字号的自定义,而且下次登录仍然保持用户的修改
2,下面看一下在上述两个场景中,正则表达式的使用方式和具体实现。
1)登录场景部分正则表达式实现

2)购物场景部分正则表达式实现
1>需求分析:用户希望可以对商品列表的某一列描述进行字号的自定义,而且下次登录仍然保持用户的修改

2>程序设计

类图:

3>代码实现
PageSetting类

PageSettingParser类

注:如果需要上面的应用案例的工程,请发email给我。

 

]]>
Throwing Tables Out the Window -把表格扔掉 http://www.phpv.net/html/1491.html http://www.phpv.net/html/1491.html#comment Tue, 27 Dec 2005 15:06:26 +0000 easy http://www.phpv.net/html/1491.html 文章摘要很多网站已经对 CSS 这片海洋进行了深入充分的测试,现在我们从水底开始欢呼的时候到了,让我们奉劝并鼓励那些还没有跳下水来的人,赶紧加入我们的行列。现在已经没有任何理由继续用表格来排版,也没有理由为不同的浏览器维护同一个网站的多个版本。赶快把表格扔掉吧,相信我们,你不再需要它们了!(译文:巴西葡萄牙语丹麦语法语德语意大利语日语西班牙语土耳其语


Throwing Tables Out the Window

妈妈快看,没有表格哟!

那些参加了今年在西雅图的 Digital Design World 的朋友们可能看到我主持了一场题为“No More Tables, CSS Layout Techniques”的讨论。在讨论中,我们回顾了一下表格的正确用法,以及一些用 CSS 来达到同样目的的方法。然后我们转向无表格排版,列举了一些范例并概括出两种基本的途径:控制位置和悬浮(positioning and floats)。

讨论进行到一半的时候,我改换了风格,宣布我们将就现实中的实例,实现从表格和占位 GIF 图片的排版方式向纯 CSS 排版的转换。我原本可以设置一个虚拟的例子用在讨论中,但是这个看起来会显得非常做作。如果我设置了我自己的例子,它看起来可能会显得漂亮整洁,所有的一切都会被按照我想象的那样被渲染,会避开所有我已知的问题点。
虚拟的还不够好,我要向真实的案例挑战。所以我选择了一个为大部分听众所熟悉的西雅图本地的小公司:

Microsoft

OK,大概并不只有一部分听众熟悉这个并不那么小的公司。很多用户每天都要登录微软网站的官方网站,不管它是不是像搜索巨头 Google 以及 Yahoo! 那样出名或者被经常用到,勿庸置疑的是,每天有数以百万计的用户访问 microsoft.com ,它为我们的互联网带来了极大的流量。

遗憾的是微软并没有竭尽全力优化她的网站。用户下载着不必要的大型页面,服务器为了支持他们浪费着额外的带宽。对于 40KB 来讲,微软首页的 HTML 还算不上是洪水猛兽,但是它负担着无法访问的、七拼八凑的、基于表格并充斥着各种属性的标记,以及一些笨拙的 JavaScript。注意我并没有提到这些是不是有效的标记。尽管它采用了 XHTML 风格,但是微软在其页面上漏掉了 doctype 声明。

为什么是微软?

这是不是仅仅另外一次对微软的挑剔?

直率地,诚恳地说,不是!

我选择微软并不是为了跳上时尚的抨击讲坛,或者向业内人们喜欢讨厌的公司多扔些鸡蛋。(我从未放弃任何机会来置疑微软做出的某些决定,但是我总是避免指责。)

我承认我有意地选择并锁定了一个备受瞩目的公司,我天生喜欢追逐领头羊。不过,作为范例,大部分人都熟悉她。microsoft.com 曾经是(现在仍然是)完美的 CSS 标准改造候选者

以下是原因……

原因 #1
因为它低效率地用大量的表格和占位 GIF 来排版。当内容用表格进行排版后,页面的兼容性会更差,甚至无法访问。并不只有微软有这个问题。目前网络上绝大多数的网站仍然使用大量的表格用于页面排版,或者其它纯粹的视觉目的。我选择微软的网站,是因为它和很多其它网站有着同样的问题,而且它可以作为一个著名的范例(甚至最后成为模范)。

原因 #2
因为微软网站首页当前设计的基本结构和成千上万的网站的设计有着共同的模式:页眉 + 3 栏 + 页脚。进一步讲,页眉横跨整个页面上部,左栏主要包含导航系统,主栏放内容,右栏提供额外的资料,然后页脚在三栏下面同样横跨整个页宽。即使不是三栏式排版,很多网站也可能使用和这个结构类似的二栏式排版:一个边栏放在主栏的左边或者右边:

微软的主页,用三个不同的部分标识出其页面的结构,一个表示页眉+三栏+页脚,另外两个表示页眉+两栏+页脚

原因 #3
因为微软的网站对 CSS 的利用,仅限 FAC (字体和颜色)。我更希望看到这个曾经在应用环境下发明了样式表基础理论的公司,更偏重于 CSS,而非旧的方法。

原因 #4
因为目前微软根据浏览其网站的浏览器的不同,提供网站的不同版本。一个提供给 Windows 的 Internet Explorer (v5.5 及以上),另一个什么 dumbed-down 的版本提供给所有其它的浏览器(包括 IE 和 Mac),它省略了一些图片,以及所有的产品徽记。这个非 IE/Win 的版本去掉了一些功能(如弹出式菜单),并用不同的技术来渲染页面元素。如果您有 IE 5.5 或以上版本,以及另外一个浏览器,您可以自己查看。如果没有,以下是两种不同版本的屏幕截图,并用红色的圈标出了不同的地方:

微软提供的两种不同的首页截图。左侧的(提供给 IE 5.5 或更高版本)与右侧(提供给其它浏览器)的相比,显示了更多的图片,从体上样式更加饱满一些。

非 IE/Win 的版本和为 IE/Win 提供服务的版本相比,明显简陋得多。我们都知道它其实并不需要这样。这并不只是在某些浏览器上能够工作而在其它的浏览器上却不行的草率代码。微软故意做了一个 JavaScript 浏览器探测,当浏览器是 IE 5.5 或更高版本时,它会将浏览器重定向到另一个页面上。其实,微软可以只维护一个能够运行在所有浏览器上的版本。

微软还只是为非 IE/Win 的浏览器用户提供了其网站的另一个版本,有些开发者所做的可能远不止这些。一些网站放弃对其它浏览器提供支持,我们听到的最多的原因是 MSIE/Win 被绝大多数用户使用,同时为任何其它的浏览器提供正确的页面会花费太多时间。有些则抱怨说为 IE/Win 之外的浏览器开发太昂贵。其实,“太多时间”和“太昂贵”的说法并不成立。

很多开发者相信这些说法,因为他们是从为 IE 开发――并在 IE 中检查――开始的。当他们用另一种浏览器来查看的时候就会感到沮丧――他们看到各种各样他们认为必须去修正的 bug。

IE 和其它在近两年不断升级版本的浏览器(Mozilla、Firefox、Safari、Opera……)相比,对 CSS 的理解更加松散。从 IE 开始开发,意味着在开发早期发现的问题会更少一些。先在 IE 上开发,然后尝试更新支持其它浏览器,从长期来看这将增加时间和金钱的消耗。但是,我们有一个更好的办法能够更快更省钱的解决这个问题。

从更严格的浏览器开始开发,这些浏览器通常按照它们应该渲染页面的方式去渲染。先让页面在这些浏览器上运行正常,然后再回来为 IE 做一些“修补”。用这种方式,开发将快得多。虽然初期这样会让页面在您流量分析中出现得绝大多数浏览器上不太直观,但是如果您并不打算习惯――或者依赖――IE 松散的渲染行为的话,这个开发过程要流畅和有效率得多。从 IE 开始开发,您可能会花费更长的时间来修改开始的代码,以便适应更严格的浏览器。

走这条路,我们仍然有 IE 方面的问题需要关注。但是,当我们有了更多关于 IE 错误的 CSS 渲染行为的经验后,IE 方面的问题从一开始就降到最少,这是肯定的。

请说事实

在讨论的后半段,我们从头到尾地经历了将微软基于表格和占位 GIF 排版的页面,转换为更容易访问的、纯 CSS 驱动的版本,使其能在任何浏览器上运行。这并不新潮,以前已经有人对 microsoft.com 进行过重新编码。本站一些常来的读者从事无表格的设计到现在已经一年多了。尽管 CSS 海洋的水已经被公平的全面测试过,但是我们仍然没有看到更多的人跳下水。因此有了 Digital Design World 上的讨论,有了这片文章。

在接下来的讨论中,我们将每个环节分成容易操作的若干个小块。我指出了过程中的主要步骤,包括去掉表格,将它们转换成更容易理解的标记,以及用来忠实重现微软首页设计每一个环节的 CSS 技术。

在整个讨论过程中,我们每个环节都演示了很多形象的东西(图示、截屏、统计图表等)来帮助理解这些渲染技术。我也预先准备了在每个环节需要的文件代码。

撰写此篇文章的其中一个目的,是为了发布对 microsoft.com 进行改造的最终结果,看起来有点让人难忘:

  当前设计
(IE/Win)
当前设计
(其它)
改造后
使用表格 40 36 0
占位 GIF 35 76 0
总 <img> 标签 43 122 6
CSS 背景图片 1 1 11
浏览器支持 2 Most modern Most modern
HTML 文件大小 40 KB 39 KB 15 KB
文件大小减少 - 3% 62%


更多

当我们开始进行 Meyer/Davidson ESPN-style 评价和设计时,这些数字变得更加有趣了。在微软一篇公开的题为“Inside Microsoft”的网页上,微软公布了其流量统计:mocrosoft.com 在 2004 年 5 月获得了 12 亿次的 page view。在以上的讨论中,我显示了如何减少一个页面 62% 的标记,或者说 25 KB。我也同样预言了如果微软能够在整个网站上更加积极的应用 CSS,每页面 25KB 是一个公平的估计。如果乘以平均每天 3870 万次的 page view,每页面 25 KB 的减少每天可以为我们节省约 924 GB 的带宽,也就是每年 329 terabytes

光凭这些数据,就应该足以让一些人回头。

现在,回到现实中,我们改造的仅仅只是一个版本,但这种改造仍然支持微软更多“高级”的设计(就像现在在 IE/Win 中看到的那样),在很多其它流行的浏览器中仍然如此。

不管像微软这样的公司是不是需要只维护其主页的一个版本来支持所有的浏览器,来提高页面加载速促,来使其更容易被所有的用户和设备所访问,我觉得值得指出的是,现在非常容易的展示他们――或者任何公司―― 能够创建一个高级的版本,使用更干净的标记,能支持更多的浏览器,能更容易地被访问。所有的展示花费不过一两小时。

更多要点和警示

  • 如果您感到好奇,并且想更仔细一些,CSS 在改造过程中对原版本仅仅增加了 3KB / 5KB(分别对应 IE/Win 和非 IE/Win 版本)到 8KB。
  • IE/Win 版本左侧导航中两个选项所带有的弹出式菜单一样可以被重现。所有这些都由纯 CSS,简单、易懂且更容易访问的标记实现。当鼠标悬垂到列表父列表条目上时,改造版本用 :hover 伪类(pseudo-class)来开关一个内嵌的无序列表(子菜单)。考虑到 IE 在列表条目上不支持 :hover,所以为了在此浏览器上支持弹出式菜单,微软正在使用的 JavaScript 仍然是必要的。或者类似于 Suckerfish Dropdowns 的东西能够用来保持和改造版本所使用的同样易懂的内嵌列表标记。
  • 微软当前的非 IE/Win 版本上如此大的图片标签缩减主要是来源于占位 GIF 的滥用。另外,非 IE/Win 版本单独调用所有列表强调符图片,而不像其 IE/Win 版本以及改造版本那样,通过一条单独的 CSS 声明来调用。
  • 微软网站上能够找到的所有 JavaScript 标记都被移除了。链接元素上成百上千的属性标记显然是出于点击追踪目的。Microsoft would likely want to add some of this layer back in ― though hopefully through a valid means of doing so.
  • 正如前面提到的,此文的目的是为了公布使用 CSS 和更简单的、易懂的标记来构建页面所带来的潜在结果和益处。我们仅仅用微软作为一个注明的范例。此文有意没有给出改造后的代码。我明白很多人能够从本次演讲讨论的成果中学到东西。即使没有参加演讲,也能够从对 HTML 和 CSS 代码的修改上获益。但是,我无意通过公开发表对源代码的修改来贬低任何人在微软的角色。我更倾向于有机会能够直接将它们展示给微软,与合适的团队成员讨论这些改变以及相关技术,如果他们愿意这么做的话。
]]>
建一个XMLHttpRequest对象池 http://www.phpv.net/html/1490.html http://www.phpv.net/html/1490.html#comment Tue, 27 Dec 2005 10:36:20 +0000 easy http://www.phpv.net/html/1490.html

在ajax应用中,通常一个页面要同时发送多个请求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆盖掉,如果每次都创建一个新的XMLHttpRequest对象,也会造成浪费。解决的办法就是创建一个XMLHttpRequset的对象池,如果池里有空闲的对象,则使用此对象,否则将创建一个新的对象。

下面是我最近写的一个简单的类:

/**
 * XMLHttpRequest Object Pool
 *
 * @author    legend <legendsky@hotmail.com>
 * @link      http://www.ugia.cn/?p=85
 * @Copyright www.ugia.cn
 */ 
    
var XMLHttp = {
    
_objPool: [],
    
    
_getInstance: function ()
    {
        for (var 
0this._objPool.length++)
        {
            if (
this._objPool[i].readyState == || this._objPool[i].readyState == 4)
            {
                return 
this._objPool[i];
            }
        }
    
        
// IE5中不支持push方法
        
this._objPool[this._objPool.length] = this._createObj();
    
        return 
this._objPool[this._objPool.length 1];
    },
    
    
_createObj: function ()
    {
        if (
window.XMLHttpRequest)
        {
            var 
objXMLHttp = new XMLHttpRequest();
    
        }
        else
        {
            var 
MSXML = ['MSXML2.XMLHTTP.5.0''MSXML2.XMLHTTP.4.0''MSXML2.XMLHTTP.3.0''MSXML2.XMLHTTP''Microsoft.XMLHTTP'];
            for(var 
0MSXML.length++)
            {
                
try
                
{
                    var 
objXMLHttp = new ActiveXObject(MSXML[n]);
                    break;
                }
                
catch(e)
                {
                }
            }
         }          
    
        
// mozilla某些版本没有readyState属性
        
if (objXMLHttp.readyState == null)
        {
            
objXMLHttp.readyState 0;
    
            
objXMLHttp.addEventListener("load", function ()
                {
                    
objXMLHttp.readyState 4;
    
                    if (
typeof objXMLHttp.onreadystatechange == "function")
                    {
                        
objXMLHttp.onreadystatechange();
                    }
                },  
false);
        }
    
        return 
objXMLHttp;
    },
    
    
// 发送请求(方法[post,get], 地址, 数据, 回调函数)
    
sendReq: function (methodurldatacallback)
    {
        var 
objXMLHttp this._getInstance();
    
        
with(objXMLHttp)
        {
            
try
            
{
                
// 加随机数防止缓存
                
if (url.indexOf("?") > 0)
                {
                    
url += "&randnum=" Math.random();
                }
                else
                {
                    
url += "?randnum=" Math.random();
                }
    
                
open(methodurltrue);
    
                
// 设定请求编码方式
                
setRequestHeader('Content-Type''application/x-www-form-urlencoded; charset=UTF-8');
                
send(data);
                
onreadystatechange = function ()
                {
                    if (
objXMLHttp.readyState == && (objXMLHttp.status == 200 || objXMLHttp.status == 304))
                    {
                        
callback(objXMLHttp);
                    }
                }
            }
            
catch(e)
            {
                
alert(e);
            }
        }
    }
}; 

示例:

<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript">
function test(obj)
{
    alert(obj.statusText);
}
    
XMLHttp.sendReq('GET', 'http://www.ugia.cn/wp-data/test.htm', '', test);
XMLHttp.sendReq('GET', 'http://www.ugia.cn/wp-data/test.htm', '', test);
XMLHttp.sendReq('GET', 'http://www.ugia.cn/wp-data/test.htm', '', test);
XMLHttp.sendReq('GET', 'http://www.ugia.cn/wp-data/test.htm', '', test);
    
alert('Pool length:' + XMLHttp._objPool.length);
</script> 

demo 下载xmlhttp.js

]]>
JS控制文本框只能输入N个字符. http://www.phpv.net/html/1458.html http://www.phpv.net/html/1458.html#comment Wed, 13 Jul 2005 12:27:53 +0000 easy http://www.phpv.net/html/1458.html

下面的文本框,只能输入十个字符

 

代码:


 

<script type="text/javascript">

function ismaxlength(obj){
var mlength=obj.getAttribute? parseInt(obj.getAttribute("maxlength")) : ""
if (obj.getAttribute && obj.value.length>mlength)
obj.value=obj.value.substring(0,mlength)
}

</script>

<textarea maxlength="10" onkeyup="return ismaxlength(this)"></textarea>

]]>
利用客户端js实现汉字简体繁体转换 http://www.phpv.net/html/1429.html http://www.phpv.net/html/1429.html#comment Wed, 27 Apr 2005 22:35:38 +0000 抽烟的蚊子 http://www.phpv.net/html/1429.html <TITLE> New Document </TITLE>
</HEAD>

<BODY>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=GB2312">
<title>汉字简体繁体转换</title>
</head>
<body>
<center>
<h3>汉字简体<u><b><font color="#FF0000">繁体</font></b></u><u><b><font color="#FF0000">转换</font></b></u>(原创)</h3>
<input type=radio name=r1 value=0 onclick="h1.value=0;convert()" checked>简体
<input type=radio name=r1 value=1 onclick="h1.value=1;convert()"><u><b><font color="#FF0000">繁体</font></b></u>
<br>
<textarea id=txt rows=10 cols=50 value=''></textarea><br>
<input type=hidden name=h1 value=0>
<img width=0 height=100>
<hr>
Simple is beauty.
<script>
//*************Copyright 2003*****************
// This script is written by neweroica, 2003-1-6
//******************************************
function charPYStr(){
return '啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬扳般颁板版扮拌伴瓣半办绊邦帮梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥薄雹保堡饱宝抱报暴豹鲍爆杯碑悲卑北辈背贝钡倍狈备惫焙被奔苯本笨崩绷甭泵蹦迸逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必辟壁臂避陛鞭边编贬扁便变卞辨辩辫遍标彪膘表鳖憋别瘪彬斌濒滨宾摈兵冰柄丙秉饼炳病并玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳捕卜哺补埠不布步簿部怖擦猜裁材才财睬踩采彩菜蔡餐参蚕残惭惨灿苍舱仓沧藏操糙槽曹草厕策侧册测层蹭插叉茬茶查碴搽察岔差诧拆柴豺搀掺蝉馋谗缠铲产阐颤昌猖场尝常长偿肠厂敞畅唱倡超抄钞朝嘲潮巢吵炒车扯撤掣彻澈郴臣辰尘晨忱沉陈趁衬撑称城橙成呈乘程惩澄诚承逞骋秤吃痴持匙池迟弛驰耻齿侈尺赤翅斥炽充冲虫崇宠抽酬畴踌稠愁筹仇绸瞅丑臭初出橱厨躇锄雏滁除楚础储矗搐触处揣川穿椽传船喘串疮窗幢床闯创吹炊捶锤垂春椿醇唇淳纯蠢戳绰疵茨磁雌辞慈瓷词此刺赐次聪葱囱匆从丛凑粗醋簇促蹿篡窜摧崔催脆瘁粹淬翠村存寸磋撮搓措挫错搭达答瘩打大呆歹傣戴带殆代贷袋待逮怠耽担丹单郸掸胆旦氮但惮淡诞弹蛋当挡党荡档刀捣蹈倒岛祷导到稻悼道盗德得的蹬灯登等瞪凳邓堤低滴迪敌笛狄涤翟嫡抵底地蒂第帝弟递缔颠掂滇碘点典靛垫电佃甸店惦奠淀殿碉叼雕凋刁掉吊钓调跌爹碟蝶迭谍叠丁盯叮钉顶鼎锭定订丢东冬董懂动栋侗恫冻洞兜抖斗陡豆逗痘都督毒犊独读堵睹赌杜镀肚度渡妒端短锻段断缎堆兑队对墩吨蹲敦顿囤钝盾遁掇哆多夺垛躲朵跺舵剁惰堕蛾峨鹅俄额讹娥恶厄扼遏鄂饿恩而儿耳尔饵洱二贰发罚筏伐乏阀法珐藩帆番翻樊矾钒繁凡烦反返范贩犯饭泛坊芳方肪房防妨仿访纺放菲非啡飞肥匪诽吠肺废沸费芬酚吩氛分纷坟焚汾粉奋份忿愤粪丰封枫蜂峰锋风疯烽逢冯缝讽奉凤佛否夫敷肤孵扶拂辐幅氟符伏俘服浮涪福袱弗甫抚辅俯釜斧脯腑府腐赴副覆赋复傅付阜父腹负富讣附妇缚咐噶嘎该改概钙盖溉干甘杆柑竿肝赶感秆敢赣冈刚钢缸肛纲岗港杠篙皋高膏羔糕搞镐稿告哥歌搁戈鸽胳疙割革葛格蛤阁隔铬个各给根跟耕更庚羹埂耿梗工攻功恭龚供躬公宫弓巩汞拱贡共钩勾沟苟狗垢构购够辜菇咕箍估沽孤姑鼓古蛊骨谷股故顾固雇刮瓜剐寡挂褂乖拐怪棺关官冠观管馆罐惯灌贯光广逛瑰规圭硅归龟闺轨鬼诡癸桂柜跪贵刽辊滚棍锅郭国果裹过哈骸孩海氦亥害骇酣憨邯韩含涵寒函喊罕翰撼捍旱憾悍焊汗汉夯杭航壕嚎豪毫郝好耗号浩呵喝荷菏核禾和何合盒貉阂河涸赫褐鹤贺嘿黑痕很狠恨哼亨横衡恒轰哄烘虹鸿洪宏弘红喉侯猴吼厚候后呼乎忽瑚壶葫胡蝴狐糊湖弧虎唬护互沪户花哗华猾滑画划化话槐徊怀淮坏欢环桓还缓换患唤痪豢焕涣宦幻荒慌黄磺蝗簧皇凰惶煌晃幌恍谎灰挥辉徽恢蛔回毁悔慧卉惠晦贿秽会烩汇讳诲绘荤昏婚魂浑混豁活伙火获或惑霍货祸击圾基机畸稽积箕肌饥迹激讥鸡姬绩缉吉极棘辑籍集及急疾汲即嫉级挤几脊己蓟技冀季伎祭剂悸济寄寂计记既忌际继纪嘉枷夹佳家加荚颊贾甲钾假稼价架驾嫁歼监坚尖笺间煎兼肩艰奸缄茧检柬碱硷拣捡简俭剪减荐槛鉴践贱见键箭件健舰剑饯渐溅涧建僵姜将浆江疆蒋桨奖讲匠酱降蕉椒礁焦胶交郊浇骄娇嚼搅铰矫侥脚狡角饺缴绞剿教酵轿较叫窖揭接皆秸街阶截劫节茎睛晶鲸京惊精粳经井警景颈静境敬镜径痉靖竟竞净炯窘揪究纠玖韭久灸九酒厩救旧臼舅咎就疚鞠拘狙疽居驹菊局咀矩举沮聚拒据巨具距踞锯俱句惧炬剧捐鹃娟倦眷卷绢撅攫抉掘倔爵桔杰捷睫竭洁结解姐戒藉芥界借介疥诫届巾筋斤金今津襟紧锦仅谨进靳晋禁近烬浸尽劲荆兢觉决诀绝均菌钧军君峻俊竣浚郡骏喀咖卡咯开揩楷凯慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕颗科壳咳可渴克刻客课肯啃垦恳坑吭空恐孔控抠口扣寇枯哭窟苦酷库裤夸垮挎跨胯块筷侩快宽款匡筐狂框矿眶旷况亏盔岿窥葵奎魁傀馈愧溃坤昆捆困括扩廓阔垃拉喇蜡腊辣啦莱来赖蓝婪栏拦篮阑兰澜谰揽览懒缆烂滥琅榔狼廊郎朗浪捞劳牢老佬姥酪烙涝勒乐雷镭蕾磊累儡垒擂肋类泪棱楞冷厘梨犁黎篱狸离漓理李里鲤礼莉荔吏栗丽厉励砾历利傈例俐痢立粒沥隶力璃哩俩联莲连镰廉怜涟帘敛脸链恋炼练粮凉梁粱良两辆量晾亮谅撩聊僚疗燎寥辽潦了撂镣廖料列裂烈劣猎琳林磷霖临邻鳞淋凛赁吝拎玲菱零龄铃伶羚凌灵陵岭领另令溜琉榴硫馏留刘瘤流柳六龙聋咙笼窿隆垄拢陇楼娄搂篓漏陋芦卢颅庐炉掳卤虏鲁麓碌露路赂鹿潞禄录陆戮驴吕铝侣旅履屡缕虑氯律率滤绿峦挛孪滦卵乱掠略抡轮伦仑沦纶论萝螺罗逻锣箩骡裸落洛骆络妈麻玛码蚂马骂嘛吗埋买麦卖迈脉瞒馒蛮满蔓曼慢漫谩芒茫盲氓忙莽猫茅锚毛矛铆卯茂冒帽貌贸么玫枚梅酶霉煤没眉媒镁每美昧寐妹媚门闷们萌蒙檬盟锰猛梦孟眯醚靡糜迷谜弥米秘觅泌蜜密幂棉眠绵冕免勉娩缅面苗描瞄藐秒渺庙妙蔑灭民抿皿敏悯闽明螟鸣铭名命谬摸摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌谋牟某拇牡亩姆母墓暮幕募慕木目睦牧穆拿哪呐钠那娜纳氖乃奶耐奈南男难囊挠脑恼闹淖呢馁内嫩能妮霓倪泥尼拟你匿腻逆溺蔫拈年碾撵捻念娘酿鸟尿捏聂孽啮镊镍涅您柠狞凝宁拧泞牛扭钮纽脓浓农弄奴努怒女暖虐疟挪懦糯诺哦欧鸥殴藕呕偶沤啪趴爬帕怕琶拍排牌徘湃派攀潘盘磐盼畔判叛乓庞旁耪胖抛咆刨炮袍跑泡呸胚培裴赔陪配佩沛喷盆砰抨烹澎彭蓬棚硼篷膨朋鹏捧碰坯砒霹批披劈琵毗啤脾疲皮匹痞僻屁譬篇偏片骗飘漂瓢票撇瞥拼频贫品聘乒坪苹萍平凭瓶评屏坡泼颇婆破魄迫粕剖扑铺仆莆葡菩蒲埔朴圃普浦谱曝瀑期欺栖戚妻七凄漆柒沏其棋奇歧畦崎脐齐旗祈祁骑起岂乞企启契砌器气迄弃汽泣讫掐洽牵扦钎铅千迁签仟谦乾黔钱钳前潜遣浅谴堑嵌欠歉枪呛腔羌墙蔷强抢橇锹敲悄桥瞧乔侨巧鞘撬翘峭俏窍切茄且怯窃钦侵亲秦琴勤芹擒禽寝沁青轻氢倾卿清擎晴氰情顷请庆琼穷秋丘邱球求囚酋泅趋区蛆曲躯屈驱渠取娶龋趣去圈颧权醛泉全痊拳犬券劝缺炔瘸却鹊榷确雀裙群然燃冉染瓤壤攘嚷让饶扰绕惹热壬仁人忍韧任认刃妊纫扔仍日戎茸蓉荣融熔溶容绒冗揉柔肉茹蠕儒孺如辱乳汝入褥软阮蕊瑞锐闰润若弱撒洒萨腮鳃塞赛三叁伞散桑嗓丧搔骚扫嫂瑟色涩森僧莎砂杀刹沙纱傻啥煞筛晒珊苫杉山删煽衫闪陕擅赡膳善汕扇缮墒伤商赏晌上尚裳梢捎稍烧芍勺韶少哨邵绍奢赊蛇舌舍赦摄射慑涉社设砷申呻伸身深娠绅神沈审婶甚肾慎渗声生甥牲升绳省盛剩胜圣师失狮施湿诗尸虱十石拾时什食蚀实识史矢使屎驶始式示士世柿事拭誓逝势是嗜噬适仕侍释饰氏市恃室视试收手首守寿授售受瘦兽蔬枢梳殊抒输叔舒淑疏书赎孰熟薯暑曙署蜀黍鼠属术述树束戍竖墅庶数漱恕刷耍摔衰甩帅栓拴霜双爽谁水睡税吮瞬顺舜说硕朔烁斯撕嘶思私司丝死肆寺嗣四伺似饲巳松耸怂颂送宋讼诵搜艘擞嗽苏酥俗素速粟僳塑溯宿诉肃酸蒜算虽隋随绥髓碎岁穗遂隧祟孙损笋蓑梭唆缩琐索锁所塌他它她塔獭挞蹋踏胎苔抬台泰酞太态汰坍摊贪瘫滩坛檀痰潭谭谈坦毯袒碳探叹炭汤塘搪堂棠膛唐糖倘躺淌趟烫掏涛滔绦萄桃逃淘陶讨套特藤腾疼誊梯剔踢锑提题蹄啼体替嚏惕涕剃屉天添填田甜恬舔腆挑条迢眺跳贴铁帖厅听烃汀廷停亭庭挺艇通桐酮瞳同铜彤童桶捅筒统痛偷投头透凸秃突图徒途涂屠土吐兔湍团推颓腿蜕褪退吞屯臀拖托脱鸵陀驮驼椭妥拓唾挖哇蛙洼娃瓦袜歪外豌弯湾玩顽丸烷完碗挽晚皖惋宛婉万腕汪王亡枉网往旺望忘妄威巍微危韦违桅围唯惟为潍维苇萎委伟伪尾纬未蔚味畏胃喂魏位渭谓尉慰卫瘟温蚊文闻纹吻稳紊问嗡翁瓮挝蜗涡窝我斡卧握沃巫呜钨乌污诬屋无芜梧吾吴毋武五捂午舞伍侮坞戊雾晤物勿务悟误昔熙析西硒矽晰嘻吸锡牺稀息希悉膝夕惜熄烯溪汐犀檄袭席习媳喜铣洗系隙戏细瞎虾匣霞辖暇峡侠狭下厦夏吓掀锨先仙鲜纤咸贤衔舷闲涎弦嫌显险现献县腺馅羡宪陷限线相厢镶香箱襄湘乡翔祥详想响享项巷橡像向象萧硝霄削哮嚣销消宵淆晓小孝校肖啸笑效楔些歇蝎鞋协挟携邪斜胁谐写械卸蟹懈泄泻谢屑薪芯锌欣辛新忻心信衅星腥猩惺兴刑型形邢行醒幸杏性姓兄凶胸匈汹雄熊休修羞朽嗅锈秀袖绣墟戌需虚嘘须徐许蓄酗叙旭序畜恤絮婿绪续轩喧宣悬旋玄选癣眩绚靴薛学穴雪血勋熏循旬询寻驯巡殉汛训讯逊迅压押鸦鸭呀丫芽牙蚜崖衙涯雅哑亚讶焉咽阉烟淹盐严研蜒岩延言颜阎炎沿奄掩眼衍演艳堰燕厌砚雁唁彦焰宴谚验殃央鸯秧杨扬佯疡羊洋阳氧仰痒养样漾邀腰妖瑶摇尧遥窑谣姚咬舀药要耀椰噎耶爷野冶也页掖业叶曳腋夜液一壹医揖铱依伊衣颐夷遗移仪胰疑沂宜姨彝椅蚁倚已乙矣以艺抑易邑屹亿役臆逸肄疫亦裔意毅忆义益溢诣议谊译异翼翌绎茵荫因殷音阴姻吟银淫寅饮尹引隐印英樱婴鹰应缨莹萤营荧蝇迎赢盈影颖硬映哟拥佣臃痈庸雍踊蛹咏泳涌永恿勇用幽优悠忧尤由邮铀犹油游酉有友右佑釉诱又幼迂淤于盂榆虞愚舆余俞逾鱼愉渝渔隅予娱雨与屿禹宇语羽玉域芋郁吁遇喻峪御愈欲狱育誉浴寓裕预豫驭鸳渊冤元垣袁原援辕园员圆猿源缘远苑愿怨院曰约越跃钥岳粤月悦阅耘云郧匀陨允运蕴酝晕韵孕匝砸杂栽哉灾宰载再在咱攒暂赞赃脏葬遭糟凿藻枣早澡蚤躁噪造皂灶燥责择则泽贼怎增憎曾赠扎喳渣札轧铡闸眨栅榨咋乍炸诈摘斋宅窄债寨瞻毡詹粘沾盏斩辗崭展蘸栈占战站湛绽樟章彰漳张掌涨杖丈帐账仗胀瘴障招昭找沼赵照罩兆肇召遮折哲蛰辙者锗蔗这浙珍斟真甄砧臻贞针侦枕疹诊震振镇阵蒸挣睁征狰争怔整拯正政帧症郑证芝枝支吱蜘知肢脂汁之织职直植殖执值侄址指止趾只旨纸志挚掷至致置帜峙制智秩稚质炙痔滞治窒中盅忠钟衷终种肿重仲众舟周州洲诌粥轴肘帚咒皱宙昼骤珠株蛛朱猪诸诛逐竹烛煮拄瞩嘱主著柱助蛀贮铸筑住注祝驻抓爪拽专砖转撰赚篆桩庄装妆撞壮状椎锥追赘坠缀谆准捉拙卓桌琢茁酌啄着灼浊兹咨资姿滋淄孜紫仔籽滓子自渍字鬃棕踪宗综总纵邹走奏揍租足卒族祖诅阻组钻纂嘴醉最罪尊遵昨左佐柞做作坐座';
}

function ftPYStr(){
return '啊阿埃挨哎唉哀皚癌藹矮艾礙愛隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翺襖傲奧懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙壩霸罷爸白柏百擺佰敗拜稗斑班搬扳般頒板版扮拌伴瓣半辦絆邦幫梆榜膀綁棒磅蚌鎊傍謗苞胞包褒剝薄雹保堡飽寶抱報暴豹鮑爆杯碑悲卑北輩背貝鋇倍狽備憊焙被奔苯本笨崩繃甭泵蹦迸逼鼻比鄙筆彼碧蓖蔽畢斃毖幣庇痹閉敝弊必辟壁臂避陛鞭邊編貶扁便變卞辨辯辮遍標彪膘表鼈憋別癟彬斌瀕濱賓擯兵冰柄丙秉餅炳病並玻菠播撥缽波博勃搏鉑箔伯帛舶脖膊渤泊駁捕蔔哺補埠不布步簿部怖擦猜裁材才財睬踩采彩菜蔡餐參蠶殘慚慘燦蒼艙倉滄藏操糙槽曹草廁策側冊測層蹭插叉茬茶查碴搽察岔差詫拆柴豺攙摻蟬饞讒纏鏟産闡顫昌猖場嘗常長償腸廠敞暢唱倡超抄鈔朝嘲潮巢吵炒車扯撤掣徹澈郴臣辰塵晨忱沈陳趁襯撐稱城橙成呈乘程懲澄誠承逞騁秤吃癡持匙池遲弛馳恥齒侈尺赤翅斥熾充沖蟲崇寵抽酬疇躊稠愁籌仇綢瞅醜臭初出櫥廚躇鋤雛滁除楚礎儲矗搐觸處揣川穿椽傳船喘串瘡窗幢床闖創吹炊捶錘垂春椿醇唇淳純蠢戳綽疵茨磁雌辭慈瓷詞此刺賜次聰蔥囪匆從叢湊粗醋簇促躥篡竄摧崔催脆瘁粹淬翠村存寸磋撮搓措挫錯搭達答瘩打大呆歹傣戴帶殆代貸袋待逮怠耽擔丹單鄲撣膽旦氮但憚淡誕彈蛋當擋黨蕩檔刀搗蹈倒島禱導到稻悼道盜德得的蹬燈登等瞪凳鄧堤低滴迪敵笛狄滌翟嫡抵底地蒂第帝弟遞締顛掂滇碘點典靛墊電佃甸店惦奠澱殿碉叼雕凋刁掉吊釣調跌爹碟蝶叠諜疊丁盯叮釘頂鼎錠定訂丟東冬董懂動棟侗恫凍洞兜抖鬥陡豆逗痘都督毒犢獨讀堵睹賭杜鍍肚度渡妒端短鍛段斷緞堆兌隊對墩噸蹲敦頓囤鈍盾遁掇哆多奪垛躲朵跺舵剁惰墮蛾峨鵝俄額訛娥惡厄扼遏鄂餓恩而兒耳爾餌洱二貳發罰筏伐乏閥法琺藩帆番翻樊礬釩繁凡煩反返範販犯飯泛坊芳方肪房防妨仿訪紡放菲非啡飛肥匪誹吠肺廢沸費芬酚吩氛分紛墳焚汾粉奮份忿憤糞豐封楓蜂峰鋒風瘋烽逢馮縫諷奉鳳佛否夫敷膚孵扶拂輻幅氟符伏俘服浮涪福袱弗甫撫輔俯釜斧脯腑府腐赴副覆賦複傅付阜父腹負富訃附婦縛咐噶嘎該改概鈣蓋溉幹甘杆柑竿肝趕感稈敢贛岡剛鋼缸肛綱崗港杠篙臯高膏羔糕搞鎬稿告哥歌擱戈鴿胳疙割革葛格蛤閣隔鉻個各給根跟耕更庚羹埂耿梗工攻功恭龔供躬公宮弓鞏汞拱貢共鈎勾溝苟狗垢構購夠辜菇咕箍估沽孤姑鼓古蠱骨谷股故顧固雇刮瓜剮寡挂褂乖拐怪棺關官冠觀管館罐慣灌貫光廣逛瑰規圭矽歸龜閨軌鬼詭癸桂櫃跪貴劊輥滾棍鍋郭國果裹過哈骸孩海氦亥害駭酣憨邯韓含涵寒函喊罕翰撼捍旱憾悍焊汗漢夯杭航壕嚎豪毫郝好耗號浩呵喝荷菏核禾和何合盒貉閡河涸赫褐鶴賀嘿黑痕很狠恨哼亨橫衡恒轟哄烘虹鴻洪宏弘紅喉侯猴吼厚候後呼乎忽瑚壺葫胡蝴狐糊湖弧虎唬護互滬戶花嘩華猾滑畫劃化話槐徊懷淮壞歡環桓還緩換患喚瘓豢煥渙宦幻荒慌黃磺蝗簧皇凰惶煌晃幌恍謊灰揮輝徽恢蛔回毀悔慧卉惠晦賄穢會燴彙諱誨繪葷昏婚魂渾混豁活夥火獲或惑霍貨禍擊圾基機畸稽積箕肌饑迹激譏雞姬績緝吉極棘輯籍集及急疾汲即嫉級擠幾脊己薊技冀季伎祭劑悸濟寄寂計記既忌際繼紀嘉枷夾佳家加莢頰賈甲鉀假稼價架駕嫁殲監堅尖箋間煎兼肩艱奸緘繭檢柬堿鹼揀撿簡儉剪減薦檻鑒踐賤見鍵箭件健艦劍餞漸濺澗建僵姜將漿江疆蔣槳獎講匠醬降蕉椒礁焦膠交郊澆驕嬌嚼攪鉸矯僥腳狡角餃繳絞剿教酵轎較叫窖揭接皆稭街階截劫節莖睛晶鯨京驚精粳經井警景頸靜境敬鏡徑痙靖竟競淨炯窘揪究糾玖韭久灸九酒廄救舊臼舅咎就疚鞠拘狙疽居駒菊局咀矩舉沮聚拒據巨具距踞鋸俱句懼炬劇捐鵑娟倦眷卷絹撅攫抉掘倔爵桔傑捷睫竭潔結解姐戒藉芥界借介疥誡屆巾筋斤金今津襟緊錦僅謹進靳晉禁近燼浸盡勁荊兢覺決訣絕均菌鈞軍君峻俊竣浚郡駿喀咖卡咯開揩楷凱慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕顆科殼咳可渴克刻客課肯啃墾懇坑吭空恐孔控摳口扣寇枯哭窟苦酷庫褲誇垮挎跨胯塊筷儈快寬款匡筐狂框礦眶曠況虧盔巋窺葵奎魁傀饋愧潰坤昆捆困括擴廓闊垃拉喇蠟臘辣啦萊來賴藍婪欄攔籃闌蘭瀾讕攬覽懶纜爛濫琅榔狼廊郎朗浪撈勞牢老佬姥酪烙澇勒樂雷鐳蕾磊累儡壘擂肋類淚棱楞冷厘梨犁黎籬狸離漓理李裏鯉禮莉荔吏栗麗厲勵礫曆利傈例俐痢立粒瀝隸力璃哩倆聯蓮連鐮廉憐漣簾斂臉鏈戀煉練糧涼梁粱良兩輛量晾亮諒撩聊僚療燎寥遼潦了撂鐐廖料列裂烈劣獵琳林磷霖臨鄰鱗淋凜賃吝拎玲菱零齡鈴伶羚淩靈陵嶺領另令溜琉榴硫餾留劉瘤流柳六龍聾嚨籠窿隆壟攏隴樓婁摟簍漏陋蘆盧顱廬爐擄鹵虜魯麓碌露路賂鹿潞祿錄陸戮驢呂鋁侶旅履屢縷慮氯律率濾綠巒攣孿灤卵亂掠略掄輪倫侖淪綸論蘿螺羅邏鑼籮騾裸落洛駱絡媽麻瑪碼螞馬罵嘛嗎埋買麥賣邁脈瞞饅蠻滿蔓曼慢漫謾芒茫盲氓忙莽貓茅錨毛矛鉚卯茂冒帽貌貿麽玫枚梅酶黴煤沒眉媒鎂每美昧寐妹媚門悶們萌蒙檬盟錳猛夢孟眯醚靡糜迷謎彌米秘覓泌蜜密冪棉眠綿冕免勉娩緬面苗描瞄藐秒渺廟妙蔑滅民抿皿敏憫閩明螟鳴銘名命謬摸摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌謀牟某拇牡畝姆母墓暮幕募慕木目睦牧穆拿哪呐鈉那娜納氖乃奶耐奈南男難囊撓腦惱鬧淖呢餒內嫩能妮霓倪泥尼擬你匿膩逆溺蔫拈年碾攆撚念娘釀鳥尿捏聶孽齧鑷鎳涅您檸獰凝甯擰濘牛扭鈕紐膿濃農弄奴努怒女暖虐瘧挪懦糯諾哦歐鷗毆藕嘔偶漚啪趴爬帕怕琶拍排牌徘湃派攀潘盤磐盼畔判叛乓龐旁耪胖抛咆刨炮袍跑泡呸胚培裴賠陪配佩沛噴盆砰抨烹澎彭蓬棚硼篷膨朋鵬捧碰坯砒霹批披劈琵毗啤脾疲皮匹痞僻屁譬篇偏片騙飄漂瓢票撇瞥拼頻貧品聘乒坪蘋萍平憑瓶評屏坡潑頗婆破魄迫粕剖撲鋪仆莆葡菩蒲埔樸圃普浦譜曝瀑期欺棲戚妻七淒漆柒沏其棋奇歧畦崎臍齊旗祈祁騎起豈乞企啓契砌器氣迄棄汽泣訖掐洽牽扡釺鉛千遷簽仟謙乾黔錢鉗前潛遣淺譴塹嵌欠歉槍嗆腔羌牆薔強搶橇鍬敲悄橋瞧喬僑巧鞘撬翹峭俏竅切茄且怯竊欽侵親秦琴勤芹擒禽寢沁青輕氫傾卿清擎晴氰情頃請慶瓊窮秋丘邱球求囚酋泅趨區蛆曲軀屈驅渠取娶齲趣去圈顴權醛泉全痊拳犬券勸缺炔瘸卻鵲榷確雀裙群然燃冉染瓤壤攘嚷讓饒擾繞惹熱壬仁人忍韌任認刃妊紉扔仍日戎茸蓉榮融熔溶容絨冗揉柔肉茹蠕儒孺如辱乳汝入褥軟阮蕊瑞銳閏潤若弱撒灑薩腮鰓塞賽三三傘散桑嗓喪搔騷掃嫂瑟色澀森僧莎砂殺刹沙紗傻啥煞篩曬珊苫杉山刪煽衫閃陝擅贍膳善汕扇繕墒傷商賞晌上尚裳梢捎稍燒芍勺韶少哨邵紹奢賒蛇舌舍赦攝射懾涉社設砷申呻伸身深娠紳神沈審嬸甚腎慎滲聲生甥牲升繩省盛剩勝聖師失獅施濕詩屍虱十石拾時什食蝕實識史矢使屎駛始式示士世柿事拭誓逝勢是嗜噬適仕侍釋飾氏市恃室視試收手首守壽授售受瘦獸蔬樞梳殊抒輸叔舒淑疏書贖孰熟薯暑曙署蜀黍鼠屬術述樹束戍豎墅庶數漱恕刷耍摔衰甩帥栓拴霜雙爽誰水睡稅吮瞬順舜說碩朔爍斯撕嘶思私司絲死肆寺嗣四伺似飼巳松聳慫頌送宋訟誦搜艘擻嗽蘇酥俗素速粟僳塑溯宿訴肅酸蒜算雖隋隨綏髓碎歲穗遂隧祟孫損筍蓑梭唆縮瑣索鎖所塌他它她塔獺撻蹋踏胎苔擡台泰酞太態汰坍攤貪癱灘壇檀痰潭譚談坦毯袒碳探歎炭湯塘搪堂棠膛唐糖倘躺淌趟燙掏濤滔縧萄桃逃淘陶討套特藤騰疼謄梯剔踢銻提題蹄啼體替嚏惕涕剃屜天添填田甜恬舔腆挑條迢眺跳貼鐵帖廳聽烴汀廷停亭庭挺艇通桐酮瞳同銅彤童桶捅筒統痛偷投頭透凸禿突圖徒途塗屠土吐兔湍團推頹腿蛻褪退吞屯臀拖托脫鴕陀馱駝橢妥拓唾挖哇蛙窪娃瓦襪歪外豌彎灣玩頑丸烷完碗挽晚皖惋宛婉萬腕汪王亡枉網往旺望忘妄威巍微危韋違桅圍唯惟爲濰維葦萎委偉僞尾緯未蔚味畏胃喂魏位渭謂尉慰衛瘟溫蚊文聞紋吻穩紊問嗡翁甕撾蝸渦窩我斡臥握沃巫嗚鎢烏汙誣屋無蕪梧吾吳毋武五捂午舞伍侮塢戊霧晤物勿務悟誤昔熙析西硒矽晰嘻吸錫犧稀息希悉膝夕惜熄烯溪汐犀檄襲席習媳喜銑洗系隙戲細瞎蝦匣霞轄暇峽俠狹下廈夏嚇掀鍁先仙鮮纖鹹賢銜舷閑涎弦嫌顯險現獻縣腺餡羨憲陷限線相廂鑲香箱襄湘鄉翔祥詳想響享項巷橡像向象蕭硝霄削哮囂銷消宵淆曉小孝校肖嘯笑效楔些歇蠍鞋協挾攜邪斜脅諧寫械卸蟹懈泄瀉謝屑薪芯鋅欣辛新忻心信釁星腥猩惺興刑型形邢行醒幸杏性姓兄凶胸匈洶雄熊休修羞朽嗅鏽秀袖繡墟戌需虛噓須徐許蓄酗敘旭序畜恤絮婿緒續軒喧宣懸旋玄選癬眩絢靴薛學穴雪血勳熏循旬詢尋馴巡殉汛訓訊遜迅壓押鴉鴨呀丫芽牙蚜崖衙涯雅啞亞訝焉咽閹煙淹鹽嚴研蜒岩延言顔閻炎沿奄掩眼衍演豔堰燕厭硯雁唁彥焰宴諺驗殃央鴦秧楊揚佯瘍羊洋陽氧仰癢養樣漾邀腰妖瑤搖堯遙窯謠姚咬舀藥要耀椰噎耶爺野冶也頁掖業葉曳腋夜液一壹醫揖銥依伊衣頤夷遺移儀胰疑沂宜姨彜椅蟻倚已乙矣以藝抑易邑屹億役臆逸肄疫亦裔意毅憶義益溢詣議誼譯異翼翌繹茵蔭因殷音陰姻吟銀淫寅飲尹引隱印英櫻嬰鷹應纓瑩螢營熒蠅迎贏盈影穎硬映喲擁傭臃癰庸雍踴蛹詠泳湧永恿勇用幽優悠憂尤由郵鈾猶油遊酉有友右佑釉誘又幼迂淤于盂榆虞愚輿余俞逾魚愉渝漁隅予娛雨與嶼禹宇語羽玉域芋郁籲遇喻峪禦愈欲獄育譽浴寓裕預豫馭鴛淵冤元垣袁原援轅園員圓猿源緣遠苑願怨院曰約越躍鑰嶽粵月悅閱耘雲鄖勻隕允運蘊醞暈韻孕匝砸雜栽哉災宰載再在咱攢暫贊贓髒葬遭糟鑿藻棗早澡蚤躁噪造皂竈燥責擇則澤賊怎增憎曾贈紮喳渣劄軋鍘閘眨柵榨咋乍炸詐摘齋宅窄債寨瞻氈詹粘沾盞斬輾嶄展蘸棧占戰站湛綻樟章彰漳張掌漲杖丈帳賬仗脹瘴障招昭找沼趙照罩兆肇召遮折哲蟄轍者鍺蔗這浙珍斟真甄砧臻貞針偵枕疹診震振鎮陣蒸掙睜征猙爭怔整拯正政幀症鄭證芝枝支吱蜘知肢脂汁之織職直植殖執值侄址指止趾只旨紙志摯擲至致置幟峙制智秩稚質炙痔滯治窒中盅忠鍾衷終種腫重仲衆舟周州洲謅粥軸肘帚咒皺宙晝驟珠株蛛朱豬諸誅逐竹燭煮拄矚囑主著柱助蛀貯鑄築住注祝駐抓爪拽專磚轉撰賺篆樁莊裝妝撞壯狀椎錐追贅墜綴諄准捉拙卓桌琢茁酌啄著灼濁茲咨資姿滋淄孜紫仔籽滓子自漬字鬃棕蹤宗綜總縱鄒走奏揍租足卒族祖詛阻組鑽纂嘴醉最罪尊遵昨左佐柞做作坐座';
}

function traditionalized(cc){
var str='';
for(var i=0;i<cc.length;i++){
if(charPYStr().indexOf(cc.charAt(i))!=-1)
str+=ftPYStr().charAt(charPYStr().indexOf(cc.charAt(i)));
else
str+=cc.charAt(i);
}
return str;
}

function simplized(cc){
var str='';
for(var i=0;i<cc.length;i++){
if(ftPYStr().indexOf(cc.charAt(i))!=-1)
str+=charPYStr().charAt(ftPYStr().indexOf(cc.charAt(i)));
else
str+=cc.charAt(i);
}
return str;
}

function convert(){
if(h1.value==0)
txt.value=simplized(txt.value);
else
txt.value=traditionalized(txt.value);
}

</script>
</center>
</body>
</html>

</BODY>
</HTML>
]]>
完美关闭窗口JS http://www.phpv.net/html/1408.html http://www.phpv.net/html/1408.html#comment Tue, 29 Mar 2005 18:00:09 +0000 easy http://www.phpv.net/html/1408.html <head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>New Page 1</title>
<!--
by fason(2003-5-20)
-->
</head>
<body>
<script language="JavaScript">
<!--
function CloseWin()
{
var ua=navigator.userAgent
var ie=navigator.appName=="Microsoft Internet Explorer"?true:false
if(ie){
    var IEversion=parseFloat(ua.substring(ua.indexOf("MSIE ")+5,ua.indexOf(";",ua.indexOf("MSIE "))))
 if(IEversion< 5.5){
    var str  = '<object id=noTipClose classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">'
    str += '<param name="Command" value="Close"></object>';
    document.body.insertAdjacentHTML("beforeEnd", str);
    document.all.noTipClose.Click();
    }
    else{
    window.opener =null;
    window.close();
    }
}
else{
window.close()
}
}
//-->
</script>
<input type=button value=关闭 onclick="CloseWin()">
</body>
</html>]]>