posted @ 2006-09-19 17:04 wander 阅读(10730) 评论(17) 编辑
目 录
1 目的
2 范围
3 注释规范
3.1 概述
3.2 自建代码文件注释
3.3 模块(类)注释
3.4 类属性注释
3.5 方法注释
3.6 代码间注释
4 命名总体规则
5 命名规范
5.1 变量(Variable)命名
5.2 常量命名
5.3 类(Class)命名
5.4 接口(Interface)命名
5.5 方法(Method)命名
5.6 名称空间Namespace)命名
6 编码规则
6.1 错误检查规则
6.2 大括号规则
6.3 缩进规则
6.4 小括号规则
6.5 If Then Else规则
6.6 比较规则
6.7 Case规则
6.8 对齐规则
6.9 单语句规则
6.10 单一功能规则
6.11 简单功能规则
6.12 明确条件规则
6.13 选用FALSE规则
6.14 独立赋值规则
6.15 定义常量规则
6.16 模块化规则
6.17 交流规则
7 编程准则
7.1 变量使用
7.2 数据库操作
7.3 对象使用
7.4 模块设计原则
7.5 结构化要求
7.6 函数返回值原则
8 代码包规范
8.1 代码包的版本号
8.2 代码包的标识
9 代码的控制
9.1 代码库/目录的建立
9.2 代码归档
10 输入控制校验规则
10.1 登陆控制
10.2 数据录入控制
附件1:数据类型缩写表
附件2:服务器控件名缩写表
1 目的
一.为了统一公司软件开发设计过程的编程规范
二.使网站开发人员能很方便的理解每个目录,变量,控件,类,方法的意义
三.为了保证编写出的程序都符合相同的规范,保证一致性、统一性而建立的程序编码规范。
四.编码规范和约定必须能明显改善代码可读性,并有助于代码管理、分类范围适用于企业所有基于.NET平台的软件开发工作
2 范围
本规范适用于开发组全体人员,作用于软件项目开发的代码编写阶段和后期维护阶段。
3 注释规范
3.1 概述
a) 注释要求英文及英文的标点符号。
b) 注释中,应标明对象的完整的名称及其用途,但应避免对代码过于详细的描述。
c) 每行注释的最大长度为100个字符。
d) 将注释与注释分隔符用一个空格分开。
e) 不允许给注释加外框。
f) 编码的同时书写注释。
g) 重要变量必须有注释。
h) 变量注释和变量在同一行,所有注释必须对齐,与变量分开至少四个“空格”键。
如:int m_iLevel,m_iCount; // m_iLevel ....tree level
// m_iCount ....count of tree items
string m_strSql; //SQL
i) 典型算法必须有注释。
j) 在循环和逻辑分支地方的上行必须就近书写注释。
k) 程序段或语句的注释在程序段或语句的上一行
l) 在代码交付之前,必须删掉临时的或无关的注释。
m) 为便于阅读代码,每行代码的长度应少于100个字符。
3.2 自建代码文件注释
对于自己创建的代码文件(如函数、脚本),在文件开头,一般编写如下注释:
/******************************************************
FileName:
Copyright (c) 2004-xxxx *********公司技术开发部
Writer:
create Date:
Rewriter:
Rewrite Date:
Impact:
Main Content(Function Name、parameters、returns)
******************************************************/
3.3 模块(类)注释
模块开始必须以以下形式书写模块注释:
///<summary>
///Module ID:<模块编号,可以引用系统设计中的模块编号>
///Depiction:<对此类的描述,可以引用系统设计中的描述>
///Author:作者中文名
///Create Date:<模块创建日期,格式:YYYY-MM-DD>
///</summary>
如果模块只进行部分少量代码的修改时,则每次修改须添加以下注释:
///Rewriter Rewrite Date:<修改日期:格式YYYY-MM-DD> Start1:
/* 原代码内容*/
///End1:
将原代码内容注释掉,然后添加新代码使用以下注释:
///Added by Add date:<添加日期,格式:YYYY-MM-DD> Start2:
///End2:
如果模块输入输出参数或功能结构有较大修改,则每次修改必须添加以下注释:
///<summary>
///Log ID:<Log编号,从1开始一次增加>
///depiction:<对此修改的描述>
///Writer:修改者中文名
///Rewrite Date:<模块修改日期,格式:YYYY-MM-DD>
///</summary>
3.4 类属性注释
在类的属性必须以以下格式编写属性注释:
/// <summary>
/// <Properties depiction>
/// </summary>
3.5 方法注释
在类的方法声明前必须以以下格式编写注释
/// <summary>
/// depiction:<对该方法的说明>
/// </summary>
/// <param name="<参数名称>"><参数说明></param>
/// <returns>
///<对方法返回值的说明,该说明必须明确说明返回的值代表什么含义>
/// </returns>
///Writer:作者中文名
///Create Date:<方法创建日期,格式:YYYY-MM-DD>
3.6 代码间注释
代码间注释分为单行注释和多行注释:
//<单行注释>
/*多行注释1
多行注释2
多行注释3*/
代码中遇到语句块时必须添加注释(if,for,foreach,……),添加的注释必须能够说明此语句块的作用和实现手段(所用算法等等)。
4 命名总体规则
? 名字应该能够标识事物的特性。
? 名字一律使用英文单词,而不能为拼音。
? 名字尽量不使用缩写,除非它是众所周知的。
? 名字可以有两个或三个单词组成,但不应多于三个,控制在3至30个字母以内。
? 在名字中,多个单词用大写第一个字母(其它字母小写)来分隔。例如:IsSuperUser。
? 名字尽量使用前缀而不是后缀。
? 名字中的单词尽量使用名词,如有动词,也尽量放在后面。例如:FunctionUserDelete(而不是FunctionDeleteUser)。
5 命名规范
5.1 变量(Variable)命名
a) 程序文件(*.cs)中的变量命名
程序中变量名称 = 变量的前缀 +代表变量含意的英文单词或单词缩写。
? 类模块级的变量请用“m_” +数据类型缩写作为前缀(其中,m 为“memory”缩写,数据类型缩写见附件中的《数据类型缩写表》)。
public class hello
{
private string m_strName;
private DateTime m_dtDate;
}
? 类的属性所对应的变量,采用属性名前加“m_”+ 类型缩写 前缀的形式
public class hello
{
private string m_strName;
public string Name
{
get
{
return m_strName;
}
}
}
过程级的变量使用类型缩写前缀
public class hello
{
void say()
{
string strSayWord;
}
}
? 过程的参数使用“p_”+ 类型缩写作为前缀(其中,p 为“parameter”缩写)
public class hello
{
void say(string p_strSayWord)
{
}
}
补充说明:
针对异常捕获过程中的Exception变量命名,在没有冲突的情况下,统一命名为exp;
如果有冲突的情况下,可以用“exp”+ 标志名称,如:expSql。
Try
{
//your code
try
{
//code
}
catch(Exception exp)
{
//your code
}
}
catch(Exception expSql)
{
//your code
}
补充:如果捕获异常不需要作任何处理,则不需要定义Exception实例。
例:
try
{
//your code
}
catch( Exception exp)
{
}
? 鉴于大多数名称都是通过连接若干单词构造的,请使用大小写混合的格式以简化它们的阅读。每个单词的第一个字母都是大写.
? 即使对于可能仅出现在几个代码行中的生存期很短的变量,仍然使用有意义的名称。仅对于短循环索引使用单字母变量名,如 i 或 j。
? 在变量名中使用互补对,如 min/max、begin/end 和 open/close。
? 不要使用原义数字或原义字符串,如 For (i = 1;i <= 7;i++)。而是使用命名常数,如 For (i = 1;i <= NUM_DAYS_IN_WEEK;i++) 以便于维护和理解。
b) 控件命名
控件命名 = 控件名称前二到三个字母 + 名称,如Labl控件(labUserName)
5.2 常量命名
常量名也应当有一定的意义,格式为 NOUN 或 NOUN_VERB。常量名均为大写,字之间用下划线分隔。
例:
private const bool WEB_ENABLEPAGECACHE_DEFAULT = true;
private const int WEB_PAGECACHEEXPIRESINSECONDS_DEFAULT = 3600;
private const bool WEB_ENABLESSL_DEFAULT = false;
注:
变量名和常量名最多可以包含 255 个字符,但是,超过 25 到 30 个字符的名称比较笨拙。此外,要想取一个有实际意义的名称,清楚地表达变量或常量的用途,25 或 30 个字符应当足够了。
5.3 类(Class)命名
a) 名字应该能够标识事物的特性。
b) 名字尽量不使用缩写,除非它是众所周知的。
c) 名字可以有两个或三个单词组成,但通常不应多于三个。
d) 在名字中,所有单词第一个字母大写。例如 IsSuperUser,包含ID的,ID全部大写,如CustomerID。
e) 使用名词或名词短语命名类。
f) 少用缩写。
g) 不要使用下划线字符 (_)。
例: public class FileStream
public class Button
public class String
5.4 接口(Interface)命名
和类命名规范相同,唯一区别是 接口在名字前加上“I”前缀
例:
interface IDBCommand;
interface IButton;
5.5 方法(Method)命名
和类命名规范相同。
5.6 命名空间(NameSpace)命名
和类命名规范相同。
错吻星空 2005-11-10 08:22
6 编码规则
6.1 错误检查规则
a) 编程中要考虑函数的各种执行情况,尽可能处理所有流程情况。
b) 检查所有的系统调用的错误信息,除非要忽略错误。
c) 将函数分两类:一类为与屏幕的显示无关, 另一类与屏幕的显示有关。对于与屏幕显示无关的函数,函数通过返回值来报告错误。对于与屏幕显示有关的函数,函数要负责向用户发出警告,并进行错误处理。
d) 错误处理代码一般放在函数末尾。
e) 对于通用的错误处理,可建立通用的错误处理函数,处理常见的通用的错误。
6.2 大括号规则
将大括号放置在关键词下方的同列处,例如:
if ($condition) while ($condition)
{ {
... ...
} }
6.3 缩进规则
使用一个“Tab”为每层次缩进。例如:
function func()
{
if (something bad)
{
if (another thing bad)
{
while (more input)
{
}
}
}
}
6.4 小括号规则
a) 不要把小括号和关键词(if 、while等)紧贴在一起,要用空格隔开它们。
b) 不要把小括号和函数名紧贴在一起。
c) 除非必要,不要在Return返回语句中使用小括号。因为关键字不是函数,如果小括号紧贴着函数名和关键字,二者很容易被看成是一体的。
6.5 If Then Else规则
如果你有用到else if 语句的话,通常最好有一个else块以用于处理未处理到的其他情况。可以的话放一个记录信息注释在else处,即使在else没有任何的动作。其格式为:
if (条件1) // 注释
{
}
else if (条件2) // 注释
{
}
else // 注释
{
}
注:if 和循环的嵌套最多允许4层
6.6 比较规则
总是将恒量放在等号/不等号的左边。一个原因是假如你在等式中漏了一个等号,语法检查器会为你报错。第二个原因是你能立刻找到数值而不是在你的表达式的末端找到它。例如:
if ( 6 == $errorNum ) ...
6.7 Case规则
default case总应该存在,如果不允许到达,则应该保证:若到达了就会触发一个错误。Case的选择条件最好使用int或string类型。
6.8 对齐规则
变量的申明和初始化都应对齐。例如:
int m_iCount;
int i,j;
float m_fIncome,m_fPay;
m_iCount = 0;
i = 1;
m_fIncome = 0.3;
6.9 单语句规则
除非这些语句有很密切的联系,否则每行只写一个语句。
6.10 单一功能规则
原则上,一个程序单元(函数、例程、方法)只完成一项功能。
6.11 简单功能规则
原则上,一个程序单元的代码应该限制在一页内(25~30行)。
6.12 明确条件规则
不要采用缺省值测试非零值。例如:使用“if ( 0 != f( ) )”而不用“if ( f( ) )”。
6.13 选用FALSE规则
大部分函数在错误时返回FALSE、0或NO之类的值,但在正确时返回值就不定了(不能用一个固定的TRUE、1或YES来代表),因此检测一个布尔值时应该用 FALSE、0、NO之类的不等式来代替。例如:使用“if ( FALSE != f( ) )” 而不用“if (TRUE == f( ) )”。
6.14 独立赋值规则
嵌入式赋值不利于理解程序,同时可能回造成意想不到的副作用,应尽量编写独立的赋值语句。例如:使用“a = b + c ; e = a + d;”而不用“e = ( a = b + c ) + d ”。
6.15 定义常量规则
对于代码中引用的常量(尤其是数字),应该define成一个大写的名字,在代码中引用名字而不直接引用值。
6.16 模块化规则
某一功能,如果重复实现一遍以上,即应考虑模块化,将它写成通用函数。并向小组成员发布。同时要尽可能利用其它人的现成模块。
6.17 交流规则
共享别人的工作成果,向别人提供自己的工作成果。
在具体任务开发中,如果有其它的编码规则,则在相应的软件开发计划中予 以明确定义。
7 编程准则
7.1 变量使用
a) 不允许随意定义全局变量。
b) 一个变量只能有一个用途;变量的用途必须和变量的名称保持一致。
c) 所有变量都必须在类和函数最前面定义,并分类排列。
7.2 数据库操作
a) 查找数据库表或视图时,只能取出确实需要的那些字段。
b) 使用无关联子查询,而不要使用关联子查询。
c) 清楚明白地使用列名,而不能使用列的序号。
d) 用事务保证数据的完整性。
7.3 对象使用
a) 尽可能晚地创建对象,并且尽可能早地释放它。
7.4 模块设计原则
a) 不允许随意定义公用的函数和类。
b) 函数功能单一,不允许一个函数实现两个及两个以上的功能。
c) 不能在函数内部使用全局变量,如要使用全局变量,应转化为局部变量。
d) 函数与函数之间只允许存在包含关系,而不允许存在交叉关系。即两者之间只存在单方向的调用与被调用,不存在双向的调用与被调用。
7.5 结构化要求
a) 禁止出现两条等价的支路。
例如:if (a == 2)
else if (a== 3)
//
else if (a == 2)
//
else
//
b) 避免使用GOTO语句
c) 用 IF 语句来强调只执行两组语句中的一组。禁止 ELSE GOTO 和 ELSE RETURN。
d) 用 CASE 实现多路分支
e) 避免从循环引出多个出口。
f) 函数只有一个出口。
g) 不使用条件赋值语句。
h) 避免不必要的分支。
i) 不要轻易用条件分支去替换逻辑表达式
7.6 函数返回值原则
1) 函数返回值
避免使用结构体等复杂类型
使用bool类型:该函数只需要获得成功或者失败的返回信息时候
使用int 类型:错误代码用负数表示,成功返回0
8 代码包规范
本项目中,每个任务在完成一个稳定的版本后,都应打包并且归档。
8.1 代码包的版本号
项目中,代码包的版本号由圆点隔开的两个数字组成,第一个数字表示发行号,第二个数字表示该版的修改号。具体用法如下:
1) 当代码包初版时,版本号为 V1.00;
2) 当代码包被局部修改或bug修正时,发行号不变,修改号第二个数字增1。例如,对初版代码包作了第一次修订,则版本号为 V1.01;
3) 当代码包在原有的基础上增加部分功能,发行号不变,修改号第一个数字增1,例如,对V1.12版的基础上增加部分功能,则新版本号为 V1.20;
4) 当代码包有重要修改或局部修订累积较多导致代码包发生全局变化时,发行号增1。例如,在 V1.15 版的基础上作了一次全面修改,则新版本号为 V2.00。
8.2 代码包的标识
本项目所产生的代码包都有唯一、特定的编码,其构成如下:
S-项目标识-代码包类型-版本号/序号
其中:
1) S:本项目的标识,表明本项目是“XXXX”。
2) 项目标识:简要标识本项目,此标识适用于整个项目的文档。
3) 代码包类型:取自以下表的两位字母编码。
4) 版本号:本代码包的版本号。
5) 序号:四位数字编码,指明该代码包在项目代码库的总序号。
例如:
一个Windows下RAR源码的压缩代码包命名为: S-XXXX-WS-V1.02/0001
项目的代码包分类表
类 型 编 码 注 释
RAR包
(web) 源码文件 WS 源代码文件包
编译文件 WB 编译文件包
安装文件 WI 安装文件包
源码代码 + 安装文件 WA 源代码和安装文件包
项目中所有代码包的标识清单将在《项目开发计划》中予以具体定义。
9 代码的控制
9.1 代码库/目录的建立
项目负责人在VSS中建立项目的文档库目录,即为“Software”目录,以便快速查询。
9.2 代码归档
所有代码在完成一个稳定的版本后,项目负责人都应打包后,存放于VSS中该目的“Software”目录下,并且依据代码包的命名规范为代码包分配一个唯一名称。
10 输入控制校验规则
10.1 登陆控制
用户登陆ID和登陆密码,要限定输入长度范围,必须检查输入合法性。
10.2 数据录入控制
a) TextBox输入
1、 要保持用户输入和数据库接收的长度一致
2、 必须进行输入合法性校验
如:E_mail格式 XXX@XXX.XXX...
电话格式 020-12345678 (020)12345678
邮政编码是六位
b) 除CheckBox、RadioButton外,禁止在DataGrid内嵌入其他编辑控件,用以添加编辑数据
11. 数据库命名规范:
SqlServer命名规范
使用本系统遵循以下命名规范:
1、表命名:用一个或三个以下英文单词组成,单词首字母大写,如:DepartmentUsers;
2、表主键名称为:表名+ID,如Document表的主键名为:DocumentID
3、存储过程命名:表名+方法,如:p_my_NewsAdd,p_my_NewsUpdate;
4、视图命名:View_表名,如:ViewNews;
5、Status为表中状态的列名,默认值为0,在表中删除操作将会改变Status的值而不真实删除该记录;
6、Checkintime为记录添加时间列,默认值为系统时间;
7、表、存储过程、视图等对象的所有都为dbo,不要使用数据库用户名,这样会影响数据库用户的更改。
附件1:数据类型缩写表
数据类型 缩写
string str
int i
char chr
sbyte sb
byte bt
uint ui
long l
ulong ul
float f
double d
bool b
decimal dec
附注:数据库服务器命名规范,控件名缩写+控件作用单词的全称,如:btnNext, txtPassword(密码文本框),txtRPassword(密码确认文本框),单词的第一个字母必须大写如果有多个单词,则为控件缩写+控件作用的第一个单词+第二个单词的全称,每个单词名的第一个字母必须大写
附件2:服务器控件名缩写表
a、web控件
web控件名 缩写
AdRotator art
Button btn
Calendar cd
CheckBox chk
CheckBoxList chkl
CompareValidator cpv
CustomValidator ctv
DataGrid dg
DataList dl
DropDownList ddl
HyperLink hl
Image img
ImageButton Ibtn
Label lab
LinkButton lbtn
ListBox lst
Panel pl
PlaceHolder ph
RadioButton rb
RadioButtonList rbl
RangeValidator rv
RegularExpressionValidator rev
Repeater rp
RequiredFieldValidator rfv
Table tb
TableCell tc
TableRow tr
TextBox txt
ValidationSummary vs
XML XML
b、html控件
html控件名 缩写
HtmlAnchor hah
HtmlButton hbtn
HtmlForm hform
HtmlGenericControl hgc
HtmlImage himg
HtmlInputButton(按钮) htxt
HtmlInputButton(重置) hrbtn
HtmlInputButton(提交) hcbtn
HtmlInputCheckBox hick
HtmlInputFile hifile
HtmlInputHidden hihidden
HtmlInputImage hiimg
HtmlInputRadioButton hirb
HtmlInputText(密码) hpwd
HtmlInputText(文本) hitxt
HtmlSelect hslt
HtmlTable htab
HtmlTableCell htc
HtmlTableRow htr
HtmlTextArea htxta
c.ADO.NET控件命名规范
类型 前缀 示例
Connection con conNorthwind
Command cmd cmdReturnProducts
Parameter parm parmProductID
DataAdapter dad dadProducts
DataReader dtr dtrProducts
DataSet dst dstNorthWind
DataTable dtbl dtblProduct
DataRow drow drowRow98
DataColumn dcol dcolProductID
DataRelation drel drelMasterDetail
DataView dvw dvwFilteredProducts
posted @ 2007-02-04 15:16 wander 阅读(1830) 评论(0) 编辑
正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了
匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行
匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力
匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用
匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用
匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822
匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始
匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字
匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位
匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用
匹配特定数字:
^[1-9]\d*$ //匹配正整数
^-[1-9]\d*$ //匹配负整数
^-?[1-9]\d*$ //匹配整数
^[1-9]\d*|0$ //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$ //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正
匹配特定字符串:
^[A-Za-z]+$ //匹配由26个英文字母组成的字符串
^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串
^[a-z]+$ //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串
^\w+$ //匹配由数字、26个英文字母或者下划线组成的字符串
匹配时间格式:
^(d)(:)?(d)2(d)$ //短时间
^(d)(-│/)(d)2(d) (d):(d):(d)$ //长时间
^(d)(-│/)(d)2(d)$ //短日期
//日期+时间
//只有年和月
//只有小时和分钟
用户名或密码^[a-zA-Z]\w{5,19}$
6位邮政编码^[0-9]{6}$
电话号码^[0-9]{3,4}-[0-9]{7,8}$
18位身份证^[0-9]{6}[12][0-9]{3}[01][0-9][0123][0-9][0-9]{3}[12]$
E-mail地址^.{1,}@.{1,}\.[a-zA-Z]{2,3}$
URL网址^http://\S+\.\S+$或^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?
只包括汉字^[\u4e00-\u9fa5]{1,}$
检查长度^.{0,20}$
数字^[-+]?\d+(\.\+)?$
年龄^(1[0-3]\d|\d{1,2}$
货币^\d+\.\d{2}$
短日期^([1-2]\d{3}|[0-9]{3})-[0-1]*[0-9]-[0-3]*[0-9]$
短日期(yyyy-MM-DD)格式,基本上把闰年和2月等的情况都考虑进去了:
^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$
这是加了时间验证的:
^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$
posted @ 2007-02-04 15:15 wander 阅读(202) 评论(0) 编辑
一、验证类
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.navigat or.appName
5.2 判断ie的版本
window.navigat or.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 复选框的全选,多选,全不选,反选
<f orm 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/>
</f orm>
<SCRIPT LANGUAGE="java script">
function checkAll(str)
{
var a = document.getElementsByName(str);
var n = a.length;
f or (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;
f or (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 ("HKCU\\Software\\ACME\\F ortuneTeller\\", 1, "REG_BINARY");
WshShell.RegWrite ("HKCU\\Software\\ACME\\F ortuneTeller\\MindReader", "Goocher!", "REG_SZ");
var bKey = WshShell.RegRead ("HKCU\\Software\\ACME\\F ortuneTeller\\");
WScript.Echo (WshShell.RegRead ("HKCU\\Software\\ACME\\F ortuneTeller\\MindReader"));
WshShell.RegDelete ("HKCU\\Software\\ACME\\F ortuneTeller\\MindReader");
WshShell.RegDelete ("HKCU\\Software\\ACME\\F ortuneTeller\\");
WshShell.RegDelete ("HKCU\\Software\\ACME\\");
</SCRIPT>
TABLAE相关(客户端动态增加行列)
<HTML>
<SCRIPT LANGUAGE="JScript">
function numberCells() {
var count=0;
f or (i=0; i < document.all.mytable.rows.length; i++) {
f or (j=0; j < document.all.mytable.rows(i).cells.length; j++) {
document.all.mytable.rows(i).cells(j).innerText = count;
count++;
}
}
}
</SCRIPT>
<BODY "numberCells()">
<TABLE id=mytable b order=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 "Err or:非法地区";
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 "Err or:非法生日";
f or(var i = 17;i>=0;i --) iSum += (Math.pow(2,i) % 11) * parseInt(sId.charAt(17 - i),11)
if(iSum%11!=1)return "Err or:非法证号";
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="java script">
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="behavi or:url(#default#download)" />
<title>Chromeless Window</title>
<SCRIPT LANGUAGE="JScript">
/*--- Special Thanks F or 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 F or 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;col or:black; b order:2px outset;b order-style:expression(onmouseout=onmouseup=function(){this.style.b orderStyle='outset'}, onmousedown=function(){if(event.button!=2)this.style.b orderStyle='inset'});background-col or:buttonface;width:16px;height:14px;font-size:12px;line-height:11px;curs or:Default;";
//Build Window
include.startDownload(CW_url, function(source){content=source});
function insert_content(){
var temp = "";
CW_Body.style.overflow = "hidden";
CW_Body.style.backgroundCol or = "white";
CW_Body.style.b order = "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 b order=0>";
temp += "<tr style=';font-size:12px;background:#0099CC;height:20;curs or: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='col or:#ffffff;padding-left:5px'>Chromeless Window F or IE6 SP1</td>";
temp += "<td style='col or:#ffffff;padding-right:5px;' align=right>";
temp += "<span id=Help onclick=\"alert('Chromeless Window F or IE6 SP1 - Ver 1.0\\n\\nCode By Windy_sk\\n\\nSpecial Thanks F or 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="java script">
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="/blog/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);
//一下是取数据的类
//Obj参数指定数据的来源(限定Table),默认第一行为字段名称行
//GetTableData类提供MoveNext方法,参数是表的行向上或向下移动的位数,正数向下移动,负数向上.
//GetFieldData方法获得指定的列名的数据
//S ort_desc方法对指定的列按降序排列
//S ort_asc方法对指定的列按升序排列
//GetData方法返回字段值为特定值的数据数组,提供数据,可以在外部进行其他处理
//Delete方法删除当前记录,数组减少一行
//初始化,Obj:table的名字,Leftlen:左面多余数据长度,Rightlen:右面多余数据长度,
function GetTableData(Obj,LeftLen,RightLen){
var MyObj=document.all(Obj);
var iRow=MyObj.rows.length;
var iLen=MyObj.rows[0].cells.length;
var i,j;
TableData=new Array();
f or (i=0;i< iRow;i++){
TableData[i]=new Array();
f or (j=0;j<iLen;j++){
TableStr=MyObj.rows(i).cells(j).innerText;
TableStr=TableStr.substring(LeftLen, TableStr.length-RightLen).Trim();
TableStr=TableStr.replace(/ /gi,"").replace(/\r\n/ig,"");
TableData[i][j]=TableStr;
}
}
this.TableData=TableData;
this.cols=this.TableData[0].length;
this.rows=this.TableData.length;
this.rowindex=0;
}
function movenext(Step){
if (this.rowindex>=this.rows){
return
}
if (Step=="" || typeof(Step)=="undefined") {
if (this.rowindex<this.rows-1)
this.rowindex++;
return;
}
else{
if (this.rowindex + Step<=this.rows-1 && this.rowindex + Step>=0 ){
this.rowindex=this.rowindex + Step;
}
else
{
if (this.rowindex + Step<0){
this.rowindex= 0;
return;
}
if (this.rowindex + Step>this.rows-1){
this.rowindex= this.rows-1;
return;
}
}
}
}
function getfielddata(Field){
var colindex=-1;
var i=0;
if (typeof(Field) == "number"){
colindex=Field;
}
else
{
f or (i=0;i<this.cols && this.rowindex<this.rows ;i++){
if (this.TableData[0][i]==Field){
colindex=i;
break;
}
}
}
if (colindex!=-1) {
return this.TableData[this.rowindex][colindex];
}
}
function s ort_desc(){//降序
var colindex=-1;
var highindex=-1;
desc_array=new Array();
var i,j;
f or (n=0; n<arguments.length; n++){
Field=arguments[arguments.length-1-n];
f or (i=0;i<this.cols;i++){
if (this.TableData[0][i]==Field){
colindex=i;
break;
}
}
if ( colindex==-1 )
return;
else
{
desc_array[0]=this.TableData[0];
f or(i=1;i<this.rows;i++){
desc_array[i]=this.TableData[1];
highindex=1;
f or(j=1;j<this.TableData.length;j++){
if (desc_array[i][colindex]<this.TableData[j][colindex]){
desc_array[i]=this.TableData[j];
highindex=j;
}
}
if (highindex!=-1)
this.TableData=this.TableData.slice(0,highindex).concat(this.TableData.slice(highindex+1,this.TableData.length));
}
}
this.TableData=desc_array;
}
return;
}
function s ort_asc(){//升序
var colindex=-1;
var highindex=-1;
var i,j;
f or (n=0; n<arguments.length; n++){
asc_array=new Array();
Field=arguments[arguments.length-1-n];
f or (i=0;i<this.cols;i++){
if (this.TableData[0][i]==Field){
colindex=i;
break;
}
}
if ( colindex==-1 )
return;
else
{
asc_array[0]=this.TableData[0];
f or(i=1;i<this.rows;i++){
asc_array[i]=this.TableData[1];
highindex=1;
f or(j=1;j<this.TableData.length;j++){//找出最小的列值
if (asc_array[i][colindex]>this.TableData[j][colindex]){
asc_array[i]=this.TableData[j];
highindex=j;
}
}
if (highindex!=-1)
this.TableData=this.TableData.slice(0,highindex).concat(this.TableData.slice(highindex+1,this.TableData.length));
}
}
this.TableData=asc_array;
}
return;
}
function getData(Field,FieldValue){
var colindex=-1;
var i,j;
GetData=new Array();
if (typeof(Field)=="undefined" || typeof(FieldValue)=="undefined" ){
return this.TableData;
}
f or(j=0;j<this.cols;j++){
if (this.TableData[0][j]==Field){
colindex=j;
}
}
if (colindex!=-1){
f or(i=1;i<this.rows;i++){
if (this.TableData[i][colindex]==FieldValue){
GetData[i]=new Array();
GetData[i]=this.TableData[i];
}
}
}
return GetData;
}
function DeletE(){
this.TableData=this.TableData.slice(0,this.rowindex).concat(this.TableData.slice(this.rowindex+1,this.TableData.length));
this.rows=this.TableData.length;
return;
}
function updateField(Field,FieldValue){
var colindex=-1;
var i=0;
if (typeof(Field) == "number"){
colindex=Field;
}
else
{
f or (i=0;i<this.cols && this.rowindex<this.rows ;i++){
if (this.TableData[0][i]==Field){
colindex=i;
break;
}
}
}
if (colindex!=-1) {
this.TableData[this.rowindex][colindex]=FieldValue;
}
}
function movefirst(){
this.rowindex=0;
}
function movelast(){
this.rowindex=this.rows-1;
}
function String.prototype.Trim() {return this.replace(/(^\s*)|(\s*$)/g,"");}
GetTableData.prototype.MoveNext = movenext;
GetTableData.prototype.GetFieldData = getfielddata;
GetTableData.prototype.S ort_asc = s ort_asc;
GetTableData.prototype.S ort_desc = s ort_desc;
GetTableData.prototype.GetData = getData;
GetTableData.prototype.Delete = DeletE;
GetTableData.prototype.UpdateField = updateField;
GetTableData.prototype.MoveFirst = movefirst;
在每个文本框的onblur事件中调用校验代码,并且每个文本框中onKeyDown事件中写一个enter转tab函数
//回车键换为tab
function enterToTab()
{
if(event.srcElement.type != 'button' && event.srcElement.type != 'textarea'
&& event.keyCode == 13)
{
event.keyCode = 9;
}
}
有时候还需要自由编辑表格---
给大家一个自由编辑表格的小例子,写的有点乱,呵呵:)
//===============================start================================
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=gb2312">
<TITLE>测试修改表格</TITLE>
<STYLE>
/*提示层的样式*/
div
{
BORDER-RIGHT: #80c144 1px solid;
BORDER-TOP: #80c144 1px solid;
VISIBILITY: hidden;
BORDER-LEFT: #80c144 1px solid;
CURSOR: default;
LINE-HEIGHT: 20px;
BORDER-BOTTOM: #80c144 1px solid;
FONT-FAMILY: 宋体;
font-size:12px;
POSITION: absolute;
BACKGROUND-COLOR: #f6f6f6;
TOP:30px;
LEFT:30px;
}
/*tr的样式*/
tr
{
font-family: "宋体";
col or: #000000;
background-col or: #C1DBF5;
font-size: 12px
}
/*table脚注样式*/
.TrFoot
{
FONT-SIZE: 12px;
font-family:"宋体", "Verdana", "Arial";
BACKGROUND-COLOR: #6699CC;
COLOR:#FFFFFF;
height: 25;
}
/*trhead属性*/
.TrHead
{
FONT-SIZE: 13px;
font-family:"宋体", "Verdana", "Arial";
BACKGROUND-COLOR: #77AADD;
COLOR:#FFFFFF;
height: 25;
}
/*文本框样式*/
INPUT
{
BORDER-COLOR: #AACEF7 #AACEF7 #AACEF7 #AACEF7;
BORDER-RIGHT: 1px solid;
BORDER-TOP: 1px solid;
BORDER-LEFT: 1px solid;
BORDER-BOTTOM: 1px solid;
FONT-SIZE: 12px;
FONT-FAMILY: "宋体","Verdana";
col or: #000000;
BACKGROUND-COLOR: #E9EFF5;
}
/*button样式*/
button
{
BORDER-COLOR: #AACEF7 #AACEF7 #AACEF7 #AACEF7;
BACKGROUND-COLOR: #D5E4F3;
CURSOR: hand;
FONT-SIZE:12px;
BORDER-RIGHT: 1px solid;
BORDER-TOP: 1px solid;
BORDER-LEFT: 1px solid;
BORDER-BOTTOM: 1px solid;
COLOR: #000000;
}
</STYLE>
</HEAD>
<BODY>
<SCRIPT language = "java script">
<!--全局变量
//标志位,值为false代表未打开一个编辑框,值为true为已经打开一个编辑框开始编辑
var editer_table_cell_tag = false;
//开启编辑功能标志,值为true时为允许编辑
var run_edit_flag = false;
//-->
</SCRIPT>
<SCRIPT language = "java script">
<!--
/**
* 编辑表格函数
* 单击某个单元格可以对里面的内容进行自由编辑
* @para tableID 为要编辑的table的id
* @para noEdiID 为不要编辑的td的ID,比如说table的标题
* 可以写为<TD id="no_editer">自由编辑表格</TD>
* 此时该td不可编辑
*/
function editerTableCell(tableId,noEdiId)
{
var tdObject = event.srcElement;
var tObject = ((tdObject.parentNode).parentNode).parentNode;
if(tObject.id == tableId &&tdObject.id != noEdiId&&editer_table_cell_tag == false && run_edit_flag == true)
{
tdObject.innerHTML = "<input type=text id=edit_table_txt name=edit_table_txt value="/blog/+tdObject.innerText+" size='15' onKeyDown='enterToTab()'> <input type=button value=' 确定 ' onclick='certainEdit()'>";
edit_table_txt.focus();
edit_table_txt.select();
editer_table_cell_tag = true;
//修改按钮提示信息
editTip.innerText = "请先点确定按钮确认修改!";
}
else
{
return false;
}
}
/**
* 确定修改
*/
function certainEdit()
{
var bObject = event.srcElement;
var tdObject = bObject.parentNode;
var txtObject = tdObject.firstChild;
tdObject.innerHTML = txtObject.value;
//代表编辑框已经关闭
editer_table_cell_tag = false;
//修改按钮提示信息
editTip.innerText = "请单击某个单元格进行编辑!";
}
function enterToTab()
{
if(event.srcElement.type != 'button' && event.srcElement.type != 'textarea'
&& event.keyCode == 13)
{
event.keyCode = 9;
}
}
/**
* 控制是否编辑
*/
function editStart()
{
if(event.srcElement.value == "开始编辑")
{
event.srcElement.value = "编辑完成";
run_edit_flag = true;
}
else
{
//如果当前没有编辑框,则编辑成功,否则,无法提交
//必须按确定按钮后才能正常提交
if(editer_table_cell_tag == false)
{
alert("编辑成功结束!");
event.srcElement.value = "开始编辑";
run_edit_flag = false;
}
}
}
/**
* 根据不同的按钮提供不同的提示信息
*/
function showTip()
{
if(event.srcElement.value == "编辑完成")
{
editTip.style.top = event.y + 15;
editTip.style.left = event.x + 12;
editTip.style.visibility = "visible";
}
else
{
editTip.style.visibility = "hidden";
}
}
-->
</SCRIPT>
<TABLE id="editer_table" width="100%" align="center"
onclick="editerTableCell('editer_table','no_editer')">
<TR class="TrHead">
<TD colspan="3" align="center" id="no_editer">自由编辑表格</TD>
</TR>
<TR>
<TD width="33%">单击开始编辑按钮,然后点击各单元格编辑</TD>
<TD width="33%">2</TD>
<TD width="33%">3</TD>
</TR>
<TR>
<TD width="33%">4</TD>
<TD width="33%">5</TD>
<TD width="33%">6</TD>
</TR>
<TR>
<TD width="33%">one</TD>
<TD width="33%">two</TD>
<TD width="33%">three</TD>
</TR>
<TR>
<TD width="33%">four</TD>
<TD width="33%">five</TD>
<TD width="33%">six</TD>
</TR>
<TR class="TrFoot">
<TD colspan="3" align="center" id="no_editer">
<INPUT type="button" class="bt" value="开始编辑" onClick="editStart()" onMouseOver="showTip()" onMouseMove="showTip()" onMouseOut="editTip.style.visibility = 'hidden';">
</TD>
</TR>
</TABLE>
</BODY>
<DIV id="editTip">请单击某个单元格进行编辑!</DIV>
</HTML>
posted @ 2007-02-04 15:12 wander 阅读(170) 评论(0) 编辑
比如说,你要点一下按钮,就访问google,那就拖个button出来,写入下代码,记得添加引用:
using System.Diagnostics;
private void button1_Click(object sender, EventArgs e)
{
Process myProcess = new Process();
myProcess.StartInfo.FileName = "iexplore.exe";
myProcess.StartInfo.Arguments = "http://www.google.com";
myProcess.Start();
}
posted @ 2006-12-25 13:10 wander 阅读(219) 评论(1) 编辑
http://dev.yesky.com/msdn/316/2456816.shtml天极(投票)
http://tech.163.com/special/000915SN/stvs2005.html
http://tech.163.com/special/A/0009159F/ASP.net.html
ASP.NET 2.0 XML高级编程(第三版)
http://book.csdn.net/bookfiles/115/
C# 2.0宝典
http://book.csdn.net/bookfiles/189/
C#高级编程(第4版)
http://book.csdn.net/bookfiles/140/
无懈可击的Web设计—— 利用XHTML和CSS提高网站的灵活性与适应性
http://book.csdn.net/bookfiles/193/
ASP.NET 2.0编程珠玑—— 来自MVP的权威开发指南
http://book.csdn.net/bookfiles/185/
ASP.NET2.0+SQL Server2005构建多层应用
http://tech.163.com/05/0831/13/1SG47BDD00091589.html
posted @ 2006-12-12 16:12 wander 阅读(91) 评论(1) 编辑
Meta标签详解,在网上转的,希望对大家有用
引言
您的个人网站即使做得再精彩,在“浩瀚如海”的网络空间中,也如一叶扁舟不易为人发现,如何推广
个人网站,人们首先想到的方法无外乎以下几种:
● 在搜索引擎中登录自己的个人网站
● 在知名网站加入你个人网站的链接
● 在论坛中发帖子宣传你的个人网站
很多人却忽视了HTML标签META的强大功效,一个好的META标签设计可以大大提高你的个人网站被搜索到的可能性,有兴趣吗,谁我来重新认识一下META标签吧!
META标签是HTML语言HEAD区的一个辅助性标签,它位于HTML文档头部的<HEAD>标记和<TITLE>标记之间,它提供用户不可见的信息。meta标签通常用来为搜索引擎robots定义页面主题,或者是定义用户浏览器上的cookie;它可以用于鉴别作者,设定页面格式,标注内容提要和关键字;还可以设置页面使其可以根据你定义的时间间隔刷新自己,以及设置RASC内容等级,等等。
详细介绍
下面介绍一些有关 标记的例子及解释。
META标签分两大部分:HTTP标题信息(HTTP-EQUIV)和页面描述信息(NAME)。
★HTTP-EQUIV
HTTP-EQUIV类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正确和精确地显示网页内容。常用的HTTP-EQUIV类型有:
1、Content-Type和Content-Language (显示字符集的设定)
说明:设定页面使用的字符集,用以说明主页制作所使用的文字已经语言,浏览器会根据此来调用相应的字符集显示page内容。
用法:<Meta http-equiv="Content-Type" Content="text/html; Charset=gb2312">
<Meta http-equiv="Content-Language" Content="zh-CN">
注意: 该META标签定义了HTML页面所使用的字符集为GB2132,就是国标汉字码。如果将其中的“charset=GB2312”替换成“BIG5”,则该页面所用的字符集就是繁体中文Big5码。当你浏览一些国外的站点时,IE浏览器会提示你要正确显示该页面需要下载xx语支持。这个功能就是通过读取HTML页面META标签的Content-Type属性而得知需要使用哪种字符集显示该页面的。如果系统里没有装相应的字符集,则IE就提示下载。其他的语言也对应不同的charset,比如日文的字符集是“iso-2022-jp ”,韩文的是“ks_c_5601”。
Content-Type的Content还可以是:text/xml等文档类型;
Charset选项:ISO-8859-1(英文)、BIG5、UTF-8、SHIFT-Jis、Euc、Koi8-2、us-ascii, x-mac-roman, iso-8859-2, x-mac-ce, iso-2022-jp, x-sjis, x-euc-jp,euc-kr, iso-2022-kr, gb2312, gb_2312-80, x-euc-tw, x-cns11643-1,x-cns11643-2等字符集;Content-Language的Content还可以是:EN、FR等语言代码。
2、Refresh (刷新)
说明:让网页多长时间(秒)刷新自己,或在多长时间后让网页自动链接到其它网页。
用法:<Meta http-equiv="Refresh" Content="30">
<Meta http-equiv="Refresh" Content="5; Url=http://www.xia8.net">
注意:其中的5是指停留5秒钟后自动刷新到URL网址。
3、Expires (期限)
说明:指定网页在缓存中的过期时间,一旦网页过期,必须到服务器上重新调阅。
用法:<Meta http-equiv="Expires" Content="0">
<Meta http-equiv="Expires" Content="Wed, 26 Feb 1997 08:21:57 GMT">
注意:必须使用GMT的时间格式,或直接设为0(数字表示多少时间后过期)。
4、Pragma (cach模式)
说明:禁止浏览器从本地机的缓存中调阅页面内容。
用法:<Meta http-equiv="Pragma" Content="No-cach">
注意:网页不保存在缓存中,每次访问都刷新页面。这样设定,访问者将无法脱机浏览。
5、Set-Cookie (cookie设定)
说明:浏览器访问某个页面时会将它存在缓存中,下次再次访问时就可从缓存中读取,以提高速度。当你希望访问者每次都刷新你广告的图标,或每次都刷新你的计数器,就要禁用缓存了。通常HTML文件没有必要禁用缓存,对于ASP等页面,就可以使用禁用缓存,因为每次看到的页面都是在服务器动态生成的,缓存就失去意义。如果网页过期,那么存盘的cookie将被删除。
用法:<Meta http-equiv="Set-Cookie" Content="cookievalue=xxx; expires=Wednesday,
21-Oct-98 16:14:21 GMT; path=/">
注意:必须使用GMT的时间格式。
6、Window-target (显示窗口的设定)
说明:强制页面在当前窗口以独立页面显示。
用法:<Meta http-equiv="Widow-target" Content="_top">
注意:这个属性是用来防止别人在框架里调用你的页面。Content选项:_blank、_top、_self、_parent。
7、Pics-label (网页RSAC等级评定)
说明:在IE的Internet选项中有一项内容设置,可以防止浏览一些受限制的网站,而网站的限制级
别就是通过该参数来设置的。
用法:<META http-equiv="Pics-label" Contect=
"(PICS-1.1'http://www.rsac.org/ratingsv01.html'
I gen comment 'RSACi North America Sever' by 'inet@microsoft.com'
for 'http://www.microsoft.com' on '1997.06.30T14:21-0500' r(n0 s0 v0 l0))">
注意:不要将级别设置的太高。RSAC的评估系统提供了一种用来评价Web站点内容的标准。用户可以设置Microsoft Internet Explorer(IE3.0以上)来排除包含有色情和暴力内容的站点。上面这个例子中的HTML取自Microsoft的主页。代码中的(n 0 s 0 v 0 l 0)表示该站点不包含不健康内容。级别的评定是由RSAC,即美国娱乐委员会的评级机构评定的,如果你想进一步了解RSAC评估系统的等级内容,或者你需要评价自己的网站,可以访问RSAC的站点:http://www.rsac.org/。
8、Page-Enter、Page-Exit (进入与退出)
说明:这个是页面被载入和调出时的一些特效。
用法:<Meta http-equiv="Page-Enter" Content="blendTrans(Duration=0.5)">
<Meta http-equiv="Page-Exit" Content="blendTrans(Duration=0.5)">
注意:blendTrans是动态滤镜的一种,产生渐隐效果。另一种动态滤镜RevealTrans也可以用于页面进入与退出效果:
<Meta http-equiv="Page-Enter" Content="revealTrans(duration=x, transition=y)">
<Meta http-equiv="Page-Exit" Content="revealTrans(duration=x, transition=y)">
Duration 表示滤镜特效的持续时间(单位:秒)
Transition 滤镜类型。表示使用哪种特效,取值为0-23。
0 矩形缩小
1 矩形扩大
2 圆形缩小
3 圆形扩大
4 下到上刷新
5 上到下刷新
6 左到右刷新
7 右到左刷新
8 竖百叶窗
9 横百叶窗
10 错位横百叶窗
11 错位竖百叶窗
12 点扩散
13 左右到中间刷新
14 中间到左右刷新
15 中间到上下
16 上下到中间
17 右下到左上
18 右上到左下
19 左上到右下
20 左下到右上
21 横条
22 竖条
23 以上22种随机选择一种
9、MSThemeCompatible (XP主题)
说明:是否在IE中关闭 xp 的主题
用法:<Meta http-equiv="MSThemeCompatible" Content="Yes">
注意:关闭 xp 的蓝色立体按钮系统显示样式,从而和win2k 很象。
10、IE6 (页面生成器)
说明:页面生成器generator,是ie6
用法:<Meta http-equiv="IE6" Content="Generator">
注意:用什么东西做的,类似商品出厂厂商。
11、Content-Script-Type (脚本相关)
说明:这是近来W3C的规范,指明页面中脚本的类型。
用法:<Meta http-equiv="Content-Script-Type" Content="text/javascript">
注意:
★NAME变量
name是描述网页的,对应于Content(网页内容),以便于搜索引擎机器人查找、分类(目前几乎所有的搜索引擎都使用网上机器人自动查找meta值来给网页分类)。
name的value值(name="")指定所提供信息的类型。有些值是已经定义好的。例如description(说明)、keyword(关键字)、refresh(刷新)等。还可以指定其他任意值,如:creationdate(创建日期) 、
document ID(文档编号)和level(等级)等。
name的content指定实际内容。如:如果指定level(等级)为value(值),则Content可能是beginner(初级)、intermediate(中级)、advanced(高级)。
1、Keywords (关键字)
说明:为搜索引擎提供的关键字列表
用法:<Meta name="Keywords" Content="关键词1,关键词2,关键词3,关键词4,……">
注意:各关键词间用英文逗号“,”隔开。META的通常用处是指定搜索引擎用来提高搜索质量的关键词。当数个META元素提供文档语言从属信息时,搜索引擎会使用lang特性来过滤并通过用户的语言优先参照来显示搜索结果。例如:
<Meta name="Kyewords" Lang="EN" Content="vacation,greece,sunshine">
<Meta name="Kyewords" Lang="FR" Content="vacances,grè:ce,soleil">
2、Description (简介)
说明:Description用来告诉搜索引擎你的网站主要内容。
用法:<Meta name="Description" Content="你网页的简述">
注意:
3、Robots (机器人向导)
说明:Robots用来告诉搜索机器人哪些页面需要索引,哪些页面不需要索引。Content的参数有all、none、index、noindex、follow、nofollow。默认是all。
用法:<Meta name="Robots" Content="All|None|Index|Noindex|Follow|Nofollow">
注意:许多搜索引擎都通过放出robot/spider搜索来登录网站,这些robot/spider就要用到meta元素的一些特性来决定怎样登录。
all:文件将被检索,且页面上的链接可以被查询;
none:文件将不被检索,且页面上的链接不可以被查询;(和 "noindex, no follow" 起相同作用)
index:文件将被检索;(让robot/spider登录)
follow:页面上的链接可以被查询;
noindex:文件将不被检索,但页面上的链接可以被查询;(不让robot/spider登录)
nofollow:文件将不被检索,页面上的链接可以被查询。(不让robot/spider顺着此页的连接往下探找)
4、Author (作者)
说明:标注网页的作者或制作组
用法:<Meta name="Author" Content="张三,abc@sina.com">
注意:Content可以是:你或你的制作组的名字,或Email
5、Copyright (版权)
说明:标注版权
用法:<Meta name="Copyright" Content="本页版权归Zerospace所有。All Rights Reserved">
注意:
6、Generator (编辑器)
说明:编辑器的说明
用法:<Meta name="Generator" Content="PCDATA|FrontPage|">
注意:Content="你所用编辑器"
7、revisit-after (重访)
说明:
用法:<META name="revisit-after" CONTENT="7 days" >
注意:
★Head中的其它一些用法
1、scheme (方案)
说明:scheme can be used when name is used to specify how the value of content should
be interpreted.
用法:<meta scheme="ISBN" name="identifier" content="0-14-043205-1" />
注意:
2、Link (链接)
说明:链接到文件
用法:<Link href="soim.ico" rel="Shortcut Icon">
注意:很多网站如果你把她保存在收件夹中后,会发现它连带着一个小图标,如果再次点击进入之后还会发现地址栏中也有个小图标。现在只要在你的页头加上这段话,就能轻松实现这一功能。<LINK> 用来将目前文件与其它 URL 作连结,但不会有连结按钮,用於 <HEAD> 标记间, 格式如下:
<link href="URL" rel="relationship">
<link href="URL" rev="relationship">
3、Base (基链接)
说明:插入网页基链接属性
用法:<Base href="http://www.xia8.net/" target="_blank">
注意:你网页上的所有相对路径在链接时都将在前面加上“http://www.cn8cn.com/”。其中target="_blank"是链接文件在新的窗口中打开,你可以做其他设置。将“_blank”改为“_parent”是链接文件将在当前窗口的父级窗口中打开;改为“_self”链接文件在当前窗口(帧)中打开;改为“_top”链接文件全屏显示。
以上是META标签的一些基本用法,其中最重要的就是:Keywords和Description的设定。为什么呢?道理很简单,这两个语句可以让搜索引擎能准确的发现你,吸引更多的人访问你的站点!根据现在流行搜索引擎(Google,Lycos,AltaVista等)的工作原理,搜索引擎先派机器人自动在WWW上搜索,当发现新的网站时,便于检索页面中的Keywords和Description,并将其加入到自己的数据库,然后再根据关键词的密度将网站排序。
由此看来,我们必须记住添加Keywords和Description的META标签,并尽可能写好关键字和简介。否则,
后果就会是:
● 如果你的页面中根本没有Keywords和Description的META标签,那么机器人是无法将你的站点加入数
据库,网友也就不可能搜索到你的站点。
● 如果你的关键字选的不好,关键字的密度不高,被排列在几十甚至几百万个站点的后面被点击的可
能性也是非常小的。
写好Keywords(关键字)要注意以下几点:
● 不要用常见词汇。例如www、homepage、net、web等。
● 不要用形容词,副词。例如最好的,最大的等。
● 不要用笼统的词汇,要尽量精确。例如“爱立信手机”,改用“T28SC”会更好。
“三人之行,必有我师”,寻找合适关键词的技巧是:到Google、Lycos、Alta等著名搜索引擎,搜索与
你的网站内容相仿的网站,查看排名前十位的网站的META关键字,将它们用在你的网站上,效果可想而知了。
★小窍门
为了提高搜索点击率,这里还有一些“捷径”可以帮得到你:
● 为了增加关键词的密度,将关键字隐藏在页面里(将文字颜色定义成与背景颜色一样)。
● 在图像的ALT注释语句中加入关键字。如:<IMG SRC="xxx.gif" Alt="Keywords">
● 利用HTML的注释语句,在页面代码里加入大量关键字。用法: <!-- 这里插入关键字 -->
<head> <title>文件头,显示在浏览器标题区</title> <meta http-equiv="Content-Language" content="zh-cn"> <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"> <meta name="制作人" content="唐蓉生"> <meta name="主题词" content="HTML 网页制作 课件"></head>
posted @ 2006-10-16 16:49 wander 阅读(106) 评论(0) 编辑
posted @ 2006-10-12 14:17 wander 阅读(155) 评论(0) 编辑
posted @ 2006-09-07 13:39 wander 阅读(492) 评论(2) 编辑
