显示标签为“MVC-V”的博文。显示所有博文
显示标签为“MVC-V”的博文。显示所有博文

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数-ecoding GBK或-ecoding gb2312编译;对于JSP,在文件头加上<%@ page contentType="text/html;charset=GBK"%>或<%@ page contentType="text/html;charset=gb2312"%>基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序 byte->char
从java程序到页面显示 char—>byte

从数据库到java程序 byte—>char
从java程序到数据库 char—>byte

从文件到java程序 byte->char
从java程序到文件 char->byte

从流到java程序 byte->char
从java程序到流 char->byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码
JSP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding("GBK")或request.setCharacterEncoding("gb2312")。
如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType("text/html;charset=GBK")或response.setContentType("text/html;charset=gb2312")解决。
如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:
web.xml:


CharacterEncodingFilter
net.vschool.web.CharacterEncodingFilter

encoding
GBK



CharacterEncodingFilter
/*


CharacterEncodingFilter.java:

public class CharacterEncodingFilter implements Filter
{

protected String encoding = null;

public void init(FilterConfig filterConfig) throws ServletException
{
this.encoding = filterConfig.getInitParameter("encoding");
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
chain.doFilter(request, response);
}

}


2、Java与数据库之间的乱码
大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。

3、Java与文件/流之间的乱码
Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中 FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的 FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型:InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。

4、其他
上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性charset和setCharset(String)方法,将upload()方法中提取参数语句:
String value = new String(m_binArray, m_startData, (m_endData - m_startData) + 1 );
改成了
String value = new String(m_binArray, m_startData, (m_endData - m_startData) + 1, charset );
终于解决了这个乱码问题。

在网页的HEAD部分中包含有许多内置标签,规范填写这些标签,非常有助于网站的推广。

meta标签是内嵌在你网页中的特殊html标签,包含着你有关于你网页的一些隐藏信息。Meat标签的作用是向搜索引擎解释你的网页是有关哪方面 信息的。对于高级的搜索引擎来说,html 的meta 标签并不是什么新奇的东西。但是无论如何它是一个优秀网页不可缺少的。下面我们就它进行一些讲解吧。

当你计划搜索引擎优化策略是meta标签是非常重要的。尽管如此,一般的加入meta 并不能帮助你在搜索引擎中获得更好的排名。有好几种meta标签,但重要的有以下几个:description标签,keywords标签,title标 签(严格来说title不算是一个标签)。当你不时刷新标签时这几个标签显得特别的重要。如果你希望搜索引擎对你的网站进行索引时就会用到html标签的 重定向(redirect)标签与robots标签。

注意:调查表只有20%的网页用到“关键字”与“描述”标签(即keyword,description)

多个关键字用英文逗号分开。

title 标签

title 标签可能是你网页中最重要的标签,它是你网页中最先看到的部分。把它放在description 与 keyword前。在这个标签中最好是加上你网站的关键字,title标签在搜索引擎的搜索中占有非常重要的地位。最好是把它放在其他meta标签前,这 更有利于你网站的排名。(注意:有些搜索引擎会按title标签的字母的优先权进行排名,尽量在你的title中使用开始的字母)title标签是人们在 搜索引擎中第一个看到有关你网站的描述,所以尽量把它弄得简单、明了。让人一看就知道你的网站是关于什么的。

Description标签

Description标签就在title后面,该标签可以是一小段(一个或者两个句子)。用于描述你网站。与title标签一样,这也是人们在搜 索引擎列表中链接到你网站的点击。这些描述将鼓动人们去浏览你的网站而不是你竞争对手的。(描述不能太夸张。不然,当访问者到你网站发现内容根本不是你说 的那个样子,那么他很快就会退出去。)很多搜索引擎允许描述的字数在150个左右,所以你要保证你的描述在150以下,否则搜索引擎会自动把多余的部分剪 去从而造成你网站的描述的不完整。搜索引擎认为描述里的关键字远比网页中的内容要重要(好像现在这种情况不是那么明显了)。真如上所述,这里提供了非常重 要的信息:确定你的描述能正确的反映你网站的主题,尽量在描述中加入你主要的关键字,越靠meta的关键字意义越大。这样会突显你的关键字。

现在大多的搜索引擎(google除外)都会支持descriptin标签。如果你不使用的话你将会失去排名靠前的可能。

keyword 标签

相比于description与title标签,keyword标签显得并不是那么重要了。有些搜索引擎把它完全地忽略,但是使用下正确的keyword标签对提高排名仍然有效。

除了搜索引擎外,一般情况下人们是看不到的。keyword标签是一个隐藏的标签,向搜索引擎提供了一组与你的页面有关的的关键字或关键短语列表。 你可以用相应的工具找出一系列适用于你网站的关键字。(注意:关键字标签中只能包括与你本页内容相关的关键字列表。所有在这里的关键字必须与页面的内容相 联系。)

提示:在你每一个页面中组织相关的关键字,每个页面必须专注于不同的产品或者内容。在标签中列满关键字对于提高你网站的排名并没有好处。多个关键字 间用逗号用隔,逗号表示是逻辑“或”的意思。空格表示逻辑“与”。这是正式在keyword标签中描述关键字必须的。尽管如此,很多搜索引擎也会把关键字 间以空格分开以达到能搜索出更相关的结果的目的。这样做的意义是,搜索引擎会把空格分开的关键字根据一定的方式自由组合。可以尝试用两种方法,看哪一种更 加适合你。

关键字不宜以同一形式重复3-6次,一般这已经认为是最大的关键字重复数(好像现在又发生了变化)。所以,尽量避免把你的关键字一次又一次地不断重 复。这对于每一个搜索引擎来说是SPAM(关键字垃圾),你会因此而受到惩罚。大多数的搜索引擎会允许你在keyword标签中使用最多1000个字符。 通常,对每一个页面使用相关连的关键字会提高你网站的排名。一个很重要的因素是你关键字冗余度,如果你一个关键字是一个字符,而你的keyword标签中 有100个字符,那么你关键字的冗余度就为1%。搜索引擎将会利用相关的算法对你的关键字冗余度进行统计你网页中的每一个重要的词或短语。去除多余的关键 字有利于提高你网站的排名。

对于readyState的五种状态的描述或者说定义,很多Ajax书(英文原版)中大都语
焉不详
在《Pragmatic Ajax A Web 2.0 Primer 》中偶然看到对readyStae状态的介绍,感
觉这个介绍很实在……
比较理想的解释方法应该以"状态:任务(目标)+过程+表现(或特征)"的表达模
式来对这几个状态进行定义

【全文】

在《Pragmatic Ajax A Web 2.0 Primer 》中偶然看到对readyStae状态的介绍,感
觉这个介绍很实在,摘译如下:

0: (Uninitialized) the send( ) method has not yet been invoked.
1: (Loading) the send( ) method has been invoked, request in progress.
2: (Loaded) the send( ) method has completed, entire response received.
3: (Interactive) the response is being parsed.
4: (Completed) the response has been parsed, is ready for harvesting.

0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了

对于readyState的这五种状态,其他书中大都语焉不详。像《Foundations of
Ajax》中,只在书中的表2-2简单地列举了状态的"名称"--The state of the
request. The five possible values are 0 = uninitialized, 1 = loading, 2
= loaded, 3 = interactive, and 4 = complete。而《Ajax in Action》中好像根
本就没有提到这5种状态的细节。《Professional Ajax》中虽不尽人意,但还是有可
取之处:

There are five possible values for readyState:
0 (Uninitialized): The object has been created but the open() method
hasn't been called.
1 (Loading): The open() method has been called but the request hasn't
been sent.
2 (Loaded): The request has been sent.
3 (Interactive). A partial response has been received.
4 (Complete): All data has been received and the connection has been closed.

readyState有五种可能的值:
0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法。
1 (载入):已经调用open() 方法,但尚未发送请求。
2 (载入完成): 请求已经发送完成。
3 (交互):可以接收到部分响应数据。
4 (完成):已经接收到了全部数据,并且连接已经关闭。

在《Understanding AJAX: Using JavaScript to Create Rich Internet
Applications》中,则用下表进行了说明:

表1. readyState Levels

readyState Status Code

Status of the XMLHttpRequest Object


(0) UNINITIALIZED
未初始化

The object has been created but not initialized. (The open method has
not been called.)
(XMLHttpRequest)对象已经创建,但尚未初始化(还没有调用open方法)。


(1) LOADING
载入

The object has been created, but the send method has not been called.
(XMLHttpRequest)对象已经创建,但尚未调用send方法。


(2) LOADED
载入完成

The send method has been called, but the status and headers are not yet
available.
已经调用send方法,(HTTP响应)状态及头部还不可用。


(3) INTERACTIVE
交互

Some data has been received. Calling the responseBody and responseText
properties at this state to obtain partial results will return an error,
because status and response headers are not fully available.
已经接收部分数据。但若在此时调用responseBody和responseText属性获取部分结
果将会产生错误,因为状态和响应头部还不完全可用。


(4) COMPLETED
完成

All the data has been received, and the complete data is available in
the responseBody and responseText properties.
已经接收到了全部数据,并且在responseBody和responseText属性中可以提取到完
整的数据。


根 据以上几本书中的关于readyState五种状态的介绍,我认为还是《Pragmatic
Ajax A Web 2.0 Primer 》比较到位,因为它提到了对接收到的数据的解析问题,
其他书中都没有提到这一点,而这一点正是"(3)交互"阶段作为一个必要的转换过
程存在于"(2)载入完成"到"(4)完成"之间的理由,也就是其任务是什么。归结起
来,我觉得比较理想的解释方法应该以"状态:任务(目标)+过程+表现(或特
征)"表达模式来对这几个状态进行定义比较准确,而且让人容易理解。现试总结
如下:

表2. readyState 状态详解

readyState 状态

状态说明


(0)未初始化

此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好
准备。值为0表示对象已经存在,否则浏览器会报错--对象不存在。


(1)载入

此阶段对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,
url,true)完成对象状态的设置。并调用 send()方法开始向服务端发送请求。值为
1表示正在向服务端发送请求。


(2)载入完成

此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能
直接在客户端使用。值为2表示已经接收完全部响应数据。并为下一阶段对数据解
析作好准备。


(3)交互

此阶段解析接收到的服务器端响应数据。即根据服务器端响应头部返回的MIME类型
把数据转换成能通过responseBody、responseText 或responseXML属性存取的格
式,为在客户端调用作好准备。状态3表示正在解析数据。


(4)完成

此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。值为4表示
数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。


概而括之,整个XMLHttpRequest对象的生命周期应该包含如下阶段:
创建-初始化请求-发送请求-接收数据-解析数据-完成

在具体应用中,明确了readyState的五个状态(XMLHttpRequest对象的生命周期各
个阶段)的含义,就可以消除对Ajax核心的神秘感(语焉不详的背后要么是故弄玄
虚,制造神秘感;要么就是"以其昏昏,使人昭昭"),迅速把握其实质,对减少学
习中的挫折感和增强自信心都极其有益。

比如,通过如下示例:

//声明数组
var states = ["正在初始化……",
"正在初始化请求……成功!<br/>正在发送请求……",
"成功!<br/>正在接收数据……",
"完成!<br/>正在解析数据……",
"完成!<br/>"];

//回调函数内部代码片段
if (xmlHttp.readyState==4)
{
var span = document.createElement("span");
span.innerHTML = states[xmlHttp.readyState];
document.body.appendChild(span);

if (xmlHttp.status == 200)
{
var xmldoc = xmlHttp.responseXML;
//其他代码
}

//别忘记销毁,防止内存泄漏
xmlHttp = null;
}else{
var span = document.createElement("span");
span.innerHTML = states[xmlHttp.readyState];
document.body.appendChild(span);
}

结果如下: 正在初始化请求……成功!
正在发送请求……成功!
正在接收数据……完成!
正在解析数据……完成!

我们很容易明白XMLHttpRequest对象在各个阶段都在做什么。因此,也就很容易对
Ajax的核心部分有一个真正简单明了的

javascript的splice

从一个数组中移除一个或多个元素,如果必要,在所移除元素的位置上插入新元素,返回所移除的元素。

arrayObj.splice(start, deleteCount, [item1[, item2[, . . . [,itemN]]]])

参数

arrayObj

必选项。一个 Array 对象。

start

必选项。指定从数组中移除元素的开始位置,这个位置是从 0 开始计算的。

deleteCount

必选项。要移除的元素的个数。

item1, item2,. . .,itemN

必选项。要在所移除元素的位置上插入的新元素。

说明

splice 方法可以移除从 start 位置开始的指定个数的元素并插入新元素,从而修改 arrayObj。返回值是一个由所移除的元素组成的新 Array 对象。

示例:

script language="javascript">
function test()
{
//var a=[1,2,3];
//alert(a);
var a=[1,2,3];
a.splice(1,1,4,6,7,8) //移除第二个,然后在第一个后插入4,6,7,8,返回:1,4,6,7,8,3
alert(a);
a.splice(0,1,3) //移除第一个,然后在第一个前插入3,返回:3,4,6,7,8,3
alert(a);

a.splice(2,0,5) //在第三个元素插入一个5,返回:3,4,5,6,7,8
alert(a);

a.splice(-1,1) //移动最后一位,类似shift方法,返回:3,4,5,6,7,8
alert(a);


}
</script>

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它采用完全独立于语言的文本格式,可以用来在客户端和服务器端传输数据!JSON对象既可用于AJAX的开发中,也可用一般的J2EE的开发中,用于一次性向后台提交多于一条的记录!(譬如显示在页面上的table中记录)
JSON官方网站的介绍:(www.json.org)

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

JSON is built on two structures:


* A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.

* An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.



These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangable with programming languages also be based on these structures.

简单的示例:
1。var jsonObj={person1:{name:"jack",age:"12"},
person2:{name:"kate",age:"23"},
person3:{name:"jim",age:"14"}
};
调用JSON对象的属性,
1)jsonObj.person1.name
2)jsonObj["person1"].name
可以通过for循环的方式调用JSON对象中的每一个子对象
for(var p in jsonStr){
//alert(typeof p); alert(p);//返回的是string
str+=jsonObj[p].name+","+jsonObj[p].age+"<br>";
}

2。var jsonObj2={persons:[{name:"jordan",sex:"m",age:"40"},
{name:"bryant",sex:"m",age:"28"},
{name:"McGrady",sex:"m",age:"27"}
]};

调用JSON对象的属性,
1)jsonObj2.persons[0].name;
2)for循环调用方法,
var persons=jsonObj2.persons;//返回的值是一个数组object
for(var i=0;i<persons.length;i++){
cur_person=persons[i];
str+=cur_person.name+"'sex is "+cur_person.sex+" and age is "+cur_person.age+"<br>";
}
向jsonObj2的persons数组中插入,删除,更新 数据,
此处,可以利用javascript的Array对象的方法进行操作,如
var person={name:"yaoMing",sex:"m",age:"26"};
jsonObj2.persons.push(person);//数组最后加一条记录
jsonObj2.persons.pop();//删除最后一项
jsonObj2.persons.shift();//删除第一项
jsonObj2.persons.unshift(person);//数组最前面加一条记录
只要适合Javascript的方法都是可以用在JSON对象的数组中的!所以还有另外的方法splice( )进行crud操作!
//删除
jsonObj2.persons.splice(0,1);//开始位置,删除个数
//替换不删除
var self={name:"tom",sex:"m",age:"24"};
var brother={name:"Mike",sex:"m",age:"29"};
jsonObj2.persons.splice(1,0,self,brother);//开始位置,删除个数,插入对象
//替换并删除
var self={name:"tom",sex:"m",age:"24"};
var brother={name:"Mike",sex:"m",age:"29"};
jsonObj2.persons.splice(0,1,self,brother);//开始位置,删除个数,插入对象

二,知道了在Javascript中JSON的基本操作,但这还不能与后台进行交互,在着之前还需要把它转化为 String!

方法有两个,1)引入一个方法 :

function obj2str(o){
var r = [];
if(typeof o =="string") return "\""+o.replace(/([\'\"\\])/g,"\\$1").replace(/(\n)/g,"\\n").replace(/(\r)/g,"\\r").replace(/(\t)/g,"\\t")+"\"";
if(typeof o == "object"){
if(!o.sort){
r[0]="{"
for(var i in o){
r[r.length]=i;
r[r.length]=":";
r[r.length]=obj2str(o[i]);
r[r.length]=",";
}
if(!!document.all && !/^\n?function\s*toString\(\)\s*\{\n?\s*\[native code\]\n?\s*\}\n?\s*$/.test(o.toString)){
r[r.length]="toString:"+o.toString.toString();
r[r.length]=",";
}
r[r.length-1]="}"
}else{
r[0]="["
for(var i =0;i<o.length;i++){
r[r.length]=obj2str(o[i]);
r[r.length]=",";
}
r[r.length-1]="]"
}
return r.join("");
}
return o.toString();
}

网上找的,还蛮好用地!!在此对原创者表示感谢啦!!

2)JSON官方网站提供的一个开源的JSON解析器和字符串转换 器,json.js

到此为止的话,就可以顺利的将客户端这边的记录传到后台!!

下面还有 一个服务器端如何处理的过程,下会接着进行总结!!

1.CSS字体属性简写规则
一般用CSS设定字体属性是这样做的:
font-weight:bold;
font-style:italic;
font-varient:small-caps;
font-size:1em;
line-height:1.5em;
font-family:verdana,sans-serif;
但也可以把它们全部写到一行上去:
font: bold italic small-caps 1em/1.5em verdana,sans-serif;
真不错!只有一点要提醒的:这种简写方法只有在同时指定font-size和font-family属性时才起作用。而且,如果你没有设定font-weight, font-style, 以及 font-varient ,他们会使用缺省值,这点要记上。

2. 同时使用两个类
一般只能给一个元素设定一个类(Class),但这并不意味着不能用两个。事实上,你可以这样:

...


同时给P元素两个类,中间用空格格开,这样所有text和side两个类的属性都会加到P元素上来。如果它们两个类中的属性有冲突的话,后设置的起作用,即在CSS文件中放在后面的类的属性起作用。
补充:对于一个ID,不能这样写

...

也不能这样写

3. CSS border的缺省值
通常可以设定边界的颜色,宽度和风格,如:
border: 3px solid #000
这位把边界显示成3像素宽,黑色,实线。但实际上这里只需要指定风格即可。
如果只指定了风格,其他属性就会使用缺省值。一般地,Border的宽度缺省是medium,一般等于3到4个像素;缺省的颜色是其中文字的颜色。如果这个值正好合适的话,就不用设那么多了。

4. CSS用于文档打印
许多网站上都有一个针对打印的版本,但实际上这并不需要,因为可以用CSS来设定打印风格。
也就是说,可以为页面指定两个CSS文件,一个用于屏幕显示,一个用于打印:
《link type='text/css" rel="stylesheet" href="stylesheet.css" media="screen"> 《link type="text/css" rel="stylesheet" href="printstyle.css" media="print">
第1行就是显示,第2行是打印,注意其中的media属性。
但应该在打印 CSS中写什么东西呢?你可以按设计普通CSS的方法来设定它。设计的同时就可以把这个CSS设成显示CSS来检查它的效果。也许你会使用 display: none 这个命令来关掉一些装饰图片,再关掉一些导航按钮。要想了解更多,可以看“打印差异”这一篇。

5. 图片替换技巧
一般都建议用标准的HTML来显示文字,而不要使用图片,这样不但快,也更具可读性。但如果你想用一些特殊字体时,就只能用图片了。
比如你想整个卖东西的图标,你就用了这个图片:

Buy widgets


这当然可以,但对搜索引擎来说,和正常文字相比,它们对alt里面的替换文字几乎没有兴趣这是因为许多设计者在这里放许多关键词来骗搜索引擎。所以方法应该是这样的:

Buy widgets


但这样就没有特殊字体了。要想达到同样效果,可以这样设计CSS:
h1 { background: url(widget-image.gif) no-repeat; height: image height text-indent: -2000px }
注意把image height换成真的图片的高度。这里,图片会当作背景显示出来,而真正的文字由于设定了-2000像素这个缩进,它们会出现在屏幕左边2000点的地方,就看不见了。但这对于关闭图片的人来说,可能全部看不到了,这点要注意。

6. CSS box模型的另一种调整技巧
这个Box模型的调整主要是针对IE6之前的IE浏览器的,它们把边界宽度和空白都算在元素宽度上。比如:
#box { width: 100px; border: 5px; padding: 20px }
这样调用它:
...

这时盒子的全宽应该是150点,这在除IE6之前的IE浏览器之外的所有浏览器上都是正确的。但在IE5这样的浏览器上,它的全宽仍是100点。可以用以前人发明的Box调整方法来处理这种差异。
但用CSS也可以达到同样的目的,让它们显示效果一致。
#box { width: 150px } #box div { border: 5px; padding: 20px }
这样调用:
...

这样,不管什么浏览器,宽度都是150点了。

7. 块元素居中对齐

如果想做个固定宽度的网页并且想让网页水平居中的话,通常是这样:
#content { width: 700px; margin: 0 auto }
你会使用《div id="content"> 来围上所有元素。这很简单,但不够好,IE6之前版本会显示不出这种效果。改CSS如下:
body { text-align: center } #content { text-align: left; width: 700px; margin: 0 auto }
这会把网页内容都居中,所以在Content中又加入了
text-align: left 。

8. 用CSS来处理垂直对齐
垂直对齐用表格可以很方便地实现,设定表格单元 vertical-align: middle 就可以了。但对CSS来说这没用。如果你想设定一个导航条是2em高,而想让导航文字垂直居中的话,设定这个属性是没用的。
CSS方法是什么呢?对了,把这些文字的行高设为 2em:line-height: 2em ,这就可以了。

9. CSS在容器内定位
CSS的一个好处是可以把一个元素任意定位,在一个容器内也可以。比如对这个容器:
#container { position: relative }
这样容器内所有的元素都会相对定位,可以这样用:


如果想定位到距左30点,距上5点,可以这样:
#navigation { position: absolute; left: 30px; top: 5px }
当然,你还可以这样:
margin: 5px 0 0 30px
注意4个数字的顺序是:上、右、下、左。当然,有时候定位的方法而不是边距的方法更好些。

10. 直通到屏幕底部的背景色
在垂直方向是进行控制是CSS所不能的。如果你想让导航栏和内容栏一样直通到页面底部,用表格是很方便的,但如果只用这样的CSS:
#navigation { background: blue; width: 150px }
较短的导航条是不会直通到底部的,半路内容结束时它就结束了。该怎么办呢?
不幸的是,只能采用欺骗的手段了,给这较短的一栏加上个背景图,宽度和栏宽一样,并让它的颜色和设定的背景色一样。
body { background: url(blue-image.gif) 0 0 repeat-y }
此时不能用em做单位,因为那样的话,一旦读者改变了字体大小,这个花招就会露馅,只能使用px。

prototype 是在 IE 4 及其以后版本引入的一个针对于某一类的对象的方法,而且特殊的地方便在于:它是一个给类的对象添加方法的方法!这一点可能听起来会有点乱,别急,下面我便通过实例对这一特殊的方法作已下讲解:
  首先,我们要先了解一下类的概念,JavaScript 本身是一种面向对象的语言,它所涉及的元素根据其属性的不同都依附于某一个特定的类。我们所常见的类包括:数组变量(Array)、逻辑变量(Boolean)、日期变量(Date)、结构变量(Function)、数值变量(Number)、对象变量(Object)、字符串变量(String) 等,而相关的类的方法,也是程序员经常用到的(在这里要区分一下类的注意和属性发方法),例如数组的push方法、日期的get系列方法、字符串的split方法等等,
  但是在实际的编程过程中不知道有没有感觉到现有方法的不足?prototype 方法应运而生!下面,将通过实例由浅入深讲解 prototype 的具体使用方法:
1、最简单的例子,了解 prototype:
(1) Number.add(num):作用,数字相加
实现方法:Number.prototype.add = function(num){return(this+num);}
试验:alert((3).add(15)) -> 显示 18
(2) Boolean.rev(): 作用,布尔变量取反
实现方法:Boolean.prototype.rev = function(){return(!this);}
试验:alert((true).rev()) -> 显示 false
是不是很简单?这一节仅仅是告诉读者又这么一种方法,这种方法是这样运用的。
2、已有方法的实现和增强,初识 prototype:
(1) Array.push(new_element)
  作用:在数组末尾加入一个新的元素
  实现方法:
  Array.prototype.push = function(new_element){
this[this.length]=new_element;
return this.length;
}
  让我们进一步来增强他,让他可以一次增加多个元素!
  实现方法:
  
Array.prototype.pushPro = function() {
var currentLength = this.length;
for (var i = 0; i < arguments.length; i++) {
this[currentLength + i] = arguments[i];
}
return this.length;
}
  应该不难看懂吧?以此类推,你可以考虑一下如何通过增强 Array.pop 来实现删除任意位置,任意多个元素(具体代码就不再细说了)
(2) String.length
  作用:这实际上是 String 类的一个属性,但是由于 JavaScript 将全角、半角均视为是一个字符,在一些实际运用中可能会造成一定的问题,现在我们通过 prototype 来弥补这部不足。
  实现方法:
  String.prototype.cnLength = function(){
var arr=this.match(/[^\x00-\xff]/ig);
return this.length+(arr==null?0:arr.length);
}
  试验:alert("EaseWe空间Spaces".cnLength()) -> 显示 16
  这里用到了一些正则表达式的方法和全角字符的编码原理,由于属于另两个比较大的类别,本文不加说明,请参考相关材料。
3、新功能的实现,深入 prototype:在实际编程中所用到的肯定不只是已有方法的增强,更多的实行的功能的要求,
下面我就举两个用 prototype 解决实际问题的例子:
(1) String.left()
  问题:用过 vb 的应该都知道left函数,从字符串左边取 n 个字符,但是不足是将全角、半角均视为是一个字符,
造成在中英文混排的版面中不能截取等长的字符串
  作用:从字符串左边截取 n 个字符,并支持全角半角字符的区分
  实现方法:
  String.prototype.left = function(num,mode){
if(!/\d+/.test(num))return(this);
var str = this.substr(0,num);
if(!mode) return str;
var n = str.Tlength() - str.length;
num = num - parseInt(n/2);
return this.substr(0,num);
}
  试验:
alert("EaseWe空间Spaces".left(8)) -> 显示 EaseWe空间
alert("EaseWe空间Spaces".left(8,true)) -> 显示 EaseWe空
  本方法用到了上面所提到的String.Tlength()方法,自定义方法之间也能组合出一些不错的新方法呀!
(2) Date.DayDiff()
  作用:计算出两个日期型变量的间隔时间(年、月、日、周)
  实现方法:
  Date.prototype.DayDiff = function(cDate,mode){
try{
cDate.getYear();
}catch(e){
return(0);
}
var base =60*60*24*1000;
var result = Math.abs(this - cDate);
switch(mode){
case "y":
result/=base*365;
break;
case "m":
result/=base*365/12;
break;
case "w":
result/=base*7;
break;
default:
result/=base;
break;
}
return(Math.floor(result));
}
  试验:alert((new Date()).DayDiff((new Date(2002,0,1)))) -> 显示 329
alert((new Date()).DayDiff((new Date(2002,0,1)),"m")) -> 显示 10
  当然,也可以进一步扩充,得出响应的小时、分钟,甚至是秒。
(3) Number.fact()
  作用:某一数字的阶乘
  实现方法:
  Number.prototype.fact=function(){
var num = Math.floor(this);
if(num<0)return NaN;
if(num==0 || num==1)
return 1;
else
return (num*(num-1).fact());
}
  试验:alert((4).fact()) -> 显示 24
  这个方法主要是说明了递归的方法在 prototype 方法中也是可行的!

Jquery是继prototype之后又一个优秀的Javascrīpt框架 -|yytcpt 发表于 2007-1-8 9:51:00


Jquery是继prototype之后又一个优秀的Javascrīpt框架。对prototype我使用不多,简单了解过。但使用上jquery之后,马上被她的优雅吸引住了。有人使用这样的一比喻来比较prototype和jquery:prototype就像Java,而jquery就像ruby.实际上我比较喜欢java(少接触Ruby 罢了)但是jquery的简单的实用的确有相当大的吸引力啊!在项目里我把jquery作为自已唯一的框架类包。使用其间也有一点点心得,其实这些心得,在jquery的文档上面也可能有讲,不过还是记下来,以备忘罢。


一,找到你了!
还记得$()这个东西吧?prototype还是DWR都使用了这个函数代替document.getElementById()。没错,jquery也跟风了。为达到document.getElementById()的目的,jquery是这样写的:

代码

var someElement = $("#myId");

看起来比其他两个框架的要多了一个#,好,看看下面的用法:
代码
$("div p");(1)
$("div.container")(2)
$("div #msg");(3)
$("table a",context);(4)


在prototype里看过这样的写法吗?第一行代码得到所有<-div>标签下的

元素。第二行代码得到class 为container的<-div>元素,第三行代码得到<-div>标签下面id为msg的元素。第四行代码得到context为上下文的table里面所有的连接元素。
如果你熟悉CSS,Xpath,你会觉得这些写法很眼熟!对了。正是。看出奥妙了吧。jquery就是通过这样的方式来找到Dom对象里面的元素。跟CSS的选择器相类似。

二,Jquery对象?
jquery提供了很多便利的函数,如each(fn),但是使用这些函数的前提是:你使用的对象是Jquer对象。使一个Dom对象成为一个Jquery对象很简单,通过下面一些方式(只是一部分):

代码



var a = $("#cid");(1)
var b = $("

hello

");(2)
var c = document.createElement("table"); var tb = $(c);

三,代替body标签的onload
这个惯例,也许是除了$()之外,用得最多的地方了。下面一段代码:

代码



$(document).ready(function(){
alert("hello");
});(1)

<-body onload="alert('hello');">(2)


上面两段代码是等价的。但代码1的好处是做到表现和逻辑分离。并且可以在不同的js文件中做相同的操作,即$(document).ready (fn)可以在一个页面中重复出现,而不会冲突。基本上Jqeury的很多plugin都是利用这个特性,正因为这个特性,多个plugin共同使用起来,在初始化时不会发生冲突。
不管怎么说,这个惯例可以分离javascrīpt与HTML。推荐使用。

四,事件机制
我大量使用的事件可能就是button的onclick了。以前习惯在input 元素上写onclick = "fn()",使用jquery可以使javascrīpt代码与html代码分离,保持HTML的清洁,还可以很轻松地绑定事件,甚至你可以不知道“事件”这个名词。

代码



$(document).ready(function(){
$("#clear").click(function(){
alert("i am about to clear the table");
});
$("form[0]").submit(validate);
});
function validate(){
//do some form validation
}


五,同一函数实现set&get

代码



$("#msg").html();
$("#msg").html("hello");

上面两行代码,调用了同样的函数。但结果却差别很大。
第一行是返回指定元素的HTML值,第二行则是将hello这串字符设置到指定元素中。jquery的函数大部分有这样的特性。

六,ajax
这是一个ajax横行的时代。多少人,了不了解ajax的都跟着用上一把。呵。使用jquery实现ajax同样简单异常

代码



$.get("search.do",{id:1},rend);
function rend(xml){
alert(xml);
} (1)
$.post("search.do",{id:1},rend);
function rend(xml){
alert(xml);
} (2)

$("#msg").ajaxStart(function(){
this.html("正在加载。。。。");
});(3)
$("#msg").ajaxSuccess(function(){
this.html("加载完成!");
});(4)

这些都是较常用的方法,get和post用法一样。第一个参数是异步请求的url,第二个为参数,第三个回调方法。
3,4的方法会在指定的Dom对象上绑定响应ajax执行的事件。当然,jquery的AJAX相关的函数不仅是这些,有兴趣可以去研究再多。

七,渐入淡出

代码

$("#msg").fadeIn("fast");
$("#msg").fadeOut("slow");

没错,上面两行代码已经分别实现了一个id为Msg的jquery对象的渐入和淡出。做一个像Gmail一样的动态加载通知条,用jquery就那么简单。两个函数接受的参数除了快慢等,还可以接收整型,作为渐入或淡出的完成时间,单位为MS。

八,plugin
这也是一个插件的时代。
jquery插件给我的感觉清一色的清洁,简单。如Jtip,要使用它的功能,只需要在你的元素的class上加上Jtip,并引入jtip.js及其样式即可以了。其他事情插件全包。我喜欢jquery的一个重要原因是发现她已经有了很多很好,很精彩的插件。
写得很烂。可能大家看不出jquery的好处。嗯,光听是没用的,试用一下吧。你会发觉很有趣。
暂时告一段落吧。待有新的发现再来分享。

加一些Jquery的资源:
http://www.visualjquery.com/index.xml 很好的API查询站点
http://jquery.com/demo/thickbox/ 知道lightBox吧,看看Jquery是怎样实现相同的东西
http://www.codylindley.com/blogstuff/js/jtip/ Jtip,实用的提示工具
http://jquery.com/plugins/ 很多牛的插件。
http://15daysofjquery.com/jquery 的15天教程

createElement2

觉得只用insertAdjacentElement比较复杂,就又写了一个


var i=1;
var j=1;

var m=0;

function add(name,postion)
{
if(name=="file"){
m=i;
i++;
}else{
m=j;
j++;
}


var oInputdiv=document.createElement("div");
oInputdiv.id='div'+name+m;
var oInputfile=document.createElement('');
var oInputdel=document.createElement('');
var oInputtext0=document.createTextNode("上报国办:");
var oInputtext1=document.createTextNode("转发专家:");
var oInputtext2=document.createTextNode("通报领导:");

//id用于oInput1删除,name用于controller识别,value用于controller读取
var oInputcheckbox0=document.createElement('');
var oInputcheckbox1=document.createElement('');
var oInputcheckbox2=document.createElement('');

document.getElementById(postion).insertAdjacentElement('AfterEnd',oInputdiv);
document.getElementById('div'+name+m).appendChild(oInputfile);

document.getElementById('div'+name+m).appendChild(oInputtext0);
document.getElementById('div'+name+m).appendChild(oInputcheckbox0);
document.getElementById('div'+name+m).appendChild(oInputtext1);
document.getElementById('div'+name+m).appendChild(oInputcheckbox1);
document.getElementById('div'+name+m).appendChild(oInputtext2);
document.getElementById('div'+name+m).appendChild(oInputcheckbox2);
document.getElementById('div'+name+m).appendChild(oInputdel);

}

function del(id)
{
id.removeNode(true);
}



显然用节点appendChild更方便。

createElement2

觉得只用insertAdjacentElement比较复杂,就又写了一个


var i=1;
var j=1;

var m=0;

function add(name,postion)
{
if(name=="file"){
m=i;
i++;
}else{
m=j;
j++;
}


var oInputdiv=document.createElement("div");
oInputdiv.id='div'+name+m;
var oInputfile=document.createElement('');
var oInputdel=document.createElement('');
var oInputtext0=document.createTextNode("上报国办:");
var oInputtext1=document.createTextNode("转发专家:");
var oInputtext2=document.createTextNode("通报领导:");

//id用于oInput1删除,name用于controller识别,value用于controller读取
var oInputcheckbox0=document.createElement('');
var oInputcheckbox1=document.createElement('');
var oInputcheckbox2=document.createElement('');

document.getElementById(postion).insertAdjacentElement('AfterEnd',oInputdiv);
document.getElementById('div'+name+m).appendChild(oInputfile);

document.getElementById('div'+name+m).appendChild(oInputtext0);
document.getElementById('div'+name+m).appendChild(oInputcheckbox0);
document.getElementById('div'+name+m).appendChild(oInputtext1);
document.getElementById('div'+name+m).appendChild(oInputcheckbox1);
document.getElementById('div'+name+m).appendChild(oInputtext2);
document.getElementById('div'+name+m).appendChild(oInputcheckbox2);
document.getElementById('div'+name+m).appendChild(oInputdel);

}

function del(id)
{
id.removeNode(true);
}



显然用节点appendChild更方便。

createElement

做了一个insertAdjacentElement的方法,以便controller能够读得到file中的路径。

var i=1;
var j=1;

var m=0;

function add(name,postion)
{
if(name=="file"){
m=i;
i++;
}else{
m=j;
j++;
}
if(name=="file"){
m=i;
i++;
}else{
m=j;
j++;
}
var oInput=document.createElement('《input type="file" name="'+name+m+'" id="file" size="10">');
var oInput1=document.createElement('《input type="button" name="del'+i+'" onclick="del('+name+m+'),del(this),del('+name+'shangbao'+m+'),del('+name+'zhuanfa'+m+'),del('+name+'tongbao'+m+'),del('+name+'div_shangbao'+m+'),del('+name+'div_zhuanfa'+m+'),del('+name+'div_tongbao'+m+')" value="删除" class="css_button">');
//id用于oInput1删除,name用于controller识别,value用于controller读取
var oInputcheckbox=document.createElement('《input type=" checkbox" id="'+name+'shangbao'+m+'" name="'+name+'_Shangbao" value="'+name+m+'">');
var oInputcheckbox1=document.createElement('《input type="checkbox" id="'+name+'zhuanfa'+m+'" name="'+name+'_Zhuanfa" value="'+name+m+'">');
var oInputcheckbox2=document.createElement('《input type="checkbox" id="'+name+'tongbao'+m+'" name="'+name+'_Tongbao" value="'+name+m+'">');

var oInputdiv=document.createElement("div");
oInputdiv.id=name+'div_shangbao'+m;
oInputdiv.innerHTML="上报国办";
var oInputdiv1=document.createElement("div");
oInputdiv1.id=name+'div_zhuanfa'+m;
oInputdiv1.innerHTML="转发专家";
var oInputdiv2=document.createElement("div");
oInputdiv2.id=name+'div_tongbao'+m;
oInputdiv2.innerHTML="通报领导";



document.getElementById(postion).insertAdjacentElement('AfterEnd',oInputcheckbox2);
document.getElementById(postion).insertAdjacentElement('AfterEnd',oInputdiv2);

document.getElementById(postion).insertAdjacentElement('AfterEnd',oInputcheckbox1);
document.getElementById(postion).insertAdjacentElement('AfterEnd',oInputdiv1);

document.getElementById(postion).insertAdjacentElement('AfterEnd',oInputcheckbox);
document.getElementById(postion).insertAdjacentElement('AfterEnd',oInputdiv);
document.getElementById(postion).insertAdjacentElement('AfterEnd',oInput1);
document.getElementById(postion).insertAdjacentElement('AfterEnd',oInput);
}

1 SQL语句中怎么去掉字段内容右边的空格? SQL SERVER中的是RTRIM( ),ORACLE中呢?
-------------
用法差不多:
SQL> select ltrim(' dfs'),rtrim('dfsdf '),trim(' df df '),ltrim('1112121','1') from dual;

LTRIM('DFS') RTRIM('DFSDF') TRIM('DFDF') LTRIM('1112121','1')
------------ -------------- ------------ --------------------
dfs dfsdf df df 2121

2 SQL SERVER中截取字段内容内容,例如SUBSTRING( fieldname, 1, 2),ORACLE中怎么做?
-------------
用法一样,函数名是substr( fieldname, 1, 2)

3 SQL SERVER中比较日期 select * from table where fieldname>'2005-01-01' ,ORACLE中这样写不行,该怎么写呢?

fieldname是date类型的话,select * from table where fieldname> date '2005-01-01'或者
select * from table where fieldname>to_date('2005-01-01','yyyy-mm-dd')







declare @a varchar(8000)
set @a='aaaa bbb'
select left(@a,charindex(' ',@a)-1)
---测试----
aaaa





declare
i integer:=1;
j integer:=1;
k integer:=1;
cursor c1 is
select t.id,replace(t.name,' ')as realname from bjpuserinfo t where t.name like '% %' and t.accounttype='qiye';
begin
for rec in c1 loop
update bjpuserinfo set name=rec.realname where id=rec.id;
update awardarchive set qiyename=rec.realname where qiyeid=rec.id;
update qiyeinfo set unitname=rec.realname where id=rec.id;
end loop;
end;


正则表达式语法

下面是正则表达式的一些示例:

表达式 匹配
/^\s*$/ 匹配空行。
/\d{2}-\d{5}/ 验证由两位数字、一个连字符再加 5 位数字组成的 ID 号。
/<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\1\s*>/ 匹配 HTML 标记。

下表包含了元字符的完整列表以及它们在正则表达式上下文中的行为:

字符 说明
\ 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,“n”匹配字符“n”。“\n”匹配换行符。序列“\\”匹配“\”,“\(”匹配“(”。
^ 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与“\n”或“\r”之后的位置匹配。
$ 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与“\n”或“\r”之前的位置匹配。
* 零次或多次匹配前面的字符或子表达式。例如,zo* 匹配“z”和“zoo”。* 等效于 {0,}。
+ 一次或多次匹配前面的字符或子表达式。例如,“zo+”与“zo”和“zoo”匹配,但与“z”不匹配。+ 等效于 {1,}。
? 零次或一次匹配前面的字符或子表达式。例如,“do(es)?”匹配“do”或“does”中的“do”。? 等效于 {0,1}。
{n} n 是非负整数。正好匹配 n 次。例如,“o{2}”与“Bob”中的“o”不匹配,但与“food”中的两个“o”匹配。
{n,} n 是非负整数。至少匹配 n 次。例如,“o{2,}”不匹配“Bob”中的“o”,而匹配“foooood”中的所有 o。'o{1,}' 等效于 'o+'。'o{0,}' 等效于 'o*'。
{n,m} mn 是非负整数,其中 n <= m。至少匹配 n 次,至多匹配 m 次。例如,“o{1,3}”匹配“fooooood”中的头三个 o。'o{0,1}' 等效于 'o?'。注意:您不能将空格插入逗号和数字之间。
? 当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是“非贪心的”。“非贪心的”模式匹配搜索到的、尽可能短的字符串,而默认的“贪心的”模式匹配搜索到的、尽可能长的字符串。例如,在字符串“oooo”中,“o+?”只匹配单个“o”,而“o+”匹配所有“o”。
. 匹配除“\n”之外的任何单个字符。若要匹配包括“\n”在内的任意字符,请使用诸如“[\s\S]”之类的模式。
(pattern) 匹配 pattern 并捕获该匹配的子表达式。可以使用 $0...$9 属性从结果“匹配”集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用“\(”或者“\)”。
(?:pattern) 匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用“或”字符 (|) 组合模式部件的情况很有用。例如,与“industry|industries”相比,“industr(?:y| ies)”是一个更加经济的表达式。
(?=pattern) 执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,“Windows (?=95| 98| NT| 2000)”与“Windows 2000”中的“Windows”匹配,但不与“Windows 3.1”中的“Windows”匹配。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。
(?!pattern) 执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,“Windows (?!95| 98| NT| 2000)”与“Windows 3.1”中的“Windows”匹配,但不与“Windows 2000”中的“Windows”匹配。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。
x| y xy 匹配。例如,“z| food”与“z”或“food”匹配。“(z| f)ood”与“zood”或“food”匹配。
[xyz] 字符集。匹配包含的任一字符。例如,“[abc]”匹配“plain”中的“a”。
[^xyz] 反向字符集。匹配未包含的任何字符。例如,“[^abc]”匹配“plain”中的“p”。
[a-z] 字符范围。匹配指定范围内的任何字符。例如,“[a-z]”匹配“a”到“z”范围内的任何小写字母。
[^a-z] 反向范围字符。匹配不在指定的范围内的任何字符。例如,“[^a-z]”匹配任何不在“a”到“z”范围内的任何字符。
\b 匹配一个字边界,即字与空格间的位置。例如,“er\b”匹配“never”中的“er”,但不匹配“verb”中的“er”。
\B 非字边界匹配。“er\B”匹配“verb”中的“er”,但不匹配“never”中的“er”。
\cx 匹配由 x 指示的控制字符。例如,\cM 匹配一个 Control-M 或回车符。x 的值必须在 A-Z 或 a-z 之间。如果不是这样,则假定 c 就是“c”字符本身。
\d 数字字符匹配。等效于 [0-9]。
\D 非数字字符匹配。等效于 [^0-9]。
\f 换页符匹配。等效于 \x0c 和 \cL。
\n 换行符匹配。等效于 \x0a 和 \cJ。
\r 匹配一个回车符。等效于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 制表符匹配。与 \x09 和 \cI 等效。
\v 垂直制表符匹配。与 \x0b 和 \cK 等效。
\w 匹配任何字类字符,包括下划线。与“[A-Za-z0-9_]”等效。
\W 任何非字字符匹配。与“[^A-Za-z0-9_]”等效。
\xn 匹配 n,此处的 n 是一个十六进制转义码。十六进制转义码必须正好是两位数长。例如,“\x41”匹配“A”。“\x041”与“\x04”&“1”等效。允许在正则表达式中使用 ASCII 代码。
\num 匹配 num,此处的 num 是一个正整数。到捕获匹配的反向引用。例如,“(.)\1”匹配两个连续的相同字符。
\n 标识一个八进制转义码或反向引用。如果 \n 前面至少有 n 个捕获子表达式,那么 n 是反向引用。否则,如果 n 是八进制数 (0-7),那么 n 是八进制转义码。
\nm 标识一个八进制转义码或反向引用。如果 \nm 前面至少有 nm 个捕获子表达式,那么 nm 是反向引用。如果 \nm 前面至少有 n 个捕获,那么 n 是反向引用,后面跟 m。如果前面的条件均不存在,那么当 n m 是八进制数 (0-7) 时,\nm 匹配八进制转义码 nm
\nml n 是八进制数 (0-3),ml 是八进制数 (0-7) 时,匹配八进制转义码 nml
\un 匹配 n,其中 n 是以四位十六进制数表示的 Unicode 字符。例如,\u00A9 匹配版权符号 (©)。

onpopup

/**//*
** ==================================================================================================
** 类名:CLASS_MSN_MESSAGE
** 功能:提供类似MSN消息框
** 示例:
---------------------------------------------------------------------------------------------------

var MSG = new CLASS_MSN_MESSAGE("aa",200,120,"短消息提示:","您有1封消息","今天请我吃饭哈");
MSG.show();

---------------------------------------------------------------------------------------------------
** 作者:ttyp
** 邮件:ttyp@21cn.com
** 日期:2005-3-18
** ==================================================================================================
**/


