Perfil de zhu三界九重天FotosBlogListas Herramientas Ayuda

css式样重用、子选择器和组选择器

  原文

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

说实话,很久没有手写CSS了,一直在关注CSS重用的问题,正好看见,先抓了再说。

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

重用:
经常会用到一些基本的式样叠加,比如字体的颜色和加粗。网页中可能同时出现三种情况:1.字体为红色  2.字体加粗 3.字体红色加粗
这时我们只需要定义前两个css:
.red{color:red;}
.b{font-weight:bold;}
第三种情况时用<div class="red b"></div>


子选择器:
相对来说,简化html文件的代码更加重要,因此在css中使用子选择器非常有益,同时也使css代码更加容易理解。比如下面的代码:
<div id="sub_nav">
<ul>
<li> <a href="#">Item 1</a></li>>
<li> <a href="#">Item 2</a></li>
<li> <a href="#">Item 3</a></li>
</ul>
</div>
如果div li a都有各自的式样,采用子选择器,可以省略代码中li 和a 的class属性,从而简化代码:
#sub_nav { /* Some styling */ }
#sub_nav li { /* Some styling */ }
#sub_nav a { /* Some styling */ }
组选择器:
当一些元素类型、class或者id都有共同的一些属性,你就可以使用组选择器来避免多次的重复定义。这可以节省不少字节。
例如:定义所有标题的字体、颜色和margin,你可以这样写:
h1,h2,h3,h4,h5,h6 {
font-family:"Lucida Grande",Lucida,Arial,Helvetica,sans-serif;
color:#333;
margin:1em 0;
}
如果在使用时,有个别元素需要定义独立样式,你可以再加上新的定义,可以覆盖老的定义,例如:
h1 { font-size:2em; }
h2 { font-size:1.6em; }
重用、子选择器和组选择器的灵活使用可以非常有效的减少代码,同时非常有利的增加代码的可读性,具体的应用需要在具体编写过程中体会。

为什么选择ColdFusion?

 来源:http://cffaq.com/faq.cfm?f=1

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

ColdFusion确实很方便,越来越多的人开始投入到这里面,但MM已经卖掉了啊,心里不平衡的说。作为互联网多媒体的巨头MM做出来的CFM,其实是个不错的概念,但问题是,微软哥哥不是千手观音,等Vista做好了,战斗想必才刚刚开始吧。

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

 

1: ColdFusion的定义

ColdFusion可以从两方面来定义,它既是一种应用服务器也是一种编程语言。很多开发人员常常把它们当成一件事,他们用ColdFusion语言(CFML - ColdFusion Markup Language)来编写应有程序,并把编写的应用程序运行在ColdFusion服务器上。 但是用ColdFusion语言编写的应用程序可以运行在其它支持CFML的应用服务器上,如J2EE应用服务器,这样一来就给那些高端的应用服务器提供了另一种简洁高效的开发语言。不管您选择使用ColdFusion应用服务器还是选择使用其它的应用服务器,CFML语言都为您提供了一个快速开发功能强大的应用程序的有效方案。


2: ColdFusion的历史有多久?

ColdFusion开始于1995年,是历史最悠久的最为成熟的互联网应有服务器。


3: 有多少企业组织或个人使用ColdFusion?

在全世界范围内有超过1万个组织,12万台以上的服务器在运行ColdFusion.


4: 有多少开发人员在使用ColdFusion?

保守估计,大概有35万。但实际上的数字远远大于35万,一台运行ColdFusion的服务器上可以运行的多个ColdFusion程序,因此在一台服务器上进行开发的程序员也会有很多。


5: 和其它应用服务器相比,ColdFusion有多少成功?

应该说是非常成功的,ColdFusion是商业(需购买)应用服务器中的佼佼者,在使用量上仅次于ASP。在财富100当中有超过75%的企业在使用ColdFusion.


6: ColdFusion可以编写那些类型的应用程序呢?

ColdFusion可以用来编写各种各样的应用程序,包括动态互联网网站,电子商务网站或门户网站,但最主要的还是大量的企业内部互联网应用程序和数据库相关的应用程序。这一点始终是也将一直会是ColdFusion的强项。


7: 为什么我能看到的用ColdFusion开发的站点并不是很多?

其实用ColdFusion开发的站点是非常多的。但是由于大多数基于ColdFusion的应用程序都是企业内部互联网应用程序给以及和敏感数据库相关的应用程序,并不是对外公开的。所以看上去用ColdFusion的并不是很多。如果您想了解一下那些重要的企业在使用ColdFusion请访问如下地址:http://www.macromedia.com/ http://www.forta.com/cf/using/


8: 为什么那些公司会花钱购买ColdFusion,而不使用‘免费’的ASP或PHP?

说其它的一些应用服务器是免费的其实有点言过其实。的确,一些应用服务器可以被免费下载,但所提供的只是一些基本的核心的功能。在ColdFusion中提供了大量非常重要的功能和服务,如图表生成,全文搜索以及其它一些有用的模块如文件上传的处理和电子邮件的处理,而在ASP或PHP中这些模块都是要另外购买的。 最近的一项估算表明,如果要在ASP中加上ColdFusion专业版所提供的所有功能,总成本会到达3万美元。与此同时售价低于1千美元的ColdFusion专业版却集成了这些功能。而这还不包括由于使用了ColdFusion而减少的学习以及开发所需的周期和成本。


9: ColdFusion是不是属于专有技术,使用专有技术是不是很难得到保障?

不,ColdFusion不是专有技术。事实上,有不少其它产品(通过其它厂商)也是用CFML(或部分)来实现的。另外,ColdFusion充分利用了大量公开的技术标准,从数据库的集成(JDBC ,ODBC)到用XML来实现配置文件到使用J2EE作为ColdFusion的底层核心。


10: 什么是CFML?

CFML的全称是ColdFusion Markup Language,是一种特别适于用来编写互联网应用程序的语言。CFML看上去和传统的编程语言并不太一样,更接近HTML,因此和HTML一样非常的易学易用。CFML可以在ColdFusion应用程序服务器上运行,也可以在其它一些应用程序服务器运行。


11: 经常看到有人在说CFML并不是一种真正的编程语言,它到底是不是呢?

如果你能用CFML来编写程序,那它当然就是一种编程语言。至于为什么会有这种疑问,原因之一是CFML看上去和传统的编程语言不太一样(基于标签而非基于脚本)。这里有几点我们需要记住: 1)CFML是模仿HTML而设计的,主要是因为HTML易学易用,并且这也是HTML是互联网成功的原因之一。 2)CFML完全符合传统编程所需的基本要求(如流程控制,条件判断等),通过 和MX中新的SSAS(Server-side ActionScript)也可以实现脚本编程。 3)CFML是一种功能强大的编程语言,包括了100多个标签和200多个函数,能够满足常用的编程需求以及一些不常用的需求如:和LDAP交互,处理 XML,支持COM和CORBA,图表生成和全文搜索等。 4)比较有讽刺意味的是,在过去的5年里,CFML由于是基于标签的语言,所以常被说为不是一种真正的编程语言,但现在在ASP.NET中也能看到这种风格,在JSP中实际上也是在Java代码中嵌入了标签,更别提XML,完全是基于标签的。由此可见,CFML走的这条路是对的。


12: 什么是.CFM 和.CFC?

CFML代码常被保存为以.CFM 或.CFC 为扩展名的文件中。.CFM 是ColdFusion的标准扩展名,它可以是普通的文本文件,由其它文件所调用的文件或是自定义标签文件。.CFC 是ColdFusion的组件文件(可以被重复调用的ColdFusion对象)


13: ColdFusion是不是只是用来实现低端或入门级解决方案的?

当然不是。ColdFusion只是一种工具,能用这种工具做什么完全取决于你的能力。对于一些初学者来说,Coldfusion是一种简单的技术,用ColdFusion来开发一些简单的产品和入门级解决方案也的确非常容易。但这并不是说ColdFusion就只是用来实现低端或入门级解决方案的。不像其它的一些学起来非常容易的技术只能用来实现简单有限的功能,ColdFusion可以用来开发功能异常强大的解决方案。除了一些低端,入门级的解决方案,还有大量高端,至关重要的解决方案都是用ColdFusion来开发的。


14: ColdFusion是不是会让开发者养成不正规的编程习惯。

当然不,ColdFusion提供了所有必须的要素用以编写伸缩性强,结构性好,易于管理和维护的代码。ColdFusion并不强制你使用某种开发习惯或逻辑方法,ColdFusion最初的设计初衷就是要让开发者能通过一个简单的语言来高效的实现所需的功能。当然有很多开发者往往是在有一个清楚的想法之前就开始动手写代码了,然后在一点一点的完善他的想法。实际上也并不是所有的程序的开发都需要严格遵守并采用MVC设计模式。当然ColdFusion完全支持MVC设计模式(通过ColdFusion组件)并且也因该尽可能的使用。换句话说,ColdFusion不会让你养成不正规的编程习惯并在以后的开发过程中感觉力不从心,不管你处于那种开发水平,ColdFusion总是能满足你的要求并且帮你一点一点的进步。


15: 我没有任何编程经验,ColdFusion是不是也适合我?

绝对适合,当然你最好有HTML和SQL的基础知识,而且如果没有的话,用Dreamweaver MX也能完成一些开发。不像其它的一些编程语言,需要通过几周或几个月的学习,在学习ColdFusion几个小时以后你就能完成简单的开发了。


16: 我是一个有经验的 C 或/和 Java程序员,我有没有必要使用ColdFusion呢?

C 和 Java 是功能非常强大的低级编程语言,非常适合编写需极强处理能力的后台进程。但却非常不适合用它们来生成HTML给浏览器或处理HTML中的表单。在这方面它们没有什么优势。事实上一个比较好的方案是把ColdFusion和他们结合在一起。让ColdFusion来处理表现层,而用C 或 Java 来处理后台。


17: 我是一名Flash开发人员,需不需要用到ColdFusion

作为一名Flash开发人员,你一定了解开发能给用户带来丰富使用体验,极具交互性的互联网应用程序的重要性。Flash常被用来制作动画,简介,广告和一些特殊效果等等,但Flash还能用来实现更多的应用。Flash非常适合用来充当基于互联网应用程序的前台界面,而ColdFusion正好非常适合用来帮Flash处理后台任务。从Macromedia推出FlashMX和ColdFusionMX来,两者之间的结合应用就变得非常简单和高效 - Flash作为客户而ColdFusion作为服务器。


18: 我们公司的技术选型是定位在J2EE平台上的,是不是就不能用ColdFusion了呢?

正好相反,你们公司选择的是一个非常有战略意义的方案来建立你们的信息平台,这种方案可以让你用到一些功能强大的技术,也是现在越来越被看好的方案。 J2EE(Java平台)提供了一个能建立稳定,健壮极具伸缩性的应用程序的结构体系。但是它却需要更高的成本(不仅仅是软件本身的成本)J2EE平台的开发是非常复杂的,超过了大多数公司的技术人员的能力。而且就是对那些经验丰富的Java程序员来说,也不是所有的东西都需要用Java来实现。而ColdFusion MX可以运行在J2EE平台的顶端,利用J2EE所带来的强大结构和原有的投资,同时使得不懂Java的人也能利用它。或换句话来说,通过这种方式,ColdFusion MX 能让不懂Java的人利用Java的强大处理能力同时有能完成更多的应用开发。所以选择J2EE的并不意味放弃ColdFusion,对你来说反而是一种明智的选择 - 你已经花了大量的成本,再多加一点ColdFusion的成本,你就能使你的信息平台实现更多的功能。


19: ColdFusionMX的底层是基于Java技术的,那现在或将来在微软的Windows平台上会有什么问题吗?

大多数的ColdFusion都是安装在微软的Windows平台上的,并使用一些微软的后台产品(如SQL服务器)。所以无论如何对微软的Windows平台的支持都是不会被放弃的,而且随着ColdFusion MX对.NET的结合,这种支持会越来越被重视。同时,ColdFusion还能在大量非微软平台上运行,如:Linux, Solaris, 和 HP-UX。 也能使用各种各样的数据库,如:Oracle, DB2 和 mySQL - 所以ColdFusion是业界最灵活的产品。


20: 对任何一项技术来说,活跃的用户讨论群都是成功的关键之一,ColdFusion有没有类似的用户社区?

ColdFusion用户一直以来都是非常具有社区性的,而且ColdFusion的成长和发展方向很大程度上也都是由ColdFusion用户群来决定的。有数不清的讨论组,论坛,出版物和用户组和活动(包括有Macromedia组织的活动和非Macromedia组织的活动)。


21: Macromedia会不会专心致力于ColdFusion的发展?

一定会的。实际上,最新版本的ColdFusion(第一个完全由Macromedia开发的版本)是一个ColdFusion史上最大的开发小组所完成的,投入了大量的人力和物力。这一点就表明了Macromedia对ColdFusionColdFusion用户的承诺。

来源:http://cffaq.com/faq.cfm?f=1
18 agosto

Nvu-1.0 这个杀手不太冷

 
     NVU, 这款基于Mozilia核心的网页工具越来越好用,现在更是推出了1.0版,而且还是开源的东西。这对于Adobe来说真是个冲击(还是不习惯说Adobe,更习惯说MM,可惜MM被卖掉了)。
 
     用下来的感觉,还是不够细腻,特别是表格,属性框用弹出的,让用惯了MM的我,十分不爽。还有一点旦,就是没有拖放,这个咚咚还真是,忠于Mozilia啊,不好用的感觉都是一样的。
 
     这个咚咚组织叶面是基于<div>的,不过话说回来,div组织叶面还真的是很难阿,还要兼顾IE这个令人诟病的浏览器,想来NVU现在只是想吸引更多的Dw的用户吧,毕竟Adobe的东西从来都不便宜。
 
 
11 agosto

prototype 源码解读 之 prototype.js

原文 AJAX这东西真的蛮好,可惜用JS实在是头痛啊,特别是DOM的解析,操作,令人烦躁啊。
 

Blog


30 diciembre

Flash 视频(FLV)编码,转换,录制,播放方案

服务器端转换工具(Server-Side-FLV-Conversion)
场景:想把 MPG 或 AVI 上传到你的服务器并自动转换成 FLV 吗?

1,FFmpeg : [url=http://sourceforge.net/projects/ffmpeg%20教程(Google%20Video%20使用的就是这个东东.):%20http://klaus.geekserver.net/flash/streaming.html]http://sourceforge.net/projects/ffmpeg 教程(Google Video 使用的就是这个东东.): http://klaus.geekserver.net/flash/streaming.html[/url]
2,Flix Engine : http://www.on2.com/developer/flix-engine-sdk
3,Turbine Video Engine: http://www.on2.com/developer/flix-engine-sdk
4,Video to Flash Console: http://www.geovid.com/Video_to_Flash_Console

录像/实时广播(Record/Broadcast)
场景:想制作一个语音视频Blog满足自恋的欲望吗?

1,RED5: http://www.osflash.org/red5
2,Flash Media Server: http://www.macromedia.com/go/fms

在线编码,分享视频(Online Encode & Share)
场景:想不花钱就可以在线分享你的视频吗?

1,Google Video: http://video.google.com/
2,You Tube: http://www.youtube.com/
3,iFilm: http://www.ifilm.com/

本地 FLV 文件播放器(FLV Player)
场景:拿到了 FLV 文件不知道怎么播放了.

1,martijndevisser FLV Player: http://www.martijndevisser.com/blog/article/flv-player-updated
2,FlashGuru FLV Player: http://www.flashguru.co.uk/free-tool-flash-video-player
3,FCZone FLV Player: http://fczone.com/2006/01/fms-media-player.cfm

在线 FLV 文件播放器(Online FLV Player)
场景:知道一个在线FLV地址,又懒得下载和安装播放器.

1,Loadr: http://dengjie.com/loadr/
2,Google Player Generator: http://dengjie.com/temp/google_player.swf

——又找到一点关于它们的资料,附加在这里,和上面的大同小异(2006-08-24)。
客户端编码工具(Client-Side-FLV-Encoding)
1,Sorenson Squeeze
2,Riva FLV Encoder
3,Turbine Video Encoder
4,Flix Exporter
5,Flash 自带的Flash Video Exporter

服务器端转换工具(Server-Side-FLV-Conversion)
1,FFmpeg | 教程一 | 教程二
2,Flix Engine | 教程 | 范例
3,Turbine Video Engine
4,Video to Flash Console

录像/实时广播(Record/Broadcast)
1,RED5
2,Flash Media Server

在线编码,分享视频(Online Encode & Share)
1,Google Video
2,You Tube

本地 FLV 文件播放器(FLV Player)
1,martijndevisser FLV Player
2,FlashGuru FLV Player
3,FCZone FLV Player

在线 FLV 文件播放器(Online FLV Player)
1,Loadr
2,Google Player Generator

——————第3次添加
客户端编码工具(Client-Side-FLV-Encoding)
场景:拿到一个 MPG 或 AVI 文件,打算在个人电脑上转换成FLV.
1,Sorenson Squeeze
2,Riva FLV Encoder
3,Turbine Video Encoder
4,Flix Exporter
5,Video2Flash
6,Flash 自带的Flash Video Exporter
更多…
服务器端转换工具(Server-Side-FLV-Conversion)
场景:想把 MPG 或 AVI 上传到你的服务器并自动转换成 FLV 吗?
1,FFmpeg | 教程一 | 教程二(Google Video 使用的就是这个东东.)
2,Flix Engine | 教程 | 范例
3,Turbine Video Engine
4,Video to Flash Console
5,Mencoder
6,libvp62
录像/实时广播(Record/Broadcast)
场景:想制作一个语音视频Blog满足自恋的欲望吗?
1,RED5
2,Flash Media Server
在线编码,分享视频(Online Encode & Share)
场景:想不花钱就可以在线分享你的视频吗?
1,Google Video
2,You Tube
3,Vlog
4,Veoh
本地 FLV 文件播放器(FLV Player)
场景:拿到了 FLV 文件不知道怎么播放了.
1,martijndevisser FLV Player
2,FlashGuru FLV Player
3,FCZone FLV Player
在线 FLV 文件播放器(Online FLV Player)
场景:知道一个在线FLV地址,又懒得下载和安装播放器.
1,Loadr
2,Google Player Generator
3,Danger Video Player -Playlist Editor 

10 diciembre

[转] 正则表达式口诀

正则是每个程序员绕不开的堡垒,只有把它攻下来。我觉得正则之所以难,第一难是需要记忆,第二难是要求具备抽象逻辑思维。
签于网上太多的介绍都是一篇凶悍的短文,边看边理解可以,帮助记忆不行。又受五笔字型字根表口诀“白手看头三二斤...”的启发,试作“正则表达式助记口诀”又名“正则打油诗”,版本0.1,绝对原创,仿冒必究,:)

正则其实也势利,削尖头来把钱揣;  (指开始符号^和结尾符号$)
特殊符号认不了,弄个倒杠来引路;  (指\. \*等特殊符号)
倒杠后面跟小w, 数字字母来表示;  (\w跟数字字母;\d跟数字)
倒杠后面跟小d, 只有数字来表示;
倒杠后面跟小a, 报警符号嘀一声;
倒杠后面跟小b, 单词分界或退格;
倒杠后面跟小t, 制表符号很明了;
倒杠后面跟小r, 回车符号知道了;
倒杠后面跟小s, 空格符号很重要;
小写跟罢跟大写,多得实在不得了;
倒杠后面跟大W, 字母数字靠边站;
倒杠后面跟大S, 空白也就靠边站;
倒杠后面跟大D, 数字从此靠边站;
倒框后面跟大B, 不含开头和结尾;

单个字符要重复,三个符号来帮忙;   (* + ?)
0 星加1 到无穷,问号只管0 和1;   (*表0-n;+表1-n;?表0-1次重复)
花括号里学问多,重复操作能力强;   ({n} {n,} {n,m})
若要重复字符串,园括把它括起来;   ((abc){3} 表示字符串“abc”重复3次 )

特殊集合自定义,中括号来帮你忙;  
转义符号行不通,一个一个来排队;
实在多得排不下,横杠请来帮个忙;   ([1-5])
尖头放进中括号,反义定义威力大;   ([^a]指除“a”外的任意字符 )

竖作用可不小,两边正则互替换;    (键盘上与“\”是同一个键)
竖能用很多次,复杂定义很方便;

园括号,用途多;
反向引用指定组,数字排符对应它;   (“\b(\w+)\b\s+\1\b”中的数字“1”引用前面的“(\w+)”)
支持组名自定义,问号加上尖括号;   (“(?<Word>\w+)”中把“\w+”定义为组,组名为“Word”)

园括号,用途多,位置指定全靠它;
问号等号字符串,定位字符串前面;   (“\b\w+(?=ing\b)”定位“ing”前面的字符串)
若要定位串后面,中间插个小于号;   (“(?<=\bsub)\w+\b”定位“sub”后面的字符串)

问号加个惊叹号,后面跟串字符串;
PHPer都知道,  !是取反的意思;
后面不跟这一串,统统符合来报到;   (“\w*d(?!og)\w*”,“dog”不符合,“do”符合)

问号小于惊叹号,后面跟串字符串;
前面不放这一串,统统符合来报到;  

点号星号很贪婪,加个问号不贪婪;
加号问号有保底,至少重复一次多;
两个问号老规矩,0次1次团团转;
花括号后跟个?,贪婪变成不贪婪;
14 octubre

诊治cSS布局的十个方法