/**//*
* 消息构造
*/
function CLASS_MSN_MESSAGE(id,width,height,caption,title,message,target,action){
this.id = id;
this.title = title;
this.caption= caption;
this.message= message;
this.target = target;
this.action = action;
this.width = width?width:200;
this.height = height?height:120;
this.timeout= 150;
this.speed = 20;
this.step = 1;
this.right = screen.width -1;
this.bottom = screen.height;
this.left = this.right - this.width;
this.top = this.bottom - this.height;
this.timer = 0;
this.pause = false;
this.close = false;
this.autoHide = true;
}

/**//*
* 隐藏消息方法
*/
CLASS_MSN_MESSAGE.prototype.hide = function(){
if(this.onunload()){

var offset = this.height>this.bottom-this.top?this.height:this.bottom-this.top;
var me = this;

if(this.timer>0){
window.clearInterval(me.timer);
}

var fun = function(){
if(me.pause==false||me.close){
var x = me.left;
var y = 0;
var width = me.width;
var height = 0;
if(me.offset>0){
height = me.offset;
}

y = me.bottom - height;

if(y>=me.bottom){
window.clearInterval(me.timer);
me.Pop.hide();
} else {
me.offset = me.offset - me.step;
}
me.Pop.show(x,y,width,height);
}
}

this.timer = window.setInterval(fun,this.speed)
}
}