原文在这里http://stopnlisten.no.land.to/2007/01/css10.html,对于初学CSS布局的人也许会有很大的帮助。有经验的开发者在调试CSS布局时也能得到些启发。 1. 检查HTML元素是否有拼写错误、是否忘记结束标记 即使是老手也经常会弄错div的嵌套关系。可以用dreamweaver的验证功能检查一下有无错误。 2. 检查CSS是否正确 检查一下有无拼写错误、是否忘记结尾的 } 等。可以利用CleanCSS来检查 CSS的拼写错误。CleanCSS本是为CSS减肥的工具,但也能检查出拼写错误。 3. 确定错误发生的位置 如果错误影响了整体布局,则可以逐个删除div块,直到删除某个div块后显示恢复正常,即可确定错误发生的位置。 4. 利用border属性确定出错元素的布局特性 使用float属性布局一不小心就会出错。这时为元素添加border属性确定元素边界,错误原因即水落石出。 5. float元素的父元素不能指定clear属性 MacIE下如果对float的元素的父元素使用clear属性,周围的float元素布局就会混乱。这是MacIE的著名的bug,倘若不知道就会走弯路。 6. float元素务必指定width属性 很多浏览器在显示未指定width的float元素时会有bug。所以不管float元素的内容如何,一定要为其指定width属性。 另外指定元素时尽量使用em而不是px做单位。 7. float元素不能指定margin和padding等属性 IE在显示指定了margin和padding的float元素时有bug。因此不要对float元素指定margin和padding属性(可以在float元素内部嵌套一个div来设置margin和padding)。也可以使用hack方法为IE指定特别的值。 8. float元素的宽度之和要小于100% 如果float元素的宽度之和正好是100%,某些古老的浏览器将不能正常显示。因此请保证宽度之和小于99%。 9. 是否重设了默认的样式? 某些属性如margin、padding等,不同浏览器会有不同的解释。因此最好在开发前首先将全体的margin、padding设置为0、列表样式设置为none等。 10. 是否忘记了写DTD? 如果无论怎样调整不同浏览器显示结果还是不一样,那么可以检查一下页面开头是不是忘了写下面这行DTD:
07 abril

访问 IIS 元数据库失败 & 267904帮助

很常见的.net 错误,但错误提示以及微软的帮助让人一头雾水,解决方法如下:

CMD 到C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 对应版本即可 下执行 aspnet_regiis /r,然后重试

---------------------------------------------------------------------
访问 IIS 元数据库失败。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.Web.Hosting.HostingEnvironmentException: 访问 IIS 元数据库失败。
用于运行 ASP.NET 的进程帐户必须具有对 IIS 元数据库(如 IIS://servername/W3SVC)的读访问权。有关如何修改元数据库权限的信息,请参见 http://support.microsoft.com/?kbid=267904
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。

堆栈跟踪:
[HostingEnvironmentException: 访问 IIS 元数据库失败。]
   System.Web.Configuration.metabaseServerConfig.MapPathCaching(String siteID, VirtualPath path) +3492186
   System.Web.Configuration.metabaseServerConfig.System.Web.Configuration.IConfigMapPath.MapPath(String siteID, VirtualPath vpath) +9
   System.Web.Hosting.HostingEnvironment.MapPathActual(VirtualPath virtualPath, Boolean permitNull) +163
   System.Web.CachedPathData.GetConfigPathData(String configPath) +382
   System.Web.CachedPathData.GetConfigPathData(String configPath) +243
   System.Web.CachedPathData.GetApplicationPathData() +68
   System.Web.CachedPathData.GetVirtualPathData(VirtualPath virtualPath, Boolean permitPathsOutsideApp) +3385695
   System.Web.Configuration.RuntimeConfig.GetLKGRuntimeConfig(VirtualPath path) +189

 

 

Wallpaper,Pic,Photo以及别的图片事

http://interfacelift.com   一个很全面的站点,墙纸,图标,主题(Mac OS X )等栏目,图标有两个付费类的介绍。墙纸质量很高,尺寸很全面,最高达到2560X1600,HDTV的居然也有,而且很Popular的是,直接提供Iphone专用尺寸,对于广大疯客很是贴心。
 
http://www.skins.be/     一个很“漂亮”的站点,因为基本都是美女照片,1024x768,一直到1920x1200,需要美女素材的,可以流口水了。
 
http://www.bikewalls.com/  从名字看就知道,机车站点,1024x768,一直到1920x1200,全尺寸提供
 
http://www.allmoviewalls.com  海报站点,支持影片首字母搜索。不是很全面,作为备用站点很是很不错。图片质量一般。
 
http://www.pixelgirlpresents.com  像素图片,这个站点是一个设计类站点的子站,收集了不少相当不错的壁纸。其中值得一提的是有不少手机壁纸。
 
 
02 abril

企业网站常用中英文对照表

网站导航 site map
公司简介 PROFILE or COMPANY Profile or Company
公司设备 EQUIPMENT Equipment
公司荣誉 GLORIES Glories
企业文化 CULTURE Culture
产品展示 PRODUCT Product
资质认证 quality certification
企业规模 SCALE Scale
营销网络 Sales Network
组织机构 orGANIZATION organization
合作加盟 Join in Cooperation
技术力量 TECHNOLOGY Technology
经理致辞 Manager`s oration
发展历程 Development history
工程案例 Engineering Projects
业务范围 Business Scope
分支机构 Branches
供求信息 Supply & Demand
经营理念 Operation Principle
产品销售 SALES Sales
联系我们 CONTACT US Contact Us
信息发布 INFORMATION Information
返回首页 HOMEPAGE Homepage
产品定购 orDER order
分类浏览 Browse by category
电子商务 E-Business
公司实力 STRENGTH Strength
版权所有 Copy right
友情连结 Hot link
应用领域 Application Fields
人力资源 Human Resource HR
领导致辞 Leader`s oration
企业资质 Enterprise qualification
行业新闻 Trade news
行业动态 Trends
客户留言 Customer Message
客户服务 Customer Service
新闻动态 News & Trends
公司名称 Company Name
销售热线 Sales Hot-line
联系人 Contact Person
您的要求 Your requirements
建设中 In construction
证书 CERTIFICATE Certificate
地址 ADD Add
邮编 POSTAL CODE Zipcode
电话 TEL Tel
传真 FAX Fax
产品名称 Product Name
产品说明 DESCRIPTION Description
价格 Price
品牌 Brand
规格 Specification
尺寸 Size
生产厂家 MANUFACUTURER Manufacturer
型号 Model
产品标号 Item No.
技术指标 Technique Data
产品描述 Description
产地 Production Place
销售信息 Sales Information
用途 Application
论坛 Forum
在线订购 On-line order
招商 Enterprise-establishing
招标 Bid inviting
综述 General
业绩 Achievements
招聘 Join Us
求贤纳士 Join Us
大事 Great Event
动态 Trends
服务 Service
投资 Investment
行业 Industry
规划 Programming
环境 Environment
发送 Delivery
提交 Submit
重写 Reset
登录 Enter
注册 Login
中国企业网技术支持 Powered by ce.net.cn
社区 Community
业务介绍 Business introduction
在线调查 Online inquiry Inquiry
下载中心 Download
会员登陆 Member Entrance
意见反馈 Feedback
常见问题 FAQ
中心概况 General Profile
教育培训 Education & Training
游乐园 amusement park
在线交流 Online communication
专题报道 Special report
19 marzo

Utf-8 Bom导致CSS不能正常显示之处理

          有个站点说页面怎么都不对,但我这里ie7,ie8,Opera,FF都看了,没有问题,VM里面ie6也看了,也没有问题,但突然就有问题了。页面的CSS没有加载,很奇怪。
 
          google一下,找到了解决办法,原因真是让人FT,原文在此
 
          原因说穿了很是简单:
              全部采用utf8编码,包含文件的时候,最后的二进制流中包含了多次UTF8 BOM标记,IE不能正常解析包含多个UTF8 BOM 标记的页面,直接替换成实际显示的回车,这样导致一个空行,而firefox却没有这个问题。
 
         估计IE7,8都解决了这个问题,6却没有。我FT,狂FT。含泪改了下,搞定。可惜不能FTP,只有等晚上回家了,哎。
 
         另,Div的排版真的是很。。。。。。,没话说了。Over。
04 enero

2006网络总结

     2006年,和网络的关系其实不大了,只是作为一个信息接受者,在旁观着。
 
     看的站点越来越单调,越来越少,关心的东西越来越少了,就是那么几条,房产,汇率,笔电价格。。。
 
     别的地方看见评选2006的web 2。0的站点,觉得还不错,不过除了排第1,2位的站点以外都不知道,真是落伍啊,偶不是一个网络人了。
 
    排名就是按先后。
  
    视频共享类:YouTubeMeta CafeVimeoDaily MotionImeem
    音乐共享类:last.fmMusicoveryread.ioMusicStrandsPODZINGER
    IM聊天类:MeeboJoopzcampfireGoowyGizmo
    图片共享类:FlickrZooomrSlidezoto23HQ
    Blog类:BloggerWeblogs, IncBlogCodeblo.gsBlogLines
    Tag标签类:Diggdel.icio.usRedditStumbleUponBlinklist
27 abril

选择Ajax FreamWork的最基本标准

一、验证类
1、数字验证内
  1.1 整数
  1.2 大于0的整数 (用于传来的ID的验证)
  1.3 负整数的验证
  1.4 整数不能大于iMax
  1.5 整数不能小于iMin
2、时间类
  2.1 短时间,形如 (13:04:06)
  2.2 短日期,形如 (2003-12-05)
  2.3 长时间,形如 (2003-12-05 13:04:06)
  2.4 只有年和月。形如(2003-05,或者2003-5)
  2.5 只有小时和分钟,形如(12:03)
3、表单类
  3.1 所有的表单的值都不能为空
  3.2 多行文本框的值不能为空。
  3.3 多行文本框的值不能超过sMaxStrleng
  3.4 多行文本框的值不能少于sMixStrleng
  3.5 判断单选框是否选择。
  3.6 判断复选框是否选择.
  3.7 复选框的全选,多选,全不选,反选
  3.8 文件上传过程中判断文件类型
4、字符类
  4.1 判断字符全部由a-Z或者是A-Z的字字母组成
  4.2 判断字符由字母和数字组成。
  4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母
  4.4 字符串替换函数.Replace();
5、浏览器类
  5.1 判断浏览器的类型
  5.2 判断ie的版本
  5.3 判断客户端的分辨率
 
6、结合类
  6.1 email的判断。
  6.2 手机号码的验证
  6.3 身份证的验证
 

二、功能类

1、时间与相关控件类
  1.1 日历
  1.2 时间控件
  1.3 万年历
  1.4 显示动态显示时钟效果(文本,如OA中时间)
  1.5 显示动态显示时钟效果 (图像,像手表)
2、表单类
  2.1 自动生成表单
  2.2 动态添加,修改,删除下拉框中的元素
  2.3 可以输入内容的下拉框
  2.4 多行文本框中只能输入iMax文字。如果多输入了,自动减少到iMax个文字(多用于短信发送)
 
3、打印类
  3.1 打印控件
4、事件类
  4.1 屏蔽右键
  4.2 屏蔽所有功能键
  4.3 --> 和<-- F5 F11,F9,F1
  4.4 屏蔽组合键ctrl+N
5、网页设计类
  5.1 连续滚动的文字,图片(注意是连续的,两段文字和图片中没有空白出现)
  5.2 html编辑控件类
  5.3 颜色选取框控件
  5.4 下拉菜单
  5.5 两层或多层次的下拉菜单
  5.6 仿IE菜单的按钮。(效果如rongshuxa.com的导航栏目)
  5.7 状态栏,title栏的动态效果(例子很多,可以研究一下)
  5.8 双击后,网页自动滚屏
6、树型结构。
  6.1 asp+SQL版
  6.2 asp+xml+sql版
  6.3 java+sql或者java+sql+xml
7、无边框效果的制作
8、连动下拉框技术
9、文本排序


一、验证类
1、数字验证内
  1.1 整数
      /^(-|+)?d+$/.test(str)
  1.2 大于0的整数 (用于传来的ID的验证)
      /^d+$/.test(str)
  1.3 负整数的验证
      /^-d+$/.test(str)
2、时间类
  2.1 短时间,形如 (13:04:06)
      function isTime(str)
      {
        var a = str.match(/^(d{1,2})(:)?(d{1,2})2(d{1,2})$/);
        if (a == null) {alert('输入的参数不是时间格式'); return false;}
        if (a[1]>24 || a[3]>60 || a[4]>60)
        {
          alert("时间格式不对");
          return false
        }
        return true;
      }
  2.2 短日期,形如 (2003-12-05)
      function strDateTime(str)
      {
         var r = str.match(/^(d{1,4})(-|/)(d{1,2})2(d{1,2})$/);
         if(r==null)return false;
         var d= new Date(r[1], r[3]-1, r[4]);
         return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]);
      }
  2.3 长时间,形如 (2003-12-05 13:04:06)
      function strDateTime(str)
      {
        var reg = /^(d{1,4})(-|/)(d{1,2})2(d{1,2}) (d{1,2}):(d{1,2}):(d{1,2})$/;
        var r = str.match(reg);
        if(r==null)return false;
        var d= new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]);
        return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==r[7]);
      }
  2.4 只有年和月。形如(2003-05,或者2003-5)
  2.5 只有小时和分钟,形如(12:03)