/**//*
* 消息卸载事件,可以重写
*/
CLASS_MSN_MESSAGE.prototype.onunload = function() {
return true;
}
/**//*
* 消息命令事件,要实现自己的连接,请重写它
*
*/
CLASS_MSN_MESSAGE.prototype.oncommand = function(){
//this.close = true;
this.hide();
window.open("http://www.baidu.com");

}
/**//*
* 消息显示方法
*/
CLASS_MSN_MESSAGE.prototype.show = function(){

var oPopup = window.createPopup(); //IE5.5+

this.Pop = oPopup;

var w = this.width;
var h = this.height;

var str = "

"
str += ""
str += ""
str += ""
str += ""
str += ""
str += ""
str += ""
str += ""
str += ""
str += "
" + this.caption + ""
str += "×
"
str += "
" + this.title + "

"
str += ""
str += "
"
str += "
"
str += "
"

oPopup.document.body.innerHTML = str;


this.offset = 0;
var me = this;

oPopup.document.body.onmouseover = function(){me.pause=true;}
oPopup.document.body.onmouseout = function(){me.pause=false;}

var fun = function(){
var x = me.left;
var y = 0;
var width = me.width;
var height = me.height;

if(me.offset>me.height){
height = me.height;
} else {
height = me.offset;
}

y = me.bottom - me.offset;
if(y<=me.top){
me.timeout--;
if(me.timeout==0){
window.clearInterval(me.timer);
if(me.autoHide){
me.hide();
}
}
} else {
me.offset = me.offset + me.step;
}
me.Pop.show(x,y,width,height);

}

this.timer = window.setInterval(fun,this.speed)



var btClose = oPopup.document.getElementById("btSysClose");

btClose.onclick = function(){
me.close = true;
me.hide();
}

var btCommand = oPopup.document.getElementById("btCommand");
btCommand.onclick = function(){
me.oncommand();
}
var ommand = oPopup.document.getElementById("ommand");
ommand.onclick = function(){
//this.close = true;
me.hide();
window.open(ommand.href);
}
}
/**//*
** 设置速度方法
**/
CLASS_MSN_MESSAGE.prototype.speed = function(s){
var t = 20;
try {
t = praseInt(s);
} catch(e){}
this.speed = t;
}
/**//*
** 设置步长方法
**/
CLASS_MSN_MESSAGE.prototype.step = function(s){
var t = 1;
try {
t = praseInt(s);
} catch(e){}
this.step = t;
}

CLASS_MSN_MESSAGE.prototype.rect = function(left,right,top,bottom){
try {
this.left = left !=null?left:this.right-this.width;
this.right = right !=null?right:this.left +this.width;
this.bottom = bottom!=null?(bottom>screen.height?screen.height:bottom):screen.height;
this.top = top !=null?top:this.bottom - this.height;
} catch(e){}
}
var MSG1 = new CLASS_MSN_MESSAGE("aa",200,120,"短消息提示:","您有1封消息","今天请我吃饭哈");
MSG1.rect(null,null,null,screen.height-50);
//MSG1.speed = 10;
//MSG1.step = 5;
//alert(MSG1.top);
MSG1.show();

//同时两个有闪烁,只能用层代替了,不过层不跨框架
//var MSG2 = new CLASS_MSN_MESSAGE("aa",200,120,"短消息提示:","您有2封消息","好的啊");
//MSG2.rect(100,null,null,screen.height);
//MSG2.show();

今天要在javascript中将一个字符串里的所有的'!@#$',替换成',',结果发现只能替换掉一个,后来查了一下才回忆起来javascript中的replace只能替换掉第一个匹配项。

网上提供的方法主要有两种,一种为通过indexof查看是否还存在匹配项,然后写循环替换,这样也很好。

更好的方案是通过写正则表达式来解决这个问题,replace(/要匹配的字符串/g,要替换的字符串)