3、表单类
  3.1 所有的表单的值都不能为空
      <input onblur="if(this.value.replace(/^s+|s+$/g,'')=='')alert('不能为空!')">
  3.2 多行文本框的值不能为空。
  3.3 多行文本框的值不能超过sMaxStrleng
  3.4 多行文本框的值不能少于sMixStrleng
  3.5 判断单选框是否选择。
  3.6 判断复选框是否选择.
  3.7 复选框的全选,多选,全不选,反选
  3.8 文件上传过程中判断文件类型
4、字符类
  4.1 判断字符全部由a-Z或者是A-Z的字字母组成
      <input onblur="if(/[^a-zA-Z]/g.test(this.value))alert('有错')">
  4.2 判断字符由字母和数字组成。
      <input onblur="if(/[^0-9a-zA-Z]/g.test(this.value))alert('有错')">
  4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母
      /^([a-zA-z_]{1})([w]*)$/g.test(str)
  4.4 字符串替换函数.Replace();
5、浏览器类
  5.1 判断浏览器的类型
      window.navigator.appName
  5.2 判断ie的版本
      window.navigator.appVersion
  5.3 判断客户端的分辨率
      window.screen.height;  window.screen.width;
 
6、结合类
  6.1 email的判断。
      function ismail(mail)
      {
        return(new RegExp(/^w+((-w+)|(.w+))*@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$/).test(mail));
      }
  6.2 手机号码的验证
  6.3 身份证的验证
      function isIdCardNo(num)
      {
        if (isNaN(num)) {alert("输入的不是数字!"); return false;}
        var len = num.length, re;
        if (len == 15)
          re = new RegExp(/^(d{6})()?(d{2})(d{2})(d{2})(d{3})$/);
        else if (len == 18)
          re = new RegExp(/^(d{6})()?(d{4})(d{2})(d{2})(d{3})(d)$/);
        else {alert("输入的数字位数不对!"); return false;}
        var a = num.match(re);
        if (a != null)
        {
          if (len==15)
          {
            var D = new Date("19"+a[3]+"/"+a[4]+"/"+a[5]);
            var B = D.getYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5];
          }
          else
          {
            var D = new Date(a[3]+"/"+a[4]+"/"+a[5]);
            var B = D.getFullYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5];
          }
          if (!B) {alert("输入的身份证号 "+ a[0] +" 里出生日期不对!"); return false;}
        }
        return true;
      }

3.7 复选框的全选,多选,全不选,反选
<form name=hrong>
<input type=checkbox name=All onclick="checkAll('mm')">全选<br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/><br/>


<input type=checkbox name=All2 onclick="checkAll('mm2')">全选<br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>

</form>

<SCRIPT LANGUAGE="JavaScript">
function checkAll(str)
{
  var a = document.getElementsByName(str);
  var n = a.length;
  for (var i=0; i<n; i++)
  a[i].checked = window.event.srcElement.checked;
}
function checkItem(str)
{
  var e = window.event.srcElement;
  var all = eval("document.hrong."+ str);
  if (e.checked)
  {
    var a = document.getElementsByName(e.name);
    all.checked = true;
    for (var i=0; i<a.length; i++)
    {
      if (!a[i].checked){ all.checked = false; break;}
    }
  }
  else all.checked = false;
}
</SCRIPT>

3.8 文件上传过程中判断文件类型
<input type=file onchange="alert(this.value.match(/^(.*)(.)(.{1,8})$/)[3])">

画图:
<OBJECT
id=S
style="LEFT: 0px; WIDTH: 392px; TOP: 0px; HEIGHT: 240px"
height=240
width=392
classid="clsid:369303C2-D7AC-11D0-89D5-00A0C90833E6">
</OBJECT>
<SCRIPT>
S.DrawingSurface.ArcDegrees(0,0,0,30,50,60);
S.DrawingSurface.ArcRadians(30,0,0,30,50,60);
S.DrawingSurface.Line(10,10,100,100);
</SCRIPT>

写注册表:
<SCRIPT>
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.RegWrite ("HKCUSoftwareACMEFortuneTeller", 1, "REG_BINARY");
WshShell.RegWrite ("HKCUSoftwareACMEFortuneTellerMindReader", "Goocher!", "REG_SZ");
var bKey =    WshShell.RegRead ("HKCUSoftwareACMEFortuneTeller");
WScript.Echo (WshShell.RegRead ("HKCUSoftwareACMEFortuneTellerMindReader"));
WshShell.RegDelete ("HKCUSoftwareACMEFortuneTellerMindReader");
WshShell.RegDelete ("HKCUSoftwareACMEFortuneTeller");
WshShell.RegDelete ("HKCUSoftwareACME");
</SCRIPT>

TABLAE相关(客户端动态增加行列)
<HTML>
<SCRIPT LANGUAGE="JScript">
function numberCells() {
    var count=0;
    for (i=0; i < document.all.mytable.rows.length; i++) {
        for (j=0; j < document.all.mytable.rows(i).cells.length; j++) {
            document.all.mytable.rows(i).cells(j).innerText = count;
            count++;
        }
    }
}
</SCRIPT>
<BODY onload="numberCells()">
<TABLE id=mytable border=1>
<TR><TH> </TH><TH> </TH><TH> </TH><TH> </TH></TR>
<TR><TD> </TD><TD> </TD><TD> </TD><TD> </TD></TR>
<TR><TD> </TD><TD> </TD><TD> </TD><TD> </TD></TR>
</TABLE>
</BODY>
</HTML>

1.身份证严格验证:

<script>
var aCity={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:" 黑龙江",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42: "湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54: "西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91: "国外"}
 
function cidInfo(sId){
 var iSum=0
 var info=""
 if(!/^d{17}(d|x)$/i.test(sId))return false;
 sId=sId.replace(/x$/i,"a");
 if(aCity[parseInt(sId.substr(0,2))]==null)return "Error:非法地区";
 sBirthday=sId.substr(6,4)+"-"+Number(sId.substr(10,2))+"-"+Number(sId.substr(12,2));
 var d=new Date(sBirthday.replace(/-/g,"/"))
 if(sBirthday!=(d.getFullYear()+"-"+ (d.getMonth()+1) + "-" + d.getDate()))return "Error:非法生日";
 for(var i = 17;i>=0;i --) iSum += (Math.pow(2,i) % 11) * parseInt(sId.charAt(17 - i),11)
 if(iSum%11!=1)return "Error:非法证号";
 return aCity[parseInt(sId.substr(0,2))]+","+sBirthday+","+(sId.substr(16,1)%2?"男":"女")
}

document.write(cidInfo("380524198002300016"),"<br/>");
document.write(cidInfo("340524198002300019"),"<br/>")
document.write(cidInfo("340524197711111111"),"<br/>")
document.write(cidInfo("34052419800101001x"),"<br/>");
</script>

2.验证IP地址
<SCRIPT LANGUAGE="JavaScript">
function isip(s){
 var check=function(v){try{return (v<=255 && v>=0)}catch(x){return false}};
 var re=s.split(".")
 return (re.length==4)?(check(re[0]) && check(re[1]) && check(re[2]) && check(re[3])):false
}

var s="202.197.78.129";
alert(isip(s))
</SCRIPT>

 

3.加sp1后还能用的无边框窗口!!
<HTML XMLNS:IE>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<IE:Download ID="include" STYLE="behavior:url(#default#download)" />
<title>Chromeless Window</title>

<SCRIPT LANGUAGE="JScript">
/*--- Special Thanks For andot ---*/

/*
 This following code are designed and writen by Windy_sk <seasonx@163.net>
 You can use it freely, but u must held all the copyright items!
*/

/*--- Thanks For andot Again ---*/

var CW_width = 400;
var CW_height = 300;
var CW_top = 100;
var CW_left = 100;
var CW_url = "/";
var New_CW = window.createPopup();
var CW_Body = New_CW.document.body;
var content = "";
var CSStext = "margin:1px;color:black; border:2px outset;border-style:expression(onmouseout=onmouseup=function(){this.style.borderStyle='outset'}, onmousedown=function(){if(event.button!=2)this.style.borderStyle='inset'});background-color:buttonface;width:16px;height:14px;font-size:12px;line-height:11px;cursor:Default;";

//Build Window
include.startDownload(CW_url, function(source){content=source});

function insert_content(){
 var temp = "";
 CW_Body.style.overflow  = "hidden";
 CW_Body.style.backgroundColor = "white";
 CW_Body.style.border  =  "solid black 1px";
 content = content.replace(/<a ([^>]*)>/g,"<a onclick='parent.open(this.href);return false' $1>");
 temp += "<table width=100% height=100% cellpadding=0 cellspacing=0 border=0>";
 temp += "<tr style=';font-size:12px;background:#0099CC;height:20;cursor:default' ondblclick="Max.innerText=Max.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();" onmouseup='parent.drag_up(event)' onmousemove='parent.drag_move(event)' onmousedown='parent.drag_down(event)' onselectstart='return false' oncontextmenu='return false'>";
 temp += "<td style='color:#ffffff;padding-left:5px'>Chromeless Window For IE6 SP1</td>";
 temp += "<td style='color:#ffffff;padding-right:5px;' align=right>";
 temp += "<span id=Help  onclick="alert('Chromeless Window For IE6 SP1  -  Ver 1.0 Code By Windy_sk Special Thanks For andot')" style=""+CSStext+"font-family:System;padding-right:2px;">?</span>";
 temp += "<span id=Min   onclick='parent.New_CW.hide();parent.blur()' style=""+CSStext+"font-family:Webdings;" title='Minimum'>0</span>";
 temp += "<span id=Max   onclick="this.innerText=this.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();" style=""+CSStext+"font-family:Webdings;" title='Maximum'>1</span>";
 temp += "<span id=Close onclick='parent.opener=null;parent.close()' style=""+CSStext+"font-family:System;padding-right:2px;" title='Close'>x</span>";
 temp += "</td></tr><tr><td colspan=2>";
 temp += "<div id=include style='overflow:scroll;overflow-x:hidden;overflow-y:auto; HEIGHT: 100%; width:"+CW_width+"'>";
 temp += content;
 temp += "</div>";
 temp += "</td></tr></table>";
 CW_Body.innerHTML = temp;
}