网上的帖子大都是互相转载的,居的例子都是一个replace(/\-/g,'!'),但是如果要匹配的字符串长度大于1,究竟怎样写呢。

其实很简单,如果需要匹配的字符串只是字母一类的,例如abcde,那就可以直接replace(/abcde/g,'!')

如果含有特殊字符,需要在特殊字符前面转义(在字符前面加上\),当然每个字符都转义也可以的。例如!@#$,就可以这样写replace(/\!\@\#\$/g,',')


http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#getstarted

《A HREF="PageName.htm" onclick="javascript:location.replace(this.href); event.returnValue=false; "》

1.CSS将从基础开始建设直到全面替代传统web设计方法。W3C组织创建的CSS技术将替代HTML的表格、font标签、frames以及其它用于表现的HTML元素。

  2.提高页面浏览速度。使用CSS方法,比传统的web设计方法至少节约50%以上的文件尺寸。

  3.缩短改版时间。只要简单的修改几个CSS文件就可以重新设计一个有成百上千页面的站点。

  4.强大的字体控制和排版能力。CSS控制字体的能力比糟糕的FONT标签好多了,有了CSS,我们不再需要用FONT标签或者透明的1 px GIF图片来控制标题,改变字体颜色,字体样式等等。

  5.CSS非常容易编写。你可以象写html代码一样轻松地编写CSS。

  6.提高易用性。使用CSS可以结构化HTML,例如:

标签只用来控制段落,heading标签只用来控制标题,table标签只用来表现格式化的数据等等。你可以增加更多的用户而不需要建立独立的版本。

  7.可以一次设计,随处发布。你的设计不仅仅用于web浏览器,也可以发布在其他设备上,比如PowerPoint。

  8.更好的控制页面布局。不用多说。

  9.表现和内容相分离。将设计部分剥离出来放在一个独立样式文件中,你可以减少未来网页无效的可能。

  10.更方便搜索引擎的搜索。用只包含结构化内容的HTML代替嵌套的标签,搜索引擎将更有效地搜索到你的内容,并可能给你一个较高的评价(ranking)。

  作者:克里斯多佛 主页 http://www.christopherschmitt.com/

indexOf方法:

返回 String 对象内第一次出现子字符串的字符位置。

strObj.indexOf(subString[, startIndex])
参数
strObj
必选项。String 对象或文字。
subString
必选项。要在 String 对象中查找的子字符串。
starIndex
可选项。该整数值指出在 String 对象内开始查找的索引。如果省略,则从字符串的开始处查找。
说明
indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置。如果没有找到子字符串,则返回 -1。

如果 startindex 是负数,则 startindex 被当作零。如果它比最大的字符位置索引还大,则它被当作最大的可能索引。