setTimeout("insert_content()",1000);

var if_max = true;
function show_CW(){
 window.moveTo(10000, 10000);
 if(if_max){
  New_CW.show(CW_top, CW_left, CW_width, CW_height);
  if(typeof(New_CW.document.all.include)!="undefined"){
   New_CW.document.all.include.style.width = CW_width;
   New_CW.document.all.Max.innerText = "1";
  }
 
 }else{
  New_CW.show(0, 0, screen.width, screen.height);
  New_CW.document.all.include.style.width = screen.width;
 }
}

window.onfocus  = show_CW;
window.onresize = show_CW;

// Move Window
var drag_x,drag_y,draging=false

function drag_move(e){
 if (draging){
  New_CW.show(e.screenX-drag_x, e.screenY-drag_y, CW_width, CW_height);
  return false;
 }
}

function drag_down(e){
 if(e.button==2)return;
 if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height)return;
 drag_x=e.clientX;
 drag_y=e.clientY;
 draging=true;
 e.srcElement.setCapture();
}

function drag_up(e){
 draging=false;
 e.srcElement.releaseCapture();
 if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height) return;
 CW_top  = e.screenX-drag_x;
 CW_left = e.screenY-drag_y;
}

</SCRIPT>
</HTML>

电话号码的验证

要求:
  (1)电话号码由数字、"("、")"和"-"构成
  (2)电话号码为3到8位
  (3)如果电话号码中包含有区号,那么区号为三位或四位
  (4)区号用"("、")"或"-"和其他部分隔开
  (5)移动电话号码为11或12位,如果为12位,那么第一位为0
  (6)11位移动电话号码的第一位和第二位为"13"
  (7)12位移动电话号码的第二位和第三位为"13"
  根据这几条规则,可以与出以下正则表达式:
  (^[0-9]{3,4}-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^([0-9]{3,4})[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)


<script language="javascript">
function PhoneCheck(s) {
var str=s;
var reg=/(^[0-9]{3,4}-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^([0-9]{3,4})[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)/
alert(reg.test(str));
}
</script>
<input type=text name="iphone">
<input type=button onclick="PhoneCheck(document.all.iphone.value)" value="Check">

具有在输入非数字字符不回显的效果,即对非数字字符的输入不作反应。
function numbersonly(field,event){
 var key,keychar;
 if(window.event){
  key = window.event.keyCode;
 }
 else if (event){
  key = event.which;
 }
 else{
  return true
 }
 keychar = String.fromCharCode(key);
 if((key == null)||(key == 0)||(key == 8)||(key == 9)||(key == 13)||(key == 27)){
  return true;
 }
 else if(("0123456789.").indexOf(keychar)>-1){
  window.status = "";
  return true;
 }
 else {
  window.status = "Field excepts numbers only";
  return false;
 }
}

验证ip

str=document.RegExpDemo.txtIP.value;
if(/^(d{1,3}).(d{1,3}).(d{1,3}).(d{1,3})$/.test(str)==false)
{
 window.alert('错误的IP地址格式');
 document.RegExpDemo.txtIP.select();
 document.RegExpDemo.txtIP.focus();
 return;
}
if(RegExp.$1<1 || RegExp.$1>254||RegExp.$2<0||RegExp.$2>254||RegExp.$3<0||RegExp.$3>254||RegExp.$4<1||RegExp.$4>254)
{
 window.alert('错误的IP地址');
 document.RegExpDemo.txtIP.select();
 document.RegExpDemo.txtIP.focus();
 return;
}
//剔除 如  010.020.020.03 前面 的0
var str=str.replace(/0(d)/g,"$1");
str=str.replace(/0(d)/g,"$1");
window.alert(str);
 
 

21 abril

Apache指南: .htaccess文件 够详细

原文链接  为防止原站点非正常死亡,copy如下

--------------------------------------------------------------------------------------------------
.htaccess文件提供了针对目录改变配置的方法。

  * .htaccess文件
  * 工作原理和使用方法
  * 使用.htaccess文件的场合
  * 指令的生效
  * 认证举例
  * 服务器端包含举例
  * CGI举例
  * 疑难解答

top
.htaccess文件
相关模块     相关指令

  * core
  * mod_auth
  * mod_cgi
  * mod_include
  * mod_mime

   

  * AccessFileName
  * AllowOverride
  * Options
  * AddHandler
  * SetHandler
  * AuthType
  * AuthName
  * AuthUserFile
  * AuthGroupFile
  * Require

top
工作原理和使用方法

.htaccess文件(或者"分布式配置文件")提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。

说明:如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。 例如,需要使用.config,则可以在服务器配置文件中按以下方法配置:

AccessFileName .config

允许放在这些文件中的指令取决于AllowOverride指令, 此指令按类别决定了.htaccess文件中哪些指令才是有效的。如果一个指令允许放在.htaccess文件中,则,在本手册的说明中,此指令会有一个覆盖段,其中说明了为使此指令生效而必须在AllowOverride指令中设置的值。

例如,本手册对AddDefaultCharset指令的说明表明了, 此指令可以用于.htaccess文件(见 Context一行),而Override一行是"FileInfo",那么为使.htaccess中的此指令有效,则至少要设置"AllowOverride FileInfo"。
例子:
Context:     server config, virtual host, directory, .htaccess
Override:     FileInfo

如果不能确定一个特定的指令是否允许用于.htaccess文件, 可以查阅手册中对指令的说明,看在Context(“上下文”)行中是否有".htaccess."。
top
使用.htaccess文件的场合

一般情况下,不应该使用.htaccess文件,除非你对主服务器配置文件没有存取权限。 有一种很常见的误解,认为用户认证只能通过.htaccess文件实现,但并不是这样, 把用户认证写在主服务器配置中是完全可行的,而且是一种很好的方法。

在内容提供者需要针对目录改变服务器的配置而对服务器系统没有root权限时,则应该使用.htaccess文件。如果服务器管理员不愿意频繁修改配置,则可以允许用户通过.htaccess文件自己修改配置,尤其是ISP在一个机器上 宿主多个用户站点,而又希望用户可以自己改变配置的情况下。

虽然如此,一般都应该尽可能地避免使用.htaccess文件。 任何希望放在.htaccess文件中的配置,都可以放在主服务器的<Directory>段中,而且更高效。

避免使用.htaccess文件有两个主要原因。

首先是性能。 如果AllowOverride允许使用.htaccess文件,则,Apache需要在每个目录中查找.htaccess文件,因此,无论是否真正用到, 允许使用.htaccess文件都会导致性能的下降。另外,每次请求一个页面时,都需要读取.htaccess文件。

还有,Apache必须在所有更高级的目录中查找.htaccess文件, 使所有有效的指令都起作用(参见how directives are applied.),所以,如果有对/www/htdocs/example中页面的请求,Apache必须查找以下文件:

/.htaccess
/www/.htaccess
/www/htdocs/.htaccess
/www/htdocs/example/.htaccess

而且,对此目录以外的每个文件访问,还有4个附加的文件系统访问,即使这些文件都不存在。 (注意,这可能仅仅发生在 / 允许使用.htaccess文件的情况下,虽然这种情况并不多。)

其次是安全。 如此,会允许用户修改服务器的配置,可能会导致未加限制的修改,请认真考虑是否给予用户这样的特权。但是,如果给予用户较少的特权而不能满足其需要,则会带来额外的技术支持请求,所以,必须明确地告诉用户已经给予他们的权限,说明AllowOverride设置的值, 并引导他们参阅相应的说明,以免日后许多麻烦。

注意,在/www/htdocs/example目录下.htaccess文件中放置指令,与, 在主服务器配置文件中<Directory /www/htdocs/example>段中放置相同指令, 是等效的。:

/www/htdocs/example中的.htaccess:
/www/htdocs/example中.htaccess文件的内容

AddType text/example .exm
httpd.conf文件中的段

<Directory /www/htdocs/example>
AddType text/example .exm
</Directory>

但是,把这个配置放置在服务器配置文件中则更加高效,因为只需要在Apache启动时读取一次, 而不是在有文件请求时每次都读取。

将AllowOverride设置为"none"可以完全禁止使用.htaccess文件。

AllowOverride None
top
指令的生效

.htaccess 文件中的配置指令作用于.htaccess文件所在的目录及其所有子目录,但是,很重要需要记住的是,其更高级的目录也可能会有.htaccess文件, 而指令是按查找顺序依次生效,所以,一个特定目录下的.htaccess文件中的指令可能会覆盖其更高级目录中的 .htaccess文件的指令,即,子目录中的指令会覆盖更高级目录或者主服务器配置文件中的指令。

例如:

目录/www/htdocs/example1中的.htaccess文件有如下内容:

Options +ExecCGI

(注意: 必须设置"AllowOverride Options"以允许在.htaccess文件中使用 "Options"指令。)

在目录/www/htdocs/example1/example2中的.htaccess文件有如下内容:

Options Includes

由于第二个.htaccess文件的存在,/www/htdocs/example1/example2中 的CGI执行是不允许的,而只允许Options Includes,它完全覆盖了之前的设置。
top
认证举例

如果你为了知道如何认证,直接从这里开始看,有很重要的一点需要注意,有一种常见的误解,认为实现密码认证必须要使用.htaccess文件,其实不是这样。把认证指令放在主服务器配置文件的<Directory>段中,是一个更好的方法,而.htaccess文件应该仅仅用于无权访问主服务器配置文件的时候。 参见上述的使用.htaccess文件的场合。

有此声明在先,如果你仍然需要使用.htaccess文件,请看以下说明。

必须设置"AllowOverride AuthConfig"以允许这些指令生效

.htaccess文件的内容:

AuthType Basic
AuthName "Password Required"
AuthUserFile /www/passwords/password.file
AuthGroupFile /www/passwords/group.file
Require Group admins

注意,必须设置AllowOverride AuthConfig以允许这些指令生效

更详细的有关身份识别和认证的说明,请参见authentication tutorial。
top
服务器端包含举例

.htaccess文件的另一个常见用途是允许一个特定目录的服务器端包含(Server Side Includes), 可以在需要的目录中放置.htaccess文件,并如下配置:

Options +Includes
AddType text/html shtml
AddHandler server-parsed shtml

注意,必须同时设置AllowOverride Options和 AllowOverride FileInfo使这些指令生效。

更详细的有关服务器端包含的说明,请参见SSI tutorial。
top
CGI举例

最后,可以通过.htaccess文件允许在特定目录中执行CGI程序,需按如下配置:

Options +ExecCGI
AddHandler cgi-script cgi pl

另外,如下,可以使给定目录下所有文件被视为CGI程序:

Options +ExecCGI
SetHandler cgi-script

注意,必须设置AllowOverride Options使这些指令生效。

更详细的有关CGI编程和配置的说明,请参见CGI tutorial。
top
疑难解答

如果在.htaccess文件中写入了配置指令但不起作用,可能有多种原因。

最常见的原因是,AllowOverride指令没有被正确设置, 必须确保没有对此文件区域设置AllowOverride None。有一个很好的测试方法,即, 在.htaccess文件随便增加点没用的内容,如果服务器没有返回了一个错误消息,那么几乎可以断定设置了AllowOverride None。

在访问文档时,如果收到服务器的出错消息,应该检查Apache的出错日志, 可以知道.htaccess文件中哪些指令是不允许使用的,也可能会发现需要纠正的语法错误。




.htaccess文件使用手册

- .htaccess文件(或者"分布式配置文件"提供了针对目录改变配置的方法,即,在一个特定的文档目录中放置一个包含一个或多个指令的文件,以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过 Apache的AllowOverride指令来设置。

- 子目录中的指令会覆盖更高级目录或者主服务器配置文件中的指令。

- .htaccess必须以ASCII模式上传,最好将其权限设置为644。

错误文档的定位

常用的客户端请求错误返回代码:
401 Authorization Required
403 Forbidden
404 Not Found
405 Method Not Allowed
408 Request Timed Out
411 Content Length Required
412 Precondition Failed
413 Request Entity Too Long
414 Request URI Too Long
415 Unsupported Media Type
常见的服务器错误返回代码:
500 Internal Server Error

用户可以利用.htaccess指定自己事先制作好的错误提醒页面。一般情况下,人们可以专门设立一个目录,例如errors放置这些页面。然后再.htaccess中,加入如下的指令:

ErrorDocument 404 /errors/notfound.html
ErrorDocument 500 /errors/internalerror.html

一条指令一行。上述第一条指令的意思是对于404,也就是没有找到所需要的文档的时候得显示页面为/errors目录下的notfound.html页面。不难看出语法格式为:

ErrorDocument 错误代码 /目录名/文件名.扩展名

如果所需要提示的信息很少的话,不必专门制作页面,直接在指令中使用HTML号了,例如下面这个例子:

ErrorDocument 401 "<body bgcolor=#ffffff><h1>你没有权限访问该页面,请放弃!</h1></body>"

文档访问的密码保护

要利用.htaccess对某个目录下的文档设定访问用户和对应的密码,首先要做的是生成一个.htpasswd的文本文档,例如:

zheng:y4E7Ep8e7EYV

这里密码经过加密,用户可以自己找些工具将密码加密成.htaccess支持的编码。该文档最好不要放在www目录下,建议放在www根目录文档之外,这样更为安全些。

有了授权用户文档,可以在.htaccess中加入如下指令了:

AuthUserFile .htpasswd的服务器目录
AuthGroupFile /dev/null (需要授权访问的目录)
AuthName EnterPassword
AuthType Basic (授权类型)

require user wsabstract (允许访问的用户,如果希望表中所有用户都允许,可以使用 require valid-user)

注,括号部分为学习时候自己添加的注释

拒绝来自某个IP的访问

如果我不想某个政府部门访问到我的站点的内容,那可以通过.htaccess中加入该部门的IP而将它们拒绝在外。

例如:


order allow,deny
deny from 210.10.56.32
deny from 219.5.45.
allow from all

第二行拒绝某个IP,第三行拒绝某个IP段,也就是219.5.45.0~219.2.45.255

想要拒绝所有人?用deny from all好了。不止用IP,也可以用域名来设定。

保护.htaccess文档

在使用.htaccess来设置目录的密码保护时,它包含了密码文件的路径。从安全考虑,有必要把.htaccess也保护起来,不让别人看到其中的内容。虽然可以用其他方式做到这点,比如文档的权限。不过,.htaccess本身也能做到,只需加入如下的指令:

<Files .htaccess>
order allow,deny
deny from all
</Files>

URL转向

我们可能对网站进行重新规划,将文档进行了迁移,或者更改了目录。这时候,来自搜索引擎或者其他网站链接过来的访问就可能出错。这种情况下,可以通过如下指令来完成旧的URL自动转向到新的地址:

Redirect /旧目录/旧文档名 新文档的地址

或者整个目录的转向:

Redirect 旧目录 新目录

改变缺省的首页文件

一般情况下缺省的首页文件名有default、index等。不过,有些时候目录中没有缺省文件,而是某个特定的文件名,比如在pmwiki中是pmwiki.php。这种情况下,要用户记住文件名来访问很麻烦。在.htaccess中可以轻易的设置新的缺省文件名:

DirectoryIndex 新的缺省文件名

也可以列出多个,顺序表明它们之间的优先级别,例如:

DirectoryIndex filename.html index.cgi index.pl default.htm

防止盗链

如果不喜欢别人在他们的网页上连接自己的图片、文档的话,也可以通过htaccess的指令来做到。

所需要的指令如下:

RewriteEngine on
RewriteCond % !^$
RewriteCond % !^http://(www\.)?mydomain.com/.*$ [NC]
RewriteRule \.(gif|jpg)$ - [F]

如果觉得让别人的页面开个天窗不好看,那可以用一张图片来代替:

RewriteEngine on
RewriteCond % !^$
RewriteCond % !^http://(www\.)?mydomain.com/.*$ [NC]
RewriteRule \.(gif|jpg)$ http://www.mydomain.com/替代图片文件名 [R,L]
12 septiembre

用python实现面向对像的ASP程序

--------------------------
这个有点意思,换可以用perl,如果真的要用,服务器要支持地说,ActivePython,ActivePerl,这两个冬冬,是推荐产品。
--------------------------
 
平时我们写ASP时,一般都用vbscript或javascript.
javascript是用function来实现类的,很麻烦,而且效果不爽.  vbscript虽然可以实现类,但是功能上也有很大的局限性.

如果用python来写ASP脚本,就可以实现真的类,成为真正的面向对像.请看下面的例子:
〈%@LANGUAGE="python" CODEPAGE="936"%〉
〈%
import sys
import urllib
class urtt:
         def __init__(self):
                 self.text1='testpython'
         def urt(self):
                 fr=urllib.urlopen('http://www.163.com')
                 for fl in fr.readlines():
                       Response.Write(Server.HTMLEncode(fl))
                 fr.close()
                 Response.Write(self.text1)
class urtta(urtt):
        def __init__(self,url):
                self.strurl=url
               self.text1='textpython'
        def urts(self):
               fr=urllib.urlopen(self.strurl)
               for fl in fr.readlines():
                       Response.Write(Server.HTMLEncode(fl))
               fr.close()
              Response.Write(self.text1)
utta=urtt()
utta.urt()
utt=urtta("http://sohu.com")
utt.urts()
%〉
代码:

/**
 * 定义一个全局对象, 属性 Version 在发布的时候会替换为当前版本号
 */
var Prototype = {
  Version: '@@VERSION@@'
}

/**
 * 创建一种类型,注意其属性 create 是一个方法,返回一个构造函数。
 * 一般使用如下 
 *     var X = Class.create();  返回一个类型,类似于 java 的一个Class实例。
 * 要使用 X 类型,需继续用 new X()来获取一个实例,如同 java 的 Class.newInstance()方法。
 *
 * 返回的构造函数会执行名为 initialize 的方法, initialize 是 Ruby 对象的构造器方法名字。
 * 此时initialize方法还没有定义,其后的代码中创建新类型时会建立相应的同名方法。
 *
 * 如果一定要从java上去理解。你可以理解为用Class.create()创建一个继承java.lang.Class类的类。当然java不允许这样做,因为Class类是final的
 *
 */
var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}

/**
 * 创建一个对象,从变量名来思考,本意也许是定义一个抽象类,以后创建新对象都 extend 它。
 * 但从其后代码的应用来看, Abstract 更多是为了保持命名空间清晰的考虑。
 * 也就是说,我们可以给 Abstract 这个对象实例添加新的对象定义。
 *
 * 从java去理解,就是动态给一个对象创建内部类。
 */
var Abstract = new Object();

/**
 * 获取参数对象的所有属性和方法,有点象多重继承。但是这种继承是动态获得的。
 * 如:
 *     var a = new ObjectA(), b = new ObjectB();
 *     var c = a.extend(b);
 * 此时 c 对象同时拥有 a 和 b 对象的属性和方法。但是与多重继承不同的是,c instanceof ObjectB 将返回false。
 */
Object.prototype.extend = function(object) {
  for (property in object) {
    this[property] = object[property];
  }
  return this;
}

/**
 * 这个方法很有趣,它封装一个javascript函数对象,返回一个新函数对象,新函数对象的主体和原对象相同,但是bind()方法参数将被用作当前对象的对象。
 * 也就是说新函数中的 this 引用被改变为参数提供的对象。
 * 比如:
 *     <input type="text" id="aaa" value="aaa">
 *     <input type="text" id="bbb" value="bbb">
 *     .................
 *     <script>
 *         var aaa = document.getElementById("aaa");
 *         var bbb = document.getElementById("bbb");
 *         aaa.showValue = function() {alert(this.value);}
 *         aaa.showValue2 = aaa.showValue.bind(bbb);
 *     </script>
 *  那么,调用aaa.showValue 将返回"aaa", 但调用aaa.showValue2 将返回"bbb"。
 *
 * apply 是ie5.5后才出现的新方法(Netscape好像很早就支持了)。
 * 该方法更多的资料参考MSDN http://msdn.microsoft.com/library/en-us/script56/html/js56jsmthApply.asp
 * 还有一个 call 方法,应用起来和 apply 类似。可以一起研究下。
 */
Function.prototype.bind = function(object) {
  var method = this;
  return function() {
    method.apply(object, arguments);
  }
}

/**
 * 和bind一样,不过这个方法一般用做html控件对象的事件处理。所以要传递event对象
 * 注意这时候,用到了 Function.call。它与 Function.apply 的不同好像仅仅是对参数形式的定义。
 * 如同 java 两个过载的方法。
 */
Function.prototype.bindAsEventListener = function(object) {
  var method = this;
  return function(event) {
    method.call(object, event || window.event);
  }
}

/**
 * 将整数形式RGB颜色值转换为HEX形式
 */
Number.prototype.toColorPart = function() {
  var digits = this.toString(16);
  if (this < 16) return '0' + digits;
  return digits;
}

/**
 * 典型 Ruby 风格的函数,将参数中的方法逐个调用,返回第一个成功执行的方法的返回值
 */
var Try = {
  these: function() {
    var returnValue;
   
    for (var i = 0; i < arguments.length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }
   
    return returnValue;
  }
}

/*--------------------------------------------------------------------------*/

/**
 * 一个设计精巧的定时执行器
 * 首先由 Class.create() 创建一个 PeriodicalExecuter 类型,
 * 然后用对象直接量的语法形式设置原型。
 *
 * 需要特别说明的是 rgisterCallback 方法,它调用上面定义的函数原型方法bind, 并传递自己为参数。
 * 之所以这样做,是因为 setTimeout 默认总以 window 对象为当前对象,也就是说,如果 registerCallback 方法定义如下的话:
 *     registerCallback: function() {
 *         setTimeout(this.onTimerEvent, this.frequency * 1000);
 *     }
 * 那么,this.onTimeoutEvent 方法执行失败,因为它无法访问 this.currentlyExecuting 属性。
 * 而使用了bind以后,该方法才能正确的找到this,也就是PeriodicalExecuter的当前实例。
 */
var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;
   
    this.registerCallback();
  },
 
  registerCallback: function() {
    setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
  },
 
  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.callback();
      } finally {
        this.currentlyExecuting = false;
      }
    }
   
    this.registerCallback();
  }
}

/*--------------------------------------------------------------------------*/

/**
 * 这个函数就 Ruby 了。我觉得它的作用主要有两个
 * 1.  大概是 document.getElementById(id) 的最简化调用。
 * 比如:$("aaa") 将返回上 aaa 对象
 * 2.  得到对象数组
 * 比如: $("aaa","bbb") 返回一个包括id为"aaa"和"bbb"两个input控件对象的数组。
 */
function $() {
  var elements = new Array();
 
  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);

    if (arguments.length == 1)
      return element;
     
    elements.push(element);
  }
 
  return elements;
}
代码:

/**
 * 定义 Ajax 对象, 静态方法 getTransport 方法返回一个 XMLHttp 对象
 */
var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
      function() {return new XMLHttpRequest()}
    ) || false;
  },
 
  emptyFunction: function() {}
}

/**
 * 我以为此时的Ajax对象起到命名空间的作用。
 * Ajax.Base 声明为一个基础对象类型
 * 注意 Ajax.Base 并没有使用 Class.create() 的方式来创建,我想是因为作者并不希望 Ajax.Base 被库使用者实例化。
 * 作者在其他对象类型的声明中,将会继承于它。
 * 就好像 java 中的私有抽象类
 */
Ajax.Base = function() {};
Ajax.Base.prototype = {
  /**
   * extend (见prototype.js中的定义) 的用法真是让人耳目一新
   * options 首先设置默认属性,然后再 extend 参数对象,那么参数对象中也有同名的属性,那么就覆盖默认属性值。
   * 想想如果我写这样的实现,应该类似如下:
     setOptions: function(options) {
      this.options.methed = options.methed? options.methed : 'post';
      ..........
     }
     我想很多时候,java 限制了 js 的创意。
   */
  setOptions: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      parameters:   ''
    }.extend(options || {});
  }
}