从左向右执行查找。否则,该方法与 lastIndexOf 相同。

示例
下面的示例说明了 indexOf 方法的用法。

程序代码 程序代码
function IndexDemo(str2){
var str1 = "BABEBIBOBUBABEBIBOBU"
var s = str1.indexOf(str2);
return(s);
}


lastIndexOf 方法:

返回 String 对象中子字符串最后出现的位置。

strObj.lastIndexOf(substring[, startindex])
参数
strObj
必选项。String 对象或文字。
substring
必选项。要在 String 对象内查找的子字符串。
startindex
可选项。该整数值指出在 String 对象内进行查找的开始索引位置。如果省略,则查找从字符串的末尾开始。
说明
lastIndexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置。如果没有找到子字符串,则返回 -1。

如果 startindex 是负数,则 startindex 被当作零。如果它比最大字符位置索引还大,则它被当作最大的可能索引。

从右向左执行查找。否则,该方法和 indexOf 相同。

下面的示例说明了 lastIndexOf 方法的用法:

程序代码 程序代码
function lastIndexDemo(str2)
{
var str1 = "BABEBIBOBUBABEBIBOBU"
var s = str1.lastIndexOf(str2);
return(s);
}


substring 方法:

返回位于 String 对象中指定位置的子字符串。

程序代码 程序代码
strVariable.substring(start, end)
"String Literal".substring(start, end)