/**
 * Ajax.Request 封装 XmlHttp
 */
Ajax.Request = Class.create();

/**
 * 定义四种事件(状态), 参考http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/readystate_1.asp
 */
Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

/**
 *
 */
Ajax.Request.prototype = (new Ajax.Base()).extend({
  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);
 
    try {
      if (this.options.method == 'get')
        url += '?' + this.options.parameters + '&_=';
   
     /**
      * 此处好像强制使用了异步方式,而不是依照 this.options.asynchronous 的值
      */
      this.transport.open(this.options.method, url, true);
     
     /**
      * 这里提供了 XmlHttp 传输过程中每个步骤的回调函数
      */
      if (this.options.asynchronous) {
        this.transport.onreadystatechange = this.onStateChange.bind(this);
        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
      }
             
      this.transport.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
      this.transport.setRequestHeader('X-Prototype-Version', Prototype.Version);

      if (this.options.method == 'post') {
        this.transport.setRequestHeader('Connection', 'close');
        this.transport.setRequestHeader('Content-type',
          'application/x-www-form-urlencoded');
      }
     
      this.transport.send(this.options.method == 'post' ?
        this.options.parameters + '&_=' : null);
                     
    } catch (e) {
    }   
  },
     
  onStateChange: function() {
    var readyState = this.transport.readyState;
   /**
    * 如果不是 Loading 状态,就调用回调函数
     */
    if (readyState != 1)
      this.respondToReadyState(this.transport.readyState);
  },
 
  /**
   * 回调函数定义在 this.options 属性中,比如:
      var option = {
         onLoaded : function(req) {...};
         ......
      }
      new Ajax.Request(url, option);
   */
  respondToReadyState: function(readyState) {
    var event = Ajax.Request.Events[readyState];
    (this.options['on' + event] || Ajax.emptyFunction)(this.transport);
  }
});

/**
 * Ajax.Updater 用于绑定一个html元素与 XmlHttp调用的返回值。类似与 buffalo 的 bind。
 * 如果 options 中有 insertion(from dom.js) 对象的话, insertion 能提供更多的插入控制。
 */
Ajax.Updater = Class.create();
Ajax.Updater.prototype = (new Ajax.Base()).extend({
  initialize: function(container, url, options) {
    this.container = $(container);
    this.setOptions(options);
 
    if (this.options.asynchronous) {
      this.onComplete = this.options.onComplete;
      this.options.onComplete = this.updateContent.bind(this);
    }
   
    this.request = new Ajax.Request(url, this.options);
   
    if (!this.options.asynchronous)
      this.updateContent();
  },
 
  updateContent: function() {
    if (this.options.insertion) {
      new this.options.insertion(this.container,
        this.request.transport.responseText);
    } else {
      this.container.innerHTML = this.request.transport.responseText;
    }

    if (this.onComplete) {
      setTimeout((function() {this.onComplete(this.request)}).bind(this), 10);
    }
  }
});
代码:

/**
 * 针对 页面元素对象 的工具类,提供一些简单静态方法
 */
var Field = {
  /**
   * 清除参数引用对象的值
   */
  clear: function() {
    for (var i = 0; i < arguments.length; i++)
      $(arguments[i]).value = '';
  },

  /**
   * 使参数引用对象获取焦点
   */
  focus: function(element) {
    $(element).focus();
  },
 
  /**
   * 判断参数引用对象值是否为空,如为空,返回false, 反之true
   */
  present: function() {
    for (var i = 0; i < arguments.length; i++)
      if ($(arguments[i]).value == '') return false;
    return true;
  },
 
  /**
   * 使选中参数引用对象
   */
  select: function(element) {
    $(element).select();
  },

  /**
   * 使参数引用对象处于可编辑状态
   */
  activate: function(element) {
    $(element).focus();
    $(element).select();
  }
}

/*--------------------------------------------------------------------------*/

/**
 * 表单工具类
 */
var Form = {
  /**
   * 将表单元素序列化后的值组合成 QueryString 的形式
   */
  serialize: function(form) {
    var elements = Form.getElements($(form));
    var queryComponents = new Array();
   
    for (var i = 0; i < elements.length; i++) {
      var queryComponent = Form.Element.serialize(elements[i]);
      if (queryComponent)
        queryComponents.push(queryComponent);
    }
   
    return queryComponents.join('&');
  },
 
  /**
   * 得到表单的所有元素对象
   */
  getElements: function(form) {
    form = $(form);
    var elements = new Array();

    for (tagName in Form.Element.Serializers) {
      var tagElements = form.getElementsByTagName(tagName);
      for (var j = 0; j < tagElements.length; j++)
        elements.push(tagElements[j]);
    }
    return elements;
  },
 
  /**
   * 将指定表单的元素置于不可用状态
   */
  disable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.blur();
      element.disable = 'true';
    }
  },

  /**
   * 使表单的第一个非 hidden 类型而且处于可用状态的元素获得焦点
   */
  focusFirstElement: function(form) {
    form = $(form);
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      if (element.type != 'hidden' && !element.disabled) {
        Field.activate(element);
        break;
      }
    }
  },

  /*
   * 重置表单
   */
  reset: function(form) {
    $(form).reset();
  }
}

/**
 * 表单元素工具类
 */
Form.Element = {
  /**
   * 返回表单元素的值先序列化再进行 URL 编码后的值
   */
  serialize: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);
   
    if (parameter)
      return encodeURIComponent(parameter[0]) + '=' +
        encodeURIComponent(parameter[1]);                   
  },
 
  /**
   *  返回表单元素序列化后的值
   */
  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);
   
    if (parameter)
      return parameter[1];
  }
}

/**
 * prototype 的所谓序列化其实就是将表单的名字和值组合成一个数组
 */
Form.Element.Serializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'hidden':
      case 'password':
      case 'text':
        return Form.Element.Serializers.textarea(element);
      case 'checkbox': 
      case 'radio':
        return Form.Element.Serializers.inputSelector(element);
    }
    return false;
  },
 
  inputSelector: function(element) {
    if (element.checked)
      return [element.name, element.value];
  },

  textarea: function(element) {
    return [element.name, element.value];
  },

  /**
   * 看样子,也不支持多选框(select-multiple)
   */
  select: function(element) {
    var index = element.selectedIndex;
    var value = element.options[index].value || element.options[index].text;
    return [element.name, (index >= 0) ? value : ''];
  }
}

/*--------------------------------------------------------------------------*/

/**
 * Form.Element.getValue 也许会经常用到,所以做了一个快捷引用
 */
var $F = Form.Element.getValue;

/*--------------------------------------------------------------------------*/

/**
 * Abstract.TimedObserver 也没有用 Class.create() 来创建,和Ajax.Base 意图应该一样
 * Abstract.TimedObserver 顾名思义,是套用Observer设计模式来跟踪指定表单元素,
 * 当表单元素的值发生变化的时候,就执行回调函数
 *
 * 我想 Observer 与注册onchange事件相似,不同点在于 onchange 事件是在元素失去焦点的时候才激发。
 * 同样的与 onpropertychange 事件也相似,不过它只关注表单元素的值的变化,而且提供timeout的控制。
 *
 * 除此之外,Observer 的好处大概就在与更面向对象,另外可以动态的更换回调函数,这就比注册事件要灵活一些。
 * Observer 应该可以胜任动态数据校验,或者多个关联下拉选项列表的连动等等
 *
 */
Abstract.TimedObserver = function() {}

/**
 * 这个设计和 PeriodicalExecuter 一样,bind 方法是实现的核心
 */
Abstract.TimedObserver.prototype = {
  initialize: function(element, frequency, callback) {
    this.frequency = frequency;
    this.element   = $(element);
    this.callback  = callback;
   
    this.lastValue = this.getValue();
    this.registerCallback();
  },
 
  registerCallback: function() {
    setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
  },
 
  onTimerEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
   
    this.registerCallback();
  }
}

/**
 * Form.Element.Observer 和 Form.Observer 其实是一样的
 * 注意 Form.Observer 并不是用来跟踪整个表单的,我想大概只是为了减少书写(这是Ruby的一个设计原则)
 */
Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create();
Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
  getValue: function() {
    return Form.serialize(this.element);
  }
});
代码:

/**
 * 针对 页面元素对象 的工具类,提供一些简单静态方法
 */
var Field = {
  /**
   * 清除参数引用对象的值
   */
  clear: function() {
    for (var i = 0; i < arguments.length; i++)
      $(arguments[i]).value = '';
  },

  /**
   * 使参数引用对象获取焦点
   */
  focus: function(element) {
    $(element).focus();
  },
 
  /**
   * 判断参数引用对象值是否为空,如为空,返回false, 反之true
   */
  present: function() {
    for (var i = 0; i < arguments.length; i++)
      if ($(arguments[i]).value == '') return false;
    return true;
  },
 
  /**
   * 使选中参数引用对象
   */
  select: function(element) {
    $(element).select();
  },

  /**
   * 使参数引用对象处于可编辑状态
   */
  activate: function(element) {
    $(element).focus();
    $(element).select();
  }
}

/*--------------------------------------------------------------------------*/

/**
 * 表单工具类
 */