参数

start
指明子字符串的起始位置,该索引从 0 开始起算。
end
指明子字符串的结束位置,该索引从 0 开始起算。
说明

substring 方法将返回一个包含从 start 到最后(不包含 end )的子字符串的字符串。

substring 方法使用 start 和 end 两者中的较小值作为子字符串的起始点。例如, strvar.substring(0, 3) 和 strvar.substring(3, 0) 将返回相同的子字符串。

如果 start 或 end 为 NaN 或者负数,那么将其替换为0。

子字符串的长度等于 start 和 end 之差的绝对值。例如,在 strvar.substring(0, 3) 和 strvar.substring(3, 0) 返回的子字符串的的长度是 3。

示例
下面的示例演示了 substring 方法的用法。

程序代码 程序代码
function SubstringDemo(){
var ss; // 声明变量。
var s = "The rain in Spain falls mainly in the plain..";
ss = s.substring(12, 17); // 取子字符串。
return(ss); // 返回子字符串。
}

〈script>
function toBreakWord(intLen){
var obj=document.getElementById("strT");
var strContent=obj.innerHTML;
var strTemp="";
while(strContent.length>intLen){
strTemp+=strContent.substr(0,intLen)+"〈br>";
strContent=strContent.substr(intLen,strContent.length);
}
strTemp+=strContent;
obj.innerHTML=strTemp;
}
〈/script>

〈div id=strT>要控制的字符串。。。。〈/div>

〈script>
if(document.getElementById &&amp;amp;amp; !document.all) toBreakWord(54);//每行54个字符换行
〈/script>

 
Copyright 2005-2007. Hello Wiki designed by Fen, Blogger Templates by Blogcrowds.