var Form = {
  /**
   * 将表单元素序列化后的值组合成 QueryString 的形式
   */
  serialize: function(form) {
    var elements = Form.getElements($(form));
    var queryComponents = new Array();
   
    for (var i = 0; i < elements.length; i++) {
      var queryComponent = Form.Element.serialize(elements[i]);
      if (queryComponent)
        queryComponents.push(queryComponent);
    }
   
    return queryComponents.join('&');
  },
 
  /**
   * 得到表单的所有元素对象
   */
  getElements: function(form) {
    form = $(form);
    var elements = new Array();

    for (tagName in Form.Element.Serializers) {
      var tagElements = form.getElementsByTagName(tagName);
      for (var j = 0; j < tagElements.length; j++)
        elements.push(tagElements[j]);
    }
    return elements;
  },
 
  /**
   * 将指定表单的元素置于不可用状态
   */
  disable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.blur();
      element.disable = 'true';
    }
  },

  /**
   * 使表单的第一个非 hidden 类型而且处于可用状态的元素获得焦点
   */
  focusFirstElement: function(form) {
    form = $(form);
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      if (element.type != 'hidden' && !element.disabled) {
        Field.activate(element);
        break;
      }
    }
  },

  /*
   * 重置表单
   */
  reset: function(form) {
    $(form).reset();
  }
}

/**
 * 表单元素工具类
 */
Form.Element = {
  /**
   * 返回表单元素的值先序列化再进行 URL 编码后的值
   */
  serialize: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);
   
    if (parameter)
      return encodeURIComponent(parameter[0]) + '=' +
        encodeURIComponent(parameter[1]);                   
  },
 
  /**
   *  返回表单元素序列化后的值
   */
  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);
   
    if (parameter)
      return parameter[1];
  }
}

/**
 * prototype 的所谓序列化其实就是将表单的名字和值组合成一个数组
 */
Form.Element.Serializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'hidden':
      case 'password':
      case 'text':
        return Form.Element.Serializers.textarea(element);
      case 'checkbox': 
      case 'radio':
        return Form.Element.Serializers.inputSelector(element);
    }
    return false;
  },
 
  inputSelector: function(element) {
    if (element.checked)
      return [element.name, element.value];
  },

  textarea: function(element) {
    return [element.name, element.value];
  },

  /**
   * 看样子,也不支持多选框(select-multiple)
   */
  select: function(element) {
    var index = element.selectedIndex;
    var value = element.options[index].value || element.options[index].text;
    return [element.name, (index >= 0) ? value : ''];
  }
}

/*--------------------------------------------------------------------------*/

/**
 * Form.Element.getValue 也许会经常用到,所以做了一个快捷引用
 */
var $F = Form.Element.getValue;

/*--------------------------------------------------------------------------*/

/**
 * Abstract.TimedObserver 也没有用 Class.create() 来创建,和Ajax.Base 意图应该一样
 * Abstract.TimedObserver 顾名思义,是套用Observer设计模式来跟踪指定表单元素,
 * 当表单元素的值发生变化的时候,就执行回调函数
 *
 * 我想 Observer 与注册onchange事件相似,不同点在于 onchange 事件是在元素失去焦点的时候才激发。
 * 同样的与 onpropertychange 事件也相似,不过它只关注表单元素的值的变化,而且提供timeout的控制。
 *
 * 除此之外,Observer 的好处大概就在与更面向对象,另外可以动态的更换回调函数,这就比注册事件要灵活一些。
 * Observer 应该可以胜任动态数据校验,或者多个关联下拉选项列表的连动等等
 *
 */
Abstract.TimedObserver = function() {}

/**
 * 这个设计和 PeriodicalExecuter 一样,bind 方法是实现的核心
 */
Abstract.TimedObserver.prototype = {
  initialize: function(element, frequency, callback) {
    this.frequency = frequency;
    this.element   = $(element);
    this.callback  = callback;
   
    this.lastValue = this.getValue();
    this.registerCallback();
  },
 
  registerCallback: function() {
    setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
  },
 
  onTimerEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
   
    this.registerCallback();
  }
}

/**
 * Form.Element.Observer 和 Form.Observer 其实是一样的
 * 注意 Form.Observer 并不是用来跟踪整个表单的,我想大概只是为了减少书写(这是Ruby的一个设计原则)
 */
Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create();
Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
  getValue: function() {
    return Form.serialize(this.element);
  }
});
代码:

/**
 * 根据 class attribute 的名字得到对象数组,支持 multiple class
 *
 */
document.getElementsByClassName = function(className) {
  var children = document.getElementsByTagName('*') || document.all;
  var elements = new Array();
 
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    var classNames = child.className.split(' ');
    for (var j = 0; j < classNames.length; j++) {
      if (classNames[j] == className) {
        elements.push(child);
        break;
      }
    }
  }
 
  return elements;
}

/*--------------------------------------------------------------------------*/

/**
 * Element 就象一个 java 的工具类,主要用来 隐藏/显示/销除 对象,以及获取对象的简单属性。
 *
 */
var Element = {
  toggle: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display =
        (element.style.display == 'none' ? '' : 'none');
    }
  },

  hide: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = 'none';
    }
  },

  show: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = '';
    }
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
  },
   
  getHeight: function(element) {
    element = $(element);
    return element.offsetHeight;
  }
}

/**
 * 为 Element.toggle 做了一个符号连接,大概是兼容性的考虑
 */
var Toggle = new Object();
Toggle.display = Element.toggle;

/*--------------------------------------------------------------------------*/

/**
 * 动态插入内容的实现,MS的Jscript实现中对象有一个 insertAdjacentHTML 方法(http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/insertadjacenthtml.asp)
 * 这里算是一个对象形式的封装。
 */
Abstract.Insertion = function(adjacency) {
  this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
  initialize: function(element, content) {
    this.element = $(element);
    this.content = content;
   
    if (this.adjacency && this.element.insertAdjacentHTML) {
      this.element.insertAdjacentHTML(this.adjacency, this.content);
    } else {
     /**
      * gecko 不支持 insertAdjacentHTML 方法,但可以用如下代码代替
      */
      this.range = this.element.ownerDocument.createRange();
     /**
      * 如果定义了 initializeRange 方法,则实行,这里相当与定义了一个抽象的 initializeRange 方法
      */
      if (this.initializeRange) this.initializeRange();
      this.fragment = this.range.createContextualFragment(this.content);

     /**
      * insertContent 也是一个抽象方法,子类必须实现
      */
      this.insertContent();
    }
  }
}

/**
 * prototype 加深了我的体会,就是写js 如何去遵循 Don’t Repeat Yourself (DRY) 原则
 * 上文中 Abstract.Insertion 算是一个抽象类,定义了名为 initializeRange 的一个抽象方法
 * var Insertion = new Object() 建立一个命名空间
 * Insertion.Before|Top|Bottom|After 就象是四个java中的四个静态内部类,而它们分别继承于Abstract.Insertion,并实现了initializeRange方法。
 */
var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
  initializeRange: function() {
    this.range.setStartBefore(this.element);
  },
 
  /**
   * 将内容插入到指定节点的前面, 与指定节点同级
   */
  insertContent: function() {
    this.element.parentNode.insertBefore(this.fragment, this.element);
  }
});

Insertion.Top = Class.create();
Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(true);
  },
 
  /**
   * 将内容插入到指定节点的第一个子节点前,于是内容变为该节点的第一个子节点
   */
  insertContent: function() { 
    this.element.insertBefore(this.fragment, this.element.firstChild);
  }
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(this.element);
  },
 
  /**
   * 将内容插入到指定节点的最后,于是内容变为该节点的最后一个子节点
   */
  insertContent: function() {
    this.element.appendChild(this.fragment);
  }
});


Insertion.After = Class.create();
Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
  initializeRange: function() {
    this.range.setStartAfter(this.element);
  },

  /**
   * 将内容插入到指定节点的后面, 与指定节点同级
   */
  insertContent: function() {
    this.element.parentNode.insertBefore(this.fragment,
      this.element.nextSibling);
  }
});
代码:

/**
 * 根据 class attribute 的名字得到对象数组,支持 multiple class
 *
 */
document.getElementsByClassName = function(className) {
  var children = document.getElementsByTagName('*') || document.all;
  var elements = new Array();
 
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    var classNames = child.className.split(' ');
    for (var j = 0; j < classNames.length; j++) {
      if (classNames[j] == className) {
        elements.push(child);
        break;
      }
    }
  }
 
  return elements;
}

/*--------------------------------------------------------------------------*/

/**
 * Element 就象一个 java 的工具类,主要用来 隐藏/显示/销除 对象,以及获取对象的简单属性。
 *
 */
var Element = {
  toggle: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display =
        (element.style.display == 'none' ? '' : 'none');
    }
  },

  hide: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = 'none';
    }
  },

  show: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = '';
    }
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
  },
   
  getHeight: function(element) {
    element = $(element);
    return element.offsetHeight;
  }
}

/**
 * 为 Element.toggle 做了一个符号连接,大概是兼容性的考虑
 */
var Toggle = new Object();
Toggle.display = Element.toggle;

/*--------------------------------------------------------------------------*/

/**
 * 动态插入内容的实现,MS的Jscript实现中对象有一个 insertAdjacentHTML 方法(http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/insertadjacenthtml.asp)
 * 这里算是一个对象形式的封装。
 */
Abstract.Insertion = function(adjacency) {
  this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
  initialize: function(element, content) {
    this.element = $(element);
    this.content = content;
   
    if (this.adjacency && this.element.insertAdjacentHTML) {
      this.element.insertAdjacentHTML(this.adjacency, this.content);
    } else {
     /**
      * gecko 不支持 insertAdjacentHTML 方法,但可以用如下代码代替
      */
      this.range = this.element.ownerDocument.createRange();
     /**
      * 如果定义了 initializeRange 方法,则实行,这里相当与定义了一个抽象的 initializeRange 方法
      */
      if (this.initializeRange) this.initializeRange();
      this.fragment = this.range.createContextualFragment(this.content);

     /**
      * insertContent 也是一个抽象方法,子类必须实现
      */
      this.insertContent();
    }
  }
}

/**
 * prototype 加深了我的体会,就是写js 如何去遵循 Don’t Repeat Yourself (DRY) 原则
 * 上文中 Abstract.Insertion 算是一个抽象类,定义了名为 initializeRange 的一个抽象方法
 * var Insertion = new Object() 建立一个命名空间
 * Insertion.Before|Top|Bottom|After 就象是四个java中的四个静态内部类,而它们分别继承于Abstract.Insertion,并实现了initializeRange方法。
 */
var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
  initializeRange: function() {
    this.range.setStartBefore(this.element);
  },
 
  /**
   * 将内容插入到指定节点的前面, 与指定节点同级
   */
  insertContent: function() {
    this.element.parentNode.insertBefore(this.fragment, this.element);
  }
});

Insertion.Top = Class.create();
Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(true);
  },
 
  /**
   * 将内容插入到指定节点的第一个子节点前,于是内容变为该节点的第一个子节点
   */
  insertContent: function() { 
    this.element.insertBefore(this.fragment, this.element.firstChild);
  }
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(this.element);
  },
 
  /**
   * 将内容插入到指定节点的最后,于是内容变为该节点的最后一个子节点
   */
  insertContent: function() {
    this.element.appendChild(this.fragment);
  }
});


Insertion.After = Class.create();
Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
  initializeRange: function() {
    this.range.setStartAfter(this.element);
  },

  /**
   * 将内容插入到指定节点的后面, 与指定节点同级
   */
  insertContent: function() {
    this.element.parentNode.insertBefore(this.fragment,
      this.element.nextSibling);
  }
});