??xml version="1.0" encoding="utf-8" standalone="yes"?>
help => Software Updates => Find and Install... => Search for new features to install,单击"New Remote Site..." 在URL栏输?http://www.technoetic.com/eclipse/update
安装好后可以看到Window => Preferences... => Java => Jode Decompiler选项卡?
配置QWindow => Preferences... => General => Editors => File Associations扑ֈ"*.class"?Associated editors"里面可以看到"Jode class file viewer"选中它再单击Default按钮.
在Eclipse中展开jar文g,双击class文g卛_看到反编译之后的源代?
]]>
一 clientX和clientY
讄或接收相对于览器窗口客户区的鼠标x、y坐标Q客户区不包括窗口滚动条及边?
大小(MSDN原文:Sets or retrieves the x-coordinate/y-coordinate of the mouse
pointer's position relative to the client area of the window, excluding
window decorations and scroll bars.)
在IE4里,q一对属性只M可写QIE5及以后版本里则可d?MSDN原文:The
property is read-only in Microsoft® Internet Explorer 4.0, and read/write
in Microsoft® Internet Explorer 5 and later.)
语法: event.clientX=[iPos] event.clientY=[iPos] iPos应该是一个整?
? screenX和screenY
讄或接收相对于用户屏幕的鼠标坐?
在IE4里,q一对属性只M可写QIE5及以后版本里则可d?
语法: event.screenX=[iSize] event.screenY=[iSize] iSize应该是一个整?
? offsetX和offsetY
讄或接攉标指针在鼠标所在的元素上的偏移?
在IE4里,q一对属性只M可写QIE5及以后版本里则可d?
语法: event.screenX=[iCoord] event.screenY=[iCoord] iCoord应该是一个整?
? x和y
讄或接收相对于鼠标所在的元素的父元素的坐?MSDN原文:Sets or retrieves
the x-coordinate, in pixels, of the mouse pointer's position relative to
the parent element.)
在IE4里,q一对属性只M可写QIE5及以后版本里则可d?但IE5以前的版式本?
x和y坐标q不相对于鼠标所在的元素的父元素Q只相对于浏览器H口的客户区
如果在检鼠标位|时Q鼠标却在浏览器H口的外面,则x和y都返?1
]]>
使用FileSystemObject 对象q行~程很简单,一般要l过如下的步骤: 创徏FileSystemObject对象、应用相x法、访问对象相兛_??
Q一Q创建FileSystemObject对象
创徏FileSystemObject对象的代码只?行:
var fso = new ActiveXObject("Scripting.FileSystemObject");
上述代码执行后,fso成Z个FileSystemObject对象实例?
Q二Q应用相x?
创徏对象实例后,可以用对象的相关Ҏ了。比如,使用CreateTextFileҎ创徏一个文本文Ӟ
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f1 = fso.createtextfile("c:\\myjstest.txt",true");
Q三Q访问对象相兛_?
要访问对象的相关属性,首先要徏立指向对象的句柄Q这p通过getpdҎ实现QGetDrive负责获取驱动器信息,GetFolder负责获取文g夹信息,GetFile负责获取文g信息。比如,指向下面的代码后Qf1成为指向文件c:\test.txt的句柄:
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f1 = fso.GetFile("c:\\myjstest.txt");
然后Q用f1讉K对象的相兛_性。比如:
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f1 = fso.GetFile("c:\\myjstest.txt");
alert("File last modified: " + f1.DateLastModified);
执行上面最后一句后Q将昄c:\myjstest.txt的最后修Ҏ期属性倹{?
但有一点请注意Q对于用createҎ建立的对象,׃必再使用getҎ获取对象句柄了,q时直接使用createҎ建立的句柄名U就可以Q?
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f1 = fso.createtextfile("c:\\myjstest.txt",true");
alert("File last modified: " + f1.DateLastModified);
三、操作驱动器QDrivesQ?
使用FileSystemObject对象来编E操作驱动器QDrivesQ和文g夹(FoldersQ很ҎQ这p在Windows文g览器中Ҏ件进行交互操作一P比如Q拷贝、移动文件夹Q获取文件夹的属性?
Q一QDrives对象属?
Drive对象负责攉pȝ中的物理或逻辑驱动器资源内容,它具有如下属性:
l TotalSizeQ以字节QbyteQؓ单位计算的驱动器大小?
l AvailableSpace或FreeSpaceQ以字节QbyteQؓ单位计算的驱动器可用I间?
l DriveLetterQ驱动器字母?
l DriveTypeQ驱动器cdQ取gؓQremovableQ移动介质)、fixedQ固定介质)、networkQ网l资源)、CD-ROM或者RAM盘?
l SerialNumberQ驱动器的系列码?
l FileSystemQ所在驱动器的文件系l类型,取gؓFAT、FAT32和NTFS?
l IsReadyQ驱动器是否可用?
l ShareNameQ共享名U?
l VolumeNameQ卷标名U?
l Path和RootFolderQ驱动器的\径或者根目录名称?
Q二QDrive对象操作例程
下面的例E显C驱动器C的卷标、d量和可用I间{信息:
var fso, drv, s ="";
fso = new ActiveXObject("Scripting.FileSystemObject");
drv = fso.GetDrive(fso.GetDriveName("c:\\"));
s += "Drive C:" + " - ";
s += drv.VolumeName + "\n";
s += "Total Space: " + drv.TotalSize / 1024;
s += " Kb" + "\n";
s += "Free Space: " + drv.FreeSpace / 1024;
s += " Kb" + "\n";
alert(s);
四、操作文件夹QFoldersQ?
涉及到文件夹的操作包括创建、移动、删除以及获取相兛_性?
Folder对象操作例程 :
下面的例E将l习获取父文件夹名称、创建文件夹、删除文件夹、判断是否ؓ根目录等操作Q?
var fso, fldr, s = "";
// 创徏FileSystemObject对象实例
fso = new ActiveXObject("Scripting.FileSystemObject");
// 获取Drive 对象
fldr = fso.GetFolder("c:\\");
// 昄父目录名U?
alert("Parent folder name is: " + fldr + "\n");
// 昄所在drive名称
alert("Contained on drive " + fldr.Drive + "\n");
// 判断是否为根目录
if (fldr.IsRootFolder)
alert("This is the root folder.");
else
alert("This folder isn't a root folder.");
alert("\n\n");
// 创徏新文件夹
fso.CreateFolder ("C:\\Bogus");
alert("Created folder C:\\Bogus" + "\n");
// 昄文g夹基名称Q不包含路径?
alert("Basename = " + fso.GetBaseName("c:\\bogus") + "\n");
// 删除创徏的文件夹
fso.DeleteFolder ("C:\\Bogus");
alert("Deleted folder C:\\Bogus" + "\n");
五、操作文ӞFilesQ?
Ҏ件进行的操作要比以上介绍的驱动器QDriveQ和文g夹(FolderQ操作复杂些Q基本上分ؓ以下两个cdQ对文g的创建、拷贝、移动、删除操作和Ҏ件内容的创徏、添加、删除和d操作。下面分别详l介l?
Q一Q创建文?
一共有3U方法可用于创徏一个空文本文gQ这U文件有时候也叫做文本(text streamQ?
W一U是使用CreateTextFileҎ。代码如下:
var fso, f1;
fso = new ActiveXObject("Scripting.FileSystemObject");
f1 = fso.CreateTextFile("c:\\testfile.txt", true);
W二U是使用OpenTextFileҎQƈd上ForWriting属性,ForWriting的gؓ2。代码如下:
var fso, ts;
var ForWriting= 2;
fso = new ActiveXObject("Scripting.FileSystemObject");
ts = fso.OpenTextFile("c:\\test.txt", ForWriting, true);
W三U是使用OpenAsTextStreamҎQ同栯讄好ForWriting属性。代码如下:
var fso, f1, ts;
var ForWriting = 2;
fso = new ActiveXObject("Scripting.FileSystemObject");
fso.CreateTextFile ("c:\\test1.txt");
f1 = fso.GetFile("c:\\test1.txt");
ts = f1.OpenAsTextStream(ForWriting, true);
Q二Q添加数据到文g
当文件被创徏后,一般要按照“打开文gQ?gt;填写数据Q?gt;关闭文g”的步骤实现添加数据到文g的目的?
打开文g可用FileSystemObject对象的OpenTextFileҎQ或者用File对象的OpenAsTextStreamҎ?
填写数据要用到TextStream对象的Write、WriteLine或者WriteBlankLinesҎ。在同是实现写入数据的功能下Q这3者的区别在于QWriteҎ不在写入数据末尾d新换行符QWriteLineҎ要在最后添加一个新换行W,而WriteBlankLines则增加一个或者多个空行?
关闭文g可用TextStream对象的CloseҎ?
Q三Q创建文件及d数据例程
下面的代码将创徏文g、添加数据、关闭文件几个步骤结合v来进行应用:
var fso, tf;
fso = new ActiveXObject("Scripting.FileSystemObject");
// 创徏新文?
tf = fso.CreateTextFile("c:\\testfile.txt", true);
// 填写数据Qƈ增加换行W?
tf.WriteLine("Testing 1, 2, 3.") ;
// 增加3个空?
tf.WriteBlankLines(3) ;
// 填写一行,不带换行W?
tf.Write ("This is a test.");
// 关闭文g
tf.Close();
Q四Q读取文件内?
从文本文件中d数据要用TextStream对象的Read、ReadLine或ReadAll Ҏ。ReadҎ用于d文g中指定数量的字符QReadLineҎd一整行Q但不包括换行符QReadAllҎ则读取文本文件的整个内容。读取的内容存放于字W串变量中,用于昄、分析。在使用Read或ReadLineҎd文g内容Ӟ如果要蟩q一些部分,p用到Skip或SkipLineҎ?
下面的代码演C打开文g、填写数据,然后d数据Q?
var fso, f1, ts, s;
var ForReading = 1;
fso = new ActiveXObject("Scripting.FileSystemObject");
// 创徏文g
f1 = fso.CreateTextFile("c:\\testfile.txt", true);
// 填写一行数?
f1.WriteLine("Hello World");
f1.WriteBlankLines(1);
// 关闭文g
f1.Close();
// 打开文g
ts = fso.OpenTextFile("c:\\testfile.txt", ForReading);
// d文g一行内容到字符?
s = ts.ReadLine();
// 昄字符串信?
alert("File contents = '" + s + "'");
// 关闭文g
ts.Close();
Q五Q移动、拷贝和删除文g
对于以上三种文g操作Qjavascript各有两种对应的方法:File.Move ?FileSystemObject.MoveFile用于Ud文gQFile.Copy ?FileSystemObject.CopyFile用于拯文gQFile.Delete ?FileSystemObject.DeleteFile用于删除文g?
下面的代码演C在驱动器C的根目录下创Z个文本文Ӟ填写一些内容,然后文件移动到\tmp目录下,再在目录\temp下面建立一个文件拷贝,最后删除这两个目录的文Ӟ
var fso, f1, f2, s;
fso = new ActiveXObject("Scripting.FileSystemObject");
f1 = fso.CreateTextFile("c:\\testfile.txt", true);
// 写一?
f1.Write("This is a test.");
// 关闭文g
f1.Close();
// 获取C:\根目录下的文件句?
f2 = fso.GetFile("c:\\testfile.txt");
// Ud文g到\tmp目录?
f2.Move ("c:\\tmp\\testfile.txt");
// 拯文g到\temp目录?
f2.Copy ("c:\\temp\\testfile.txt");
// 获取文g句柄
f2 = fso.GetFile("c:\\tmp\\testfile.txt");
f3 = fso.GetFile("c:\\temp\\testfile.txt");
// 删除文g
f2.Delete();
f3.Delete();
六、结 ?
通过以上对FileSystemObject的各U对象、属性和Ҏ的介l和CZQ相信你已经对如何用javascript语言在页面中操作驱动器、文件和文gҎ了清晰的认识。但是上q提及的例程都非常简单,要全面、灵zd掌握javascript文g操作技术,q需要大量的实践l习。而且q有一Ҏ醒大Ӟ׃涉及到在览器中q行文gdq样的高U操作,对于默认的浏览器安全U别而言Q在代码q行前都会有一个信息提C,q点请在实际环境中提C问者注意?
]]>
再看一下TextField中的rewindFormComponentlgҎ
可以看到在rewindFormComponent中,主要是从h中取得用戯入的|然后q行处理Q最后赋值给容器或者页面,上面的例子中会调用页面类的getPicture().setPrice(“用户输入的?#8221;)来进行赋倹{这h个表单的提交可以理解ؓ所有的表单lgd用户输入的值ƈ赋值给面的过E?
整个表单提交的详l处理过E如下:
* initialize():面初始?
我们可以看到pageBeginRender和pageEndRender被调用了两次Q两ơ中的区别ؓRequestCycle().isRewindingQ因为我们在使用时经常利用pageBeginRender的初始化|所以这里有很多使用上的误区Q如果在pageBeginRender中从数据库读取数据来初始化跟表单提交无关的变量的话,可能被调用两次Q这个是应该避免的。什么叫跟表单提交无关的变量呢,是表单lg中跟赋值无关的Q例如上Ҏ到的value="ognl:picture.price",q时picture是与表单提交相关的变量Q如果你没有初始化,那么在赋值时调用getPicture().setPrice()׃出现I指针异常,因ؓq是的picture为null。我们D个例子来看一下表单无关的变量Q假如这个picture面会显CZ个创建picture的表单和所有picture的列表,那这个picture的列表就是与表单提交无关的变量,如果你在pageBeginRender中初始化的话Q就需要区分是否rewindQ否则表单提交时׃被初始化两次Q让我们看一下代码:
* pageBeginRender() ("rewind"):getRequestCycle().isRewinding()为true
* rewind of the form / setting of properties:所有表单组件调用rewindFormComponent来取D?
* Deferred listeners (for Submit components):调用Submitlg的listener
* Form's listenerQ调用Formlg的listener
* pageEndRender() ("rewind"): getRequestCycle().isRewinding()为true
* pageBeginRender() (normal): getRequestCycle().isRewinding()为false
* pageEndRender() (normal): getRequestCycle().isRewinding()为false
原文地址Qhttp://www.javaeye.com/article/41724
]]>
package util;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.convert.Converter;
import javax.faces.context.FacesContext;
import javax.faces.convert.ConverterException;
public class StringConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component,
String newValues) throws ConverterException {
String newstr = "";
if (newValues == null) {
newValues = "";
}
byte[] byte1 = null;
try {
byte1 = newValues.getBytes("ISO-8859-1");
newstr = new String(byte1, "GB2312");
UIInput input=(UIInput)component;//
input.setSubmittedValue(newstr);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return newstr;
}
public String getAsString(FacesContext context, UIComponent component,
Object Values) throws ConverterException {
return (String) Values;
}
}
2、注册{换器
faces-config.xml片段
<converter>
<converter-id>util.stringconverter</converter-id>
<converter-class>util.StringConverter</converter-class>
</converter>
3、在面使用转换?br />
<h:inputText id="account" value="#{util.account}" required="true" styleClass="input" >
<f:converter converterId="utilstringconverter"/>
* csr 文g的生成:
%Java_Home%\bin\keytool -certreq -alias localhost-weblogic -sigalg MD5withRSA -file ./testServer.csr -keystore ./testKey.jks
* 注意Q?http 的默认端口是80Qhttps 的默认端口是433Qftp 的默认端口是21?br />
2Q部|keystore 文g
?<http://hostname:7001/console> 中配|刚才生成的 testKey.jks 文g?/p>
1.1.2 Tomcat 下面SSL配置
1Q生?keystoreFileQ?br />
* keystoreFile 文g的生成:
%Java_Home%\bin\keytool -genkey -alias localhost-weblogic -keyalg RSA -validity 365 -keystore ./testKey.jks
Example for inner testQ?br />
[root@localhost ~]#
/home/tomcat/jdk1.5.0_12/bin/keytool -genkey -alias localhost-tomcat -keyalg RSA -validity 365 -keystore /home/tomcat/apache-tomcat-5.5.23/conf/VCMarketKey.jks
Enter keystore password: someday2007
What is your first and last name?
[Unknown]: lifenote
What is the name of your organizational unit?
[Unknown]: Java
What is the name of your organization?
[Unknown]: Sunxc
What is the name of your City or Locality?
[Unknown]: Beijing
What is the name of your State or Province?
[Unknown]: Beijing
What is the two-letter country code for this unit?
[Unknown]: ZH
Is CN=lifenote, OU=Java, O=Sunxc, L=Beijing, ST=Beijing, C=ZH correct?
[no]: y
Enter key password for <localhost-tomcat>
(RETURN if same as keystore password): someday2007
[root@localhost ~]#
* csr 文g的生成:
%Java_Home%\bin\keytool -certreq -alias localhost-weblogic -sigalg MD5withRSA -file ./testServer.csr -keystore ./testKey.jks
* 注意Q?http 的默认端口是80Qhttps 的默认端口是433Qftp 的默认端口是21?/p>
2Q部|keystore 文g
打开 server.xml 文gQ修改内容如下:
* 只需L server.xml 中对SSL定义的注释,在加?keystoreFile、keystorePass q两个属性即可?br />
<Service
name="Catalina">
<Connector
port="8080"
...
</Connector>
<!-- Define a SSL HTTP/1.1 Connector on port 8443 --------------------- 要加入的内容在这?-->
<Connector port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="e:/temp_E/ssl/testKey.jks"
keystorePass="aaaaaa"/>
<Connector
port="8009"
...
</Connector>
...
Example for inner testQ?br />
<Connector port="443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="/home/tomcat/apache-tomcat-5.5.23/conf/VCMarketKey.jks"
keystorePass="password"/>
注意需默认要?443 而不?8443Q要使用8443要在apache中配|,保证从apachehtomcat 采用 <https://ip:8443/>... 的格式?/p>
1.1.3 使用http讉KWebService s的客L配置
Servlet服务器配|好SSL之后Q客L可以使用https讉K了?br />
对于用户使用览器访问https的方式,览器会弹出安装证书的对话框Q确认之后可以正怋用https讉K?br />
对于WebService 通过https方式讉KQ按照一下步骤:
1Q?nbsp;WebService客户端要先取得keyStore文gQ?br />
2Q?nbsp;虚拟机系l?System.setProperties(…) 讄keyStore信息Q?br />
3Q?nbsp;使用 url=<https://ip:port/...> 讉KWebService服务
后面一个很Ҏ理解Q它{h于function f(){};定义一个函数f。但前面一个就不常见了Q这其实是创Z个对象,在{}中可以指定对象的成员Q比如上面的PrototypeQ就是一个对象,有两个成员,W一个是版本PW二个是一个空ҎQ函敎ͼ。像q种不用定义c,p直接创徏对象的功能可能只有js能做到。后面一U语法其实还有一个功能,是定义一个类f。如果你在函C中用了thisQ那么this后面的变量就是类的成员?br />
不仅this可以定义cL员,q有一U语法:
function c(){
member1:value,
member2:function(){}
}
q等价于:
function c(){
this.member1=value;
this.member2=function(){};
}
需要注意的是,用前一U办法时Q最后一个成员的最后不能加逗号Q我惌U语法应该和数组有关?br />
在js里,函数和类是没有区别的Q都可以newQnew的作用是把函C的语句都执行一遍,然后q回一个对象。如果函数里有thisQ那么this后面的变量会作ؓ对象成员Q如果没有,那么new的作用只是返回一个没有Q何成员的I对象。所以你用typeof查看一个所谓类的类型时Q仍然会q回function。在js里也基本没有cd的概念,所有变量的声明都用varQ即使是函数Q也是如此。函敎ͼ其实也只是一个变量?br />
说函数是变量Q可能很多h不解。但是你试试下面的做法:
function fTest(){
var a=1;
alert(a);
}
alert(fTest);
你会发现昄的是fTestq个函数的函CQ所以我们可以认为,所谓函敎ͼ仅仅是js引擎可以解析的一D代码字W串。函数名变量存储的只是这个字W串。说的更准确一点,函数名是一个指针变量,它存储的是这个代码字W串在内存中的位|。这样就不难理解函C为参C递,可以作ؓD回了Q这是以后会大量使用的技术。因为类也是函数Q所以理解了函数Q也q解了cR?br />
虽然在js里函数和cL有区别,但是cȝ概念却可以方便我们进行程序设计,于是prototype很有创意的创Z一个全局对象ClassQ?br />
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
Class是一个全局对象Q它的唯一Ҏ是createQ作用返回一个函敎ͼ前面已经讲过函数作ؓq回值的机制Q这里不再遨q。返回的函数包括一条语句:
this.initialize.apply(this, arguments);
前面讲过Qnew一个函数时Q会执行函数里的代码Q最后返回对象。所以当使用Class.create()创徏了一个函敎ͼ再newq个q回的函数时Q首先会执行q条语句。后面可以看刎ͼq其实是Z调用cȝ构造函数?br />
是q样QClass成ؓ了整个prototype的类型创建模型,q且能很好的把类和函数在代码上区分开来。Class.create()仅仅是返回一个空c,而且它会默认个类是具有initializeҎ的,所以要使用q个c,臛_需要有一个构造函敎ͼq就需要用到cȝl承。类只是一个函敎ͼ那么函数怎么l承呢?看v来匪h思,javascript能做到这一点,prototype使得实现更ؓ优雅Q至于它是怎么做到的,且听下回分解?br />
AJAX之旅(2)Qjavascript中类的深入研IӞ实现和?
上回说到了类的定义,prototype通过一个全局对象Class从Ş式上函数和cd别开来。既然是c,那么有抽象c,具体c,cȝl承Q同Ӟcȝ成员可以有实例成员和静态成员。下面来看一下prototype是怎么做到q些的?br />
先看prototype中的以下的代码:
var Abstract = new Object();
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}
W一个声明了一个对象AbstractQObject其实是一个函敎ͼ他没有Q何成员,所以是一个空c,所以Abstract也就没有M成员。这个暂时不_后面可以看到q是抽象cȝ基础。先解释以下q个语法Q?br />
function.member=function(){}
在这U情况下Qfunction一般都是已l定义过的,q条语句的作用是lfunction增加一个静态成员memberQmember的内Ҏ{号后面的。如上面W二D代码Object.extend=……Q就是给Objectq个cd加了一个静态方法extend。okQ我们知道了怎样l一个类定义静态成员,那么你一定很想知道实例成员怎么定义Q很单,在类名和成员名之间加上prototypeQ?
function.prototype.member=function(){}
prototype不仅可以q么使用Q还可以Q?
function.prototype={
member1:function(){……},
member2:"abc",
member3:function(){……}
}
q样是实现了实例成员的定义。但prototype代表什么意思呢Q在W一我说过Q直接用{}括v来,表示一个对象,如PrototypeQClass都是q样定义的全局对象。而看下面一U用法,prototype后面是一个{}的结构,N它也是对象?是的Q没错,prototype其实也是一个对象!在javascript里,一个对象我们可以Q意增加它的成员,用如下的语法Q?br />
object.member=function(){……};
只要l过q样的定义,一个对象就可以立刻hmemberq个ҎQjavascript是q么奇Q?br />
好,我们现在知道了prototype是一个对象,而function是一个函数或者类Q那么我们可以认为prototype是Q何一个类Q函敎ͼ都内部保留的一个静态成员。它的功能就是存储这个类的所有成员指针,但这些成员都只是原型Q没有经q初始化Q这也符合prototype的原义。你可以随时通过prototypeq个对象来扩充成员。在new一个类Ӟprototype的成员就l过初始化,然后赋给了实例化的对象?br />
上面W三D代码Object.prototype.extend=……Q就是给Object增加了一个实例方法extendQ实例方法中可以引用this指针Q指向由q个cd例化的对象本w。当Ӟq个对象具有成员extend?br />
l箋之前Q先了解一下两个语句:
for(var p in object){}
method.apply(object,arguments);
W一句:列DZ个变量的所有成员,如果是函敎ͼ那么是所有静态成员;如果是对象,那就是所有实例成员,p的类型是一个字W串。表C成员的名称。引用一个成员不仅可以用variabel.memberQ还可以用variabel["member"]。反q来Q赋g是如此。这q枚D一个变量的成员带来了很大方ѝ?br />
W二条语句:methodq个Ҏ应用到objectL行,参数是argumentsq个数组。注意:methodq不是object的成员。但是,我们可以认ؓq条语句执行的意思就是:object.method(arguments)。这是一个很重要的方法,后面会经常用刎ͼ你也会逐渐熟悉它的?br />
下面l箋extendQ它是一个非帔R要的ҎQ可以看到它既是cObject的静态成员,也是其实例成员,那它有什么作用呢Q让我们来看Q它接收两个参数Qdestination和sourceQ如果destination和source都是c,那么它的功能是把csource的所有静态成员都复制l类destinationQ如果destination和source都是对象Q那么是把所有实例成员都复制q来。这时destination中如果已l有同名成员Q那么这个成员将被覆盖。也是说让destinationh了source的所有成员,q且函数q回q个destination。下面看extend作ؓObject的实例成员:
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}
开始有Ҏ了,不过不要急,q是可以看懂的,apply语法刚刚已经讲过了,它的调用者是一个方法,而Object.extend是一个静态方法,它被应用到this上面Q也是Object的实例,假设为objQ后面方括号是一个数l,包括两个成员Qthis和object。这个数l实际上是Object静态成员extend的arguments参数。那么这条语句就相当于执?
obj.extend(this,object);
this不解释了Q表C本w。object是什么?参数Q恩Q是实例Ҏextend传来的参敎ͼ不要h。extend呢?objq没有定义extend实例成员Q但通过applyQ它可以把Object的静态成员extend拿来使用Q再看一下extend的函CQ?
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}
因ؓobj是对象,object也是对象Q即destination和source都是对象Q于是函数的作用是使objhobject的所有成员。ƈ且会q回obj。听h有点拗口Q但逻辑很简单:让obj“l承?#8221;objectQ很好,我们看到了承,但你肯定会问Q对象的l承Q第一ơ听说啊Q我们讲l承都是讲的cȝl承。没错,现在的确q没有看到真正的cȝ承,但已l近在眼前了Q类不就是有个prototype吗,而prototype是对象!
好,惛_q一点,cȝl承语法看似很简单了Q?
b.prototype.extend(a.prototype);
让bl承a?br />
可是事实却没那么单:prototype是存放方法原型指针,extendҎ没有初始化,不能使用Q要使用extendQ就必须实例化一个对象。还是看看prototype是怎么做的吧:
b.prototype=(new a()).extend(b.prototype);
很高明的办法Q充分说明了函数其实也是一个变量的道理。先实例化a对象Q然后在它基上调用extendQ将所有的成员b.prototype的成员覆盖到a的对象,然后把这个a对象再赋值给b.prototype。完成了b从al承的工作。在实际使用中,一般的用法都是Q?br />
b.prototype=(new a()).extend({});
因ؓ让一个bl承自aQ通常b之前都是一个未定义的类Q所以后面的{}中其实就可以定义cL员。当Ӟ你也可以先定义,再承,只是和传l概忉|所区别了?/p>
AJAX之旅Q?Q:javascript中的事g设计模式
今天暂时抛开prototype1.3.1Q分享一下我的javscript事g设计心得。其实现的技术基在于函数的本质,q在前面两篇中有详细叙述Q更多请xQ?a >http://www.x2design.netQ?br />
javascript内置的对象都有事件功能,比如button有onclick事gQinput有onchange事g。那么如何在我们自定义的cM实现事g呢?很简单:
var myClass=Class.create();
myClass.prototype={
show:function(){
//statement
onshow();
},
onshow:function(){}
}
q段代码其实是实现了onshow事gQ在myClass实例show的时候触发,你可以给onshowl定一个函敎ͼ从而用事件功能。在javascript中,内置的对象事件用方法都是如此,其内部实现应该也是基于这L模式。但是,q样的实现却有两个突出的问题Q?br />
1.只能l定一个回调函数。如果要实现多绑定,必须自己写很多代码来装要回调的函数C个函C?br />
2.不能传递参数。因为onshow只能赋给函数名,卛_C本nQƈ不能传递参数进去,Z传递参敎ͼ我曾写过一:《用外壳包装法给javascript触发器传递参数》,可见Q同样需要写很多代码?br />
那么Q这些问题怎么解决呢?javascript内置对象的事件用我们就暂时不管Q来考虑一下怎么在自己实现的cM避免如上两个问题。实C前,先来考虑下面q个问题Q或许有助于理解实现q个功能的意义:
我的面需要用javascriptq行一些初始化Q但初始化必d面载入完成之后q行。通常我们会将代码攑ֈhtml文g最下面。但此时Q在面载入完成之前Q页面上的按钮点击需要调用必ȝq初始化的方法,如果不作判断Q那么就很容易出现脚本错误。因没有初始化,一个简单的x是:用一个bool变量loaded来判断,初始为falseQ初始化完成后ؓtrueQ那么按钮点L遇到falseq单返回。这实现固然单,但有可能造成用户发现点击无效Q而不知其所以然。所以完善的做法应该是能捕获q个ҎQ将其绑定到面载入完成事g上,当页面蝲入完成后自动调用?br />
好,现在看事件设计模式的实现代码Q?br />
var myClass=Class.create();
myClass.prototype={
initialize:function(){
this.initEvent=new Object();
},
init:function(){
//初始化要执行的语?br />
//下面是调用绑定的回调函数
for(var p in this.initEvent){
//extend是内|方法,不可作ؓ回调关键?br />
if(p=="extend")continue;
this.initEvent[p].apply(_object,[]);
}
},
attachOnInit:function(_key,_object,_method,_arguments){
this.initEvent[_key]=createFunction(_object,_method,_arguments);
},
}
function createFunction(_object,_method,_arguments){
return function(){
_method.apply(_object,_arguments);
}
}
q段代码实C一个类myClassQ具有initҎQ触发oninit事gQ用时要想l定一个事Ӟ可以调用attachOnInitҎQ参数的意思分别ؓQ_keyQ回调参函数的唯一标识Q如果重复,后者覆盖前者;_object回调函数的对象,如果是直接在script中的函数Q可以传递this指针q去Q即document对象Q_methodQ要回调的函敎ͼ注意Q这是一个函数名Q不是字W串Q_argumentsQ回调函数的参数数组。还有一个函数是createFunctionQ作用是包装一个函敎ͼ使其内置参数Q这是外壛_装法那篇文章的一个通用实现。如果大家看qajax之旅pd的前两篇文章Q应该容易理解上面的代码Q如果有什么问题,Ƣ迎评论?br />
使用CZQ?br />
function myFunc(s){
alert(s);
}
var myObj=new myClass();
myClass.attach("key1",this,myFunc,[123]);
myClass.init();
q就myFunc函数l定到myObj的init函数Q执行后会弹出对话框123?br />
Ajax::prototype 源码解读 ?prototype.js 一[转蝲]
/**
* 定义一个全局对象, 属?Version 在发布的时候会替换为当前版本号
*/
var Prototype = {
Version: '@@VERSION@@'
}
/**
* 创徏一U类型,注意其属?create 是一个方法,q回一个构造函数?
* 一般用如?nbsp;
* var X = Class.create(); q回一个类型,cM?java 的一个Class实例?
* 要?X cdQ需l箋?new X()来获取一个实例,如同 java ?Class.newInstance()Ҏ?
*
* q回的构造函C执行名ؓ initialize 的方法, initialize ?Ruby 对象的构造器Ҏ名字?
* 此时initializeҎq没有定义,其后的代码中创徏新类型时会徏立相应的同名Ҏ?
*
* 如果一定要从java上去理解。你可以理解为用Class.create()创徏一个承java.lang.ClasscȝcR当然java不允许这样做Q因为ClasscLfinal?
*
*/
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
/**
* 创徏一个对象,从变量名来思考,本意也许是定义一个抽象类Q以后创建新对象?extend 它?
* 但从其后代码的应用来看, Abstract 更多是ؓ了保持命名空间清晰的考虑?
* 也就是说Q我们可以给 Abstract q个对象实例d新的对象定义?
*
* 从javaȝ解,是动态给一个对象创建内部类?
*/
var Abstract = new Object();
/**
* 获取参数对象的所有属性和ҎQ有点象多重l承。但是这U承是动态获得的?
* 如:
* var a = new ObjectA(), b = new ObjectB();
* var c = a.extend(b);
* 此时 c 对象同时拥有 a ?b 对象的属性和Ҏ。但是与多重l承不同的是Qc instanceof ObjectB 返回false?
*/
Object.prototype.extend = function(object) {
for (property in object) {
this[property] = object[property];
}
return this;
}
/**
* q个Ҏ很有,它封装一个javascript函数对象Q返回一个新函数对象Q新函数对象的主体和原对象相同,但是bind()Ҏ参数被用作当前对象的对象?
* 也就是说新函C?this 引用被改变ؓ参数提供的对象?
* 比如Q?
* <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>
* 那么Q调用aaa.showValue 返?aaa", 但调用aaa.showValue2 返?bbb"?
*
* apply 是ie5.5后才出现的新Ҏ(Netscape好像很早支持了)?
* 该方法更多的资料参考MSDN http://msdn.microsoft.com/library/en-us/script56/html/js56jsmthApply.asp
* q有一?call ҎQ应用v来和 apply cM。可以一LI下?
*/
Function.prototype.bind = function(object) {
var method = this;
return function() {
method.apply(object, arguments);
}
}
/**
* 和bind一P不过q个Ҏ一般用做html控g对象的事件处理。所以要传递event对象
* 注意q时候,用到?Function.call。它?Function.apply 的不同好像仅仅是对参数Ş式的定义?
* 如同 java 两个q蝲的方法?
*/
Function.prototype.bindAsEventListener = function(object) {
var method = this;
return function(event) {
method.call(object, event || window.event);
}
}
/**
* 整数Ş式RGB颜色D{换ؓHEX形式
*/
Number.prototype.toColorPart = function() {
var digits = this.toString(16);
if (this < 16) return '0' + digits;
return digits;
}
/**
* 典型 Ruby 风格的函敎ͼ参C的方法逐个调用Q返回第一个成功执行的Ҏ的返回?
*/
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 cdQ?
* 然后用对象直接量的语法Ş式设|原型?
*
* 需要特别说明的?rgisterCallback ҎQ它调用上面定义的函数原型方法bind, q传递自׃ؓ参数?
* 之所以这样做Q是因ؓ setTimeout 默认M window 对象为当前对象,也就是说Q如?registerCallback Ҏ定义如下的话Q?
* registerCallback: function() {
* setTimeout(this.onTimerEvent, this.frequency * 1000);
* }
* 那么Qthis.onTimeoutEvent Ҏ执行p|Q因为它无法讉K this.currentlyExecuting 属性?
* 而用了bind以后Q该Ҏ才能正确的找到thisQ也是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();
}
}
/*--------------------------------------------------------------------------*/
/**
* q个函数?Ruby 了。我觉得它的作用主要有两?
* 1. 大概?document.getElementById(id) 的最化调用?
* 比如Q?("aaa") 返回上 aaa 对象
* 2. 得到对象数组
* 比如: $("aaa","bbb") q回一个包括id?aaa"?bbb"两个input控g对象的数l?
*/
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::prototype 源码解读 ?prototype.js 二[转蝲]
/**
* 定义 Ajax 对象, 静态方?getTransport Ҏq回一?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对象起到命名I间的作用?
* Ajax.Base 声明Z个基对象cd
* 注意 Ajax.Base q没有?Class.create() 的方式来创徏Q我x因ؓ作者ƈ不希?Ajax.Base 被库使用者实例化?
* 作者在其他对象cd的声明中Q将会承于它?
* 好?java 中的U有抽象c?
*/
Ajax.Base = function() {};
Ajax.Base.prototype = {
/**
* extend (见prototype.js中的定义) 的用法真是让目一?
* options 首先讄默认属性,然后?extend 参数对象Q那么参数对象中也有同名的属性,那么p盖默认属性倹{?
* x如果我写q样的实玎ͼ应该cM如下Q?
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();
/**
* 定义四种事g(状?Q?参?a >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);
/**
* q里提供?XmlHttp 传输q程中每个步骤的回调函数
*/
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 状态,p用回调函?
*/
if (readyState != 1)
this.respondToReadyState(this.transport.readyState);
},
/**
* 回调函数定义?this.options 属性中Q比?
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 用于l定一个html元素?XmlHttp调用的返回倹{类g 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);
}
}
});
Ajax::prototype 源码解读 ?prototype.js 三[转蝲]
/**
* 针对 面元素对象 的工LQ提供一些简单静态方?
*/
var Field = {
/**
* 清除参数引用对象的?
*/
clear: function() {
for (var i = 0; i < arguments.length; i++)
$(arguments[i]).value = '';
},
/**
* 使参数引用对象获取焦?
*/
focus: function(element) {
$(element).focus();
},
/**
* 判断参数引用对象值是否ؓI,如ؓI,q回false, 反之true
*/
present: function() {
for (var i = 0; i < arguments.length; i++)
if ($(arguments[i]).value == '') return false;
return true;
},
/**
* 佉K中参数引用对象
*/
select: function(element) {
$(element).select();
},
/**
* 使参数引用对象处于可~辑状?
*/
activate: function(element) {
$(element).focus();
$(element).select();
}
}
/*--------------------------------------------------------------------------*/
/**
* 表单工具c?
*/
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';
}
},
/**
* 使表单的W一个非 hidden cd而且处于可用状态的元素获得焦点
*/
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();
}
}
/**
* 表单元素工具c?
*/
Form.Element = {
/**
* q回表单元素的值先序列化再q行 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]);
},
/**
* q回表单元素序列化后的?
*/
getValue: function(element) {
element = $(element);
var method = element.tagName.toLowerCase();
var parameter = Form.Element.Serializers[method](element);
if (parameter)
return parameter[1];
}
}
/**
* prototype 的所谓序列化其实是表单的名字和值组合成一个数l?
*/
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 思义Q是套用Observer设计模式来跟t指定表单元素,
* 当表单元素的值发生变化的时候,执行回调函?
*
* 我想 Observer 与注册onchange事g怼Q不同点在于 onchange 事g是在元素失去焦点的时候才Ȁ发?
* 同样的与 onpropertychange 事g也相|不过它只x表单元素的值的变化Q而且提供timeout的控制?
*
* 除此之外QObserver 的好处大概就在与更面向对象,另外可以动态的更换回调函数Q这比注册事g要灵zM些?
* Observer 应该可以胜Q动态数据校验,或者多个关联下拉选项列表的连动等{?
*
*/
Abstract.TimedObserver = function() {}
/**
* q个设计?PeriodicalExecuter 一Pbind Ҏ是实现的核心
*/
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 其实是一L
* 注意 Form.Observer q不是用来跟t整个表单的Q我惛_概只是ؓ了减书?q是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);
}
});
Ajax::prototype 源码解读 ?prototype.js 四[转蝲]
/**
* Ҏ class attribute 的名字得到对象数l,支持 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 p一?java 的工LQ主要用?隐藏/昄/销?对象Q以及获取对象的单属性?
*
*/
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;
/*--------------------------------------------------------------------------*/
/**
* 动态插入内容的实现QMS的Jscript实现中对象有一?insertAdjacentHTML Ҏ(http: //msdn.microsoft.com/workshop/author/dhtml/reference/methods/insertadjacenthtml.asp)
* q里是一个对象Ş式的装?
*/
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 ҎQ但可以用如下代码代?
*/
this.range = this.element.ownerDocument.createRange();
/**
* 如果定义?initializeRange ҎQ则实行Q这里相当与定义了一个抽象的 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 是一个抽象类Q定义了名ؓ initializeRange 的一个抽象方?
* var Insertion = new Object() 建立一个命名空?
* Insertion.Before|Top|Bottom|After p是四个java中的四个静态内部类Q而它们分别承于Abstract.InsertionQƈ实现了initializeRangeҎ?
*/
var Insertion = new Object();
Insertion.Before = Class.create();
Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
initializeRange: function() {
this.range.setStartBefore(this.element);
},
/**
* 内Ҏ入到指定节点的前? 与指定节点同U?
*/
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);
},
/**
* 内Ҏ入到指定节点的第一个子节点前,于是内容变ؓ该节点的W一个子节点
*/
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);
},
/**
* 内Ҏ入到指定节点的后? 与指定节点同U?
*/
insertContent: function() {
this.element.parentNode.insertBefore(this.fragment,
this.element.nextSibling);
}
});
Ajax::prototype 源码解读 ?prototype.js 五[转蝲]
prototype q有两个源码文g effects.js compat.js ׃贴出来了。两者ƈ不常用,effects.js 看example 做花哨的效果q不错,不过代码中没有太多新鲜的东西?
需要指出的是
compat.js ?Funcation.prototype.apply 的实现有两个错误Q应该是拼写错误Q, 我分别脓出来Q大家比较一下就清楚了?/p>
to_char(sysdate, 'dd') 查看今天是几号to_char(sysdate, 'ww') 查看q是q个月第几个星期
to_char(sysdate, 'mm') 查看q是一q中W几个月
to_char(sysdate, 'yyyy') 查看q䆾last_day(to_date('2007-02-01','YYYY-MM-DD'))查看一个月的最后一天,add_months(sysdate,10)查看若干个月后的今天Qnext_day(sysdate,'星期?)l个日期查看后面的最q的星期几的日期Q不q这个星期五要是换成英文居然有问题,W?个参数可以是数字1-7Q分别表C周日到周六?/p>
下面贴个全的Q需要的时候顺便查一下?/p>
一、PL/SQL单行函数和组函数详解
函数是一U有零个或多个参数ƈ且有一个返回值的E序。在SQL中Oracle内徏了一pd函数Q这些函数都可被UCؓSQL或PL/SQL语句Q函C要分Z大类Q单行函数和l函数?/p>
本文讨论如何利用单行函C及用规则?br /> 1、SQL中的单行函数
SQL和PL/SQL中自带很多类型的函数Q有字符、数字、日期、{换、和混合型等多种函数用于处理单行数据Q因此这些都可被l称为单行函数。这些函数均可用于SELECT,WHERE、ORDER BY{子句中Q例如下面的例子中就包含了TO_CHAR,UPPER,SOUNDEX{单行函数?/p>
SELECT ename,TO_CHAR(hiredate,'day,DD-Mon-YYYY')FROM empWhere UPPER(ename) Like 'AL%'ORDER BY SOUNDEX(ename)
单行函数也可以在其他语句中用,如update的SET子句QINSERT的VALUES子句QDELET的WHERE子句,认证考试特别注意在SELECT语句中用这些函敎ͼ所以我们的注意力也集中在SELECT语句中?/p>
2、NULL和单行函?/p>
在如何理解NULL上开始是很困隄Q就是一个很有经验的Z然对此感到困惑。NULLDCZ个未知数据或者一个空|术操作W的M一个操作数为NULL|l果均ؓ提个NULL?q个规则也适合很多函数Q只有CONCAT,DECODE,DUMP,NVL,REPLACE在调用了NULL参数时能够返回非NULL倹{在q些中NVL函数时最重要的,因ؓ他能直接处理NULL|NVL有两个参?NVL(x1,x2),x1和x2都式表达式,当x1为null时返回X2,否则q回x1?/p>
下面我们看看emp数据表它包含了薪水、奖金两,需要计ȝ补偿?/p>
column name emp_id salary bonuskey type pk nulls/unique nn,u nnfk table datatype number number numberlength 11.2 11.2
不是单的薪水和奖金加v来就可以了,如果某一行是null值那么结果就是nullQ比如下面的例子Q?/p>
update empset salary=(salary+bonus)*1.1
q个语句中,雇员的工资和奖金都将更新Z个新的|但是如果没有奖金Q即 salary + null,那么׃得出错误的结论,q个时候就要用nvl函数来排除null值的影响?/p>
所以正的语句是:
update empset salary=(salary+nvl(bonus,0)*1.1
3、单行字W串函数
单行字符串函数用于操作字W串数据Q他们大多数有一个或多个参数Q其中绝大多数返回字W串?/p>
ASCII()
c1是一字符Ԍq回c1W一个字母的ASCII码,他的逆函数是CHR()
SELECT ASCII('A') BIG_A,ASCII('z') BIG_z FROM empBIG_A BIG_z65 122
CHR()[NCHAR_CS]
i是一个数字,函数q回十进制表C的字符?/p>
select CHR(65),CHR(122),CHR(223) FROM empCHR65 CHR122 CHR223A z B
CONCAT(,)
c1,c2均ؓ字符Ԍ函数c2q接到c1的后面,如果c1为null,返回c2.如果c2为null,则返回c1Q如果c1、c2都ؓnullQ则q回null。他和操作符||q回的结果相?/p>
select concat('slobo ','Svoboda') username from dualusernameslobo Syoboda
INITCAP()
c1Z字符丌Ӏ函数将每个单词的第一个字母大写其它字母小写返回。单词由I格Q控制字W,标点W号限制?/p>
select INITCAP('veni,vedi,vici') Ceasar from dualCeasarVeni,Vedi,Vici
INSTR(,[,[,]])
c1,c2均ؓ字符Ԍi,j为整数。函数返回c2在c1中第jơ出现的位置Q搜索从c1的第i个字W开始。当没有发现需要的字符时返?,如果i敎ͼ那么搜烦从叛_左进行,但是位置的计还是从左到叻Ii和j的缺省gؓ1?/p>
select INSTR('Mississippi','i',3,3) from dualINSTR('MISSISSIPPI','I',3,3)11select INSTR('Mississippi','i',-2,3) from dualINSTR('MISSISSIPPI','I',3,3)2
INSTRB(,[,i[,j])
与INSTR()函数一P只是他返回的是字节,对于单字节INSTRB(){于INSTR()?/p>
LENGTH()
c1为字W串Q返回c1的长度,如果c1为nullQ那么将q回null倹{?/p>
select LENGTH('Ipso Facto') ergo from dualergo10
LENGTHb()
与LENGTH()一Pq回字节?/p>
lower()
q回c的小写字W,l常出现在where子串中?/p>
select LOWER(colorname) from itemdetail WHERE LOWER(colorname) LIKE '%white%'COLORNAMEWinterwhite
LPAD(,[,])
c1,c2均ؓ字符Ԍi为整数。在c1的左侧用c2字符串补长度i,可多ơ重复,如果i于c1的长度,那么只返回i那么长的c1字符Q其他的被截去。c2的缺省gؓ单空|参见RPAD?/p>
select LPAD(answer,7,'') padded,answer unpadded from question;PADDED UNPADDED Yes YesNO NOMaybe maybe
LTRIM(,)
把c1中最左边的字W去掉,使其W一个字W不在c2中,如果没有c2Q那么c1׃会改变?/p>
select LTRIM('Mississippi','Mis') from dualLTRppi
RPAD(,[,])
在c1的右侧用c2字符串补长度i,可多ơ重复,如果i于c1的长度,那么只返回i那么长的c1字符Q其他的被截去。c2的缺省gؓ单空?其他与LPAD怼?/p>
RTRIM(,)
把c1中最双的字W去掉,使其W后一个字W不在c2中,如果没有c2Q那么c1׃会改变?/p>
REPLACE(,[,])
c1,c2,c3都是字符Ԍ函数用c3代替出现在c1中的c2后返回?/p>
select REPLACE('uptown','up','down') from dualREPLACEdowntown
STBSTR(,[,])
c1Z字符Ԍi,j为整敎ͼ从c1的第i位开始返回长度ؓj的子字符Ԍ如果j为空Q则直到串的N?/p>
select SUBSTR('Message',1,4) from dualSUBSMess
SUBSTRB(,[,])
与SUBSTR大致相同Q只是I,J是以字节计算?/p>
SOUNDEX()
q回与c1发音怼的词?/p>
select SOUNDEX('dawes') Dawes SOUNDEX('daws') Daws, SOUNDEX('dawson') from dualDawes Daws DawsonD200 D200 D250
TRANSLATE(,,)
c1中与c2相同的字W以c3代替
select TRANSLATE('fumble','uf','ar') test from dualTEXTramble
TRIM([[]] from c3)
c3串中的第一个,最后一个,或者都删除?/p>
select TRIM(' space padded ') trim from dual TRIMspace padded
UPPER()
q回c1的大写,常出现where子串?/p>
select name from dual where UPPER(name) LIKE 'KI%'NAMEKING
4、单行数字函?/p>
单行数字函数操作数字数据Q执行数学和术q算。所有函数都有数字参数ƈq回数字倹{所有三角函数的操作数和值都是弧度而不是角度,oracle没有提供内徏的弧度和角度的{换函数?/p>
ABS()
q回n的绝对?/p>
ACOS()
反余弦函敎ͼq回-1?之间的数。n表示弧度
select ACOS(-1) pi,ACOS(1) ZERO FROM dualPI ZERO3.14159265 0
ASIN()
反正弦函敎ͼq回-1?Qn表示弧度
ATAN()
反正切函敎ͼq回n的反正切|n表示弧度?/p>
CEIL()
q回大于或等于n的最整数?/p>
COS()
q回n的余玄|n为弧?/p>
COSH()
q回n的双曲余玄|n 为数字?/p>
select COSH(<1.4>) FROM dualCOSH(1.4)2.15089847
EXP()
q回e的nơ幂Qe=2.71828183.
FLOOR()
q回于{于N的最大整数?/p>
LN()
q回N的自然对敎ͼN必须大于0
LOG(,)
q回以n1为底n2的对?/p>
MOD()
q回n1除以n2的余?br /> POWER(,)
q回n1的n2ơ方
ROUND(,)
q回舍入数点右边n2位的n1的|n2的缺省gؓ0Q这回将数Ҏ接近的整敎ͼ如果n2数就舍入到小数点左边相应的位上,n2必须是整数?/p>
select ROUND(12345,-2),ROUND(12345.54321,2) FROM dualROUND(12345,-2) ROUND(12345.54321,2)12300 12345.54
SIGN()
如果n敎ͼq回-1,如果n为正敎ͼq回1Q如果n=0q回0
SIN()
q回n的正玄?n为弧度?/p>
SINH()
q回n的双曲正玄?n为弧度?/p>
SQRT()
q回n的^Ҏ,n为弧?/p>
TAN()
q回n的正切?n为弧?/p>
TANH()
q回n的双曲正切?n为弧?/p>
TRUNC(,)
q回截尾到n2位小数的n1的|n2~省讄?Q当n2为缺省设|时会将n1截尾为整敎ͼ如果n2|截֜数点左边相应的位上?/p>
5、单行日期函?/p>
单行日期函数操作DATA数据cdQ绝大多数都有DATA数据cd的参敎ͼl大多数q回的也是DATA数据cd的倹{?/p>
ADD_MONTHS(,)
q回日期d加上i个月后的l果。i可以使Q意整数。如果i是一个小敎ͼ那么数据库将隐式的他转换成整敎ͼ会截去数点后面的部分?/p>
LAST_DAY()
函数q回包含日期d的月份的最后一?/p>
MONTHS_BETWEEN(,)
q回d1和d2之间月的数目,如果d1和d2的日的日期都相同Q或者都使该月的最后一天,那么返回一个整敎ͼ否则会返回的l果包含一个分数?/p>
NEW_TIME(,,)
d1是一个日期数据类型,当时区tz1中的日期和时间是dӞq回时区tz2中的日期和时间。tz1和tz2时字W串?/p>
NEXT_DAY(,)
q回日期d后由dowl出的条件的W一天,dow使用当前会话中给出的语言指定了一周中的某一天,q回的时间分量与d的时间分量相同?/p>
select NEXT_DAY('01-Jan-2000','Monday') "1st Monday",NEXT_DAY('01-Nov-2004','Tuesday')+7 "2nd Tuesday") from dual;1st Monday 2nd Tuesday03-Jan-2000 09-Nov-2004
ROUND([,])
日期d按照fmt指定的格式舍入,fmt为字W串?/p>
SYADATE
函数没有参数Q返回当前日期和旉?/p>
TRUNC([,])
q回由fmt指定的单位的日期d
6、单行{换函?/p>
单行转换函数用于操作多数据类型,在数据类型之间进行{换?/p>
CHARTORWID()
c 使一个字W串Q函数将c转换为RWID数据cd?/p>
SELECT test_id from test_case where rowid=CHARTORWID('AAAA0SAACAAAALiAAA')
CONVERT(,[,])
c֭W串Qdset、sset是两个字W集Q函数将字符串c由sset字符集{换ؓdset字符集,sset的缺省设|ؓ数据库的字符集?/p>
HEXTORAW()
x?6q制的字W串Q函数将16q制的x转换为RAW数据cd?/p>
RAWTOHEX()
x是RAW数据cd字符Ԍ函数RAW数据c{换ؓ16q制的数据类型?/p>
ROWIDTOCHAR()
函数ROWID数据cd转换为CHAR数据cd?/p>
TO_CHAR([[,)
x是一个data或number数据cdQ函数将x转换成fmt指定格式的char数据cdQ如果x为日期nlsparm=NLS_DATE_LANGUAGE 控制q回的月份和日䆾所使用的语a。如果x为数字nlsparm=NLS_NUMERIC_CHARACTERS 用来指定数位和千分位的分隔W,以及货币W号?/p>
NLS_NUMERIC_CHARACTERS ="dg", NLS_CURRENCY="string"
TO_DATE([,[,)
c表示字符Ԍfmt表示一U特D格式的字符丌Ӏ返回按照fmt格式昄的c,nlsparm表示使用的语a。函数将字符串c转换成date数据cd?/p>
TO_MULTI_BYTE()
c表示一个字W串Q函数将c的担子截字符转换成多字节字符?/p>
TO_NUMBER([,[,)
c表示字符Ԍfmt表示一个特D格式的字符Ԍ函数q回值按照fmt指定的格式显C。nlsparm表示语言Q函数将q回c代表的数字?/p>
TO_SINGLE_BYTE()
字W串c中得多字节字W{化成{h的单字节字符。该函数仅当数据库字W集同时包含单字节和多字节字W时才?/p>
7、其它单行函?/p>
BFILENAME(,)
dir是一个directorycd的对象,fileZ文g名。函数返回一个空的BFILE位置值指C符Q函数用于初始化BFILE变量或者是BFILE列?/p>
DECODE(,,[,,,[])
x是一个表辑ּQm1是一个匹配表辑ּQx与m1比较Q如果m1{于xQ那么返回r1,否则,x与m2比较Q依ơ类推m3,m4,m5....直到有返回结果?/p>
DUMP(,[,[,[,]]])
x是一个表辑ּ或字W,fmt表示8q制?0q制?6q制、或则单字符。函数返回包含了有关x的内部表CZ息的VARCHAR2cd的倹{如果指定了n1,n2那么从n1开始的长度为n2的字节将被返回?/p>
EMPTY_BLOB()
该函数没有参敎ͼ函数q回 一个空的BLOB位置指示W。函数用于初始化一个BLOB变量或BLOB列?/p>
EMPTY_CLOB()
该函数没有参敎ͼ函数q回 一个空的CLOB位置指示W。函数用于初始化一个CLOB变量或CLOB列?/p>
GREATEST()
exp_list是一列表辑ּQ返回其中最大的表达式,每个表达式都被隐含的转换W一个表辑ּ的数据类型,如果W一个表辑ּ是字W串数据cd中的M一个,那么q回的结果是varchar2数据cdQ同时用的比较是非填充I格cd的比较?br /> LEAST()
exp_list是一列表辑ּQ返回其中最的表达式,每个表达式都被隐含的转换W一个表辑ּ的数据类型,如果W一个表辑ּ是字W串数据cd中的M一个,返回的l果是varchar2数据cdQ同时用的比较是非填充I格cd的比较?/p>
UID
该函数没有参敎ͼq回唯一标示当前数据库用L整数?/p>
USER
q回当前用户的用户名
USERENV()
Zoptq回包含当前会话信息。opt的可选gؓQ?/p>
ISDBA 会话中SYSDBA脚色响应Q返回TRUE
SESSIONID q回审计会话标示W?/p>
ENTRYID q回可用的审计项标示W?/p>
INSTANCE在会话连接后Q返回实例标C符。该值只用于q行Parallel 服务器ƈ且有 多个实例的情况下使用?/p>
LANGUAGEq回语言、地域、数据库讄的字W集?/p>
LANGq回语言名称的ISO~写?/p>
TERMINAL为当前会话用的l端或计机q回操作pȝ的标C符?/p>
VSIZE() x是一个表辑ּ。返回x内部表示的字节数?/p>
二、SQL中的l函?/p>
l函C叫集合函敎ͼq回Z多个行的单一l果Q行的准数量无法确定,除非查询被执行ƈ且所有的l果都被包含在内。与单行函数不同的是Q在解析时所有的行都是已知的。由于这U差别ɾl函C单行函数有在要求和行Z有微的差异.
1、组(多行)函数
与单行函数相比,oracle提供了丰富的Zl的Q多行的函数。这些函数可以在select或select的having子句中用,当用于select子串时常帔R和GROUP BY一起用?/p>
AVG([{DISYINCT|ALL}])
q回数值的q_倹{缺省设|ؓALL
SELECT AVG(sal),AVG(ALL sal),AVG(DISTINCT sal) FROM scott.empAVG(SAL) AVG(ALL SAL) AVG(DISTINCT SAL)1877.94118 1877.94118 1916.071413
COUNT({*|DISTINCT|ALL} )
q回查询中行的数目,~省讄是ALL,*表示q回所有的行?/p>
MAX([{DISTINCT|ALL}])
q回选择列表目的最大|如果x是字W串数据cdQ他q回一个VARCHAR2数据cdQ如果X是一个DATA数据cdQ返回一个日期,如果X是numeric数据cdQ返回一个数字。注意distinct和all不v作用Q应为最大gq两U设|是相同的?/p>
MIN([{DISTINCT|ALL}])
q回选择列表目的最倹{?/p>
STDDEV([{DISTINCT|ALL}])
q回选者的列表目的标准差Q所谓标准差是方差的qx栏V?/p>
SUM([{DISTINCT|ALL}])
q回选择列表目的数值的d?/p>
VARIANCE([{DISTINCT|ALL}])
q回选择列表目的统计方差?/p>
2、用GROUP BYl数据分l?/p>
正如题目暗示的那L函数是操作那些已经分好l的数据Q我们告诉数据库用GROUP BY怎样l数据分l或者分c,当我们在SELECT语句的SELECT子句中用组函数Ӟ我们必须把ؓ分组或非常数列放|在GROUP BY子句中,如果没有用group byq行专门处理Q那么缺省的分类是将整个l果设ؓ一cR?/p>
select stat,counter(*) zip_count from zip_codes GROUP BY state;ST ZIP_COUNT-- ---------AK 360AL 1212AR 1309AZ 768CA 3982
在这个例子中Q我们用state字段分类;如果我们要将l果按照zip_codes排序,可以用ORDER BY语句QORDER BY子句可以使用列或l函数?/p>
select stat,counter(*) zip_count from zip_codes GROUP BY state ORDER BY COUNT(*) DESC;ST COUNT(*)-- --------NY 4312PA 4297TX 4123CA 3982
3、用HAVING子句限制分组数据
现在你已l知道了在查询的SELECT语句和ORDER BY子句中用主函数Q组函数只能用于两个子串中,l函C能用于WHERE子串中,例如下面的查询是错误的:
错误SELECT sales_clerk,SUN(sale_amount) FROM gross_sales WHERE sales_dept='OUTSIDE' AND SUM(sale_amount)>10000 GROUP BY sales_clerk
q个语句中数据库不知道SUM()是什么,当我们需要指C数据库对行分组Q然后限制分l后的行的输出时Q正的Ҏ是用HAVING语句Q?/p>
SELECT sales_clerk,SUN(sale_amount) FROM gross_sales WHERE sales_dept='OUTSIDE' GROUP BY sales_clerkHAVING SUM(sale_amount)>10000;
4、嵌套函?/p>
函数可以嵌套。一个函数的输出可以是另一个函数的输入。操作数有一个可l承的执行过E。但函数的优先权只是Z位置Q函数遵循由内到外,由左到右的原则。嵌套技术一般用于象DECODEq样的能被用于逻辑判断语句IF....THEN...ELSE的函数?/p>
嵌套函数可以包括在组函数中嵌套单行函敎ͼ或者组函数嵌套入单行函数或l函C。比如下面的例子Q?/p>
SELECT deptno, GREATEST(COUNT(DISTINCT job),COUNT(DISTINCT mgr) cnt,COUNT(DISTINCT job) jobs,COUNT(DISTINCT mgr) mgrsFROM empGROUP BY deptno;DEPTNO CNT JOBS MGRS------ --- ---- ----10 4 4 220 4 3 430 3 3 2
2、Foreach 和For一样?/p>
3、Hiddenlg L多余S的处?br /> <input jwcid="@Hidden" type="hidden" value="ognl:blahblah" encode="false"/>
4?Insert lg
e.g.
<input type="text" jwcid="name@Insert" value="ognl:user.name"/>
面表现?会到页面类中寻找getUser().getName()Ҏ获取初值ƈ输出
相当于在面上显C数?
5?TextField lg
e.g.
<input type="text" jwcid="username@TextField" value="ognl:username"/>
面表现?会到页面类中寻找getUsername()Ҏ获取初?
*如果是修改信息页?通常初始D在页面表C前由setUsername()手动讄从数据库中读取出来的?
表单提交?通过setUsername()写入新?即用戯入?,在类中通过getUsername()获取新?
相当于在修改个h信息?首先d用户名赋予文本框(用户?初?用户修改时填入新?后台获取?
*Hidden属性区分是普通文本输入框(默认false)和密码输入框(hidden="ognl:true")
readonly属性设|只?readonly="true"为只?后台可读?
*disabled属性设|是否可?diabled="true"Z可写(后台也不可读?
6?TextArea lg
e.g.
<textarea jwcid="content@TextArea" value="ognl:content" cols="40" rows="10"></textarea>
面表现?会到页面类中寻找getContent()Ҏ获取初?
工作原理同TextField
7?RadioGroup/Radio lg
e.g.
<span jwcid="headImage@RadioGroup" selected="ognl:headImage">
<input jwcid="@Radio" type="radio" value="1"/>头像1
<input jwcid="@Radio" type="radio" value="2"/>头像2
<input jwcid="@Radio" type="radio" value="3"/>头像3
<input jwcid="@Radio" type="radio" value="4"/>头像4
<input jwcid="@Radio" type="radio" value="5"/>头像5
<input jwcid="@Radio" type="radio" value="6"/>头像6
</span>
RadioGroup为每一个Radio提供一个唯一的ID。RadioGroup跟踪当前被选中的属性|q且只有一个Radio能够被选中.
面提交ӞRadioGrouplg利用OGNL表达式向headImage字段写入被选中的Radiolg的value参数?
面表现?修改面),会到页面类中寻找getHeadImage()Ҏ获取初?然后L@Radiolg中与其相同的lgq勾选上.
8?PropertySelection lg
使用PropertySelectionlg必须要构造一个类来实现IPropertySelectionModel接口Qƈ且重写该接口?个方?
public int getOptionCount() //提供下拉菜单的长?
public Object getOption(int index) //提供select标签的option
public String getLabel(int index) //提供select标签的Label|也就是下拉菜单显C的内容
public String getValue(int index) //提供select标签的value?
public Object translateValue(String value) //selected后的q回|value值未必就是我们需要的q回|可以在这个方法里面对q回的value做对应的转换或修?
e.g.1. 性别下拉?
<select jwcid="gender@ProPertySelection" name="genderSelect" value="ognl:gender" model="supportedGender">
<option selected>先生</option>
<option>奛_</option>
</select>
代码
GenderSelectionModel.java
public class GenderSelectionModel implements IPropertySelectionModel {
public static final String male = "先生";
public static final String female = "奛_";
public static final String[] genderOptions = { male, female };
public int getOptionCount() {
return genderOptions.length;
}
public Object getOption(int index) {
return this.translateValue(genderOptions[index]);
}
public String getLabel(int index) {
return genderOptions[index].toString();
}
public String getValue(int index) {
return genderOptions[index];
}
public Object translateValue(String value) {
if (value.equals("先生")) {
return "1";
} else {
return "0";
}
}
}
代码
ModUserInfo.java
public IPropertySelectionModel getSupportedGender() {
return new GenderSelectionModel();
}
存入数据库中"1"代表先生,"0"代表奛_,通过translateValue(String value)Ҏ转换
面表现?通过model属性给出的IPropertySelectionModel获取下拉选项,即getSupportedGender().
然后通过getGender()Ҏ获取初?比如获取"0",则在面昄时寻找valuegؓ"0"的选项即ؓ"奛_",q择之作为初始选择?
e.g.2. 日志cd下拉?
<select jwcid="logType@PropertySelection" name="typeSelect" value="ognl:logType" model="supportedType">
<option>心情日记</option>
<option>情感天地</option>
<option>生活感触</option>
</select>
代码
TypeSelectionModel.java
public class TypeSelectionModel implements IPropertySelectionModel {
private List typeList = new ArrayList();
public TypeSelectionModel(List typeList) {
this.typeList = typeList;
}
public int getOptionCount() {
return typeList.size();
}
public Object getOption(int index) {
return ((LogType)typeList.get(index)).getValue();
}
public String getLabel(int index) {
return ((LogType) typeList.get(index)).getName();
}
public String getValue(int index) {
return ((LogType) typeList.get(index)).getValue();
}
public Object translateValue(String value) {
return value;
}
}
代码
ModLog.java
public IPropertySelectionModel getSupportedType() {
TypeSelectionModel typeSelectionModel =
new TypeSelectionModel(loadType(getUser().getUserId()));
return typeSelectionModel;
}
private List loadType(int userid) {
...//从数据库载入该用L日志cd列表
}
面表现?通过model属性给出的IPropertySelectionModel获取下拉选项,即getSupportedType().
然后通过value属性给出的初始值即,getLogType()Ҏ获取初?比如获取"2",则在面昄时寻找valuegؓ"2"的选项即ؓ"生活感触",q择之作为初始选择?
9?Formlg
e.g.
<form jwcid="logForm@Form">
...
</form>
Form的监?listener)Ҏ可以有两U方?
1. 在Formlg中声?
<form jwcid="logForm@Form" listener="ognl:listener:onLogin">
...
</form>
2. 在submitcdlg中声?
<input type="submit" jwcid="onLogin@Submit" listener="listener:onLogin" value="发表"/>或?
<span jwcid="@ImageSubmit" image="..." listener="listener:onLogin"><img src="..." width="" height=""/></span>
前一U方式当Form中只要有submit׃触发监听Ҏ,后一U方式是Form中有多个submit,各自实现不同的监听方?
G) Foreach lg
e.g.
<span jwcid="@Foreach" source="ognl:logList" value="ognl:item">
循环lg,遍历source参数,在表现其内容前更新value参数,Foreachlg所包含的内定w复表?其中可以通过value参数获取所需昄内容.
本例?面表现旉过getLogList()Ҏ获取日志列表,循环取出其中数据更新item(日志对象)q予以显C?其中item需要在面规范(.page)文g中声?
<property name="item"/>
*class参数用来LcMCSS的文件对Foreachq行修饰.
Foreachlg: class="ognl:beans.evenOdd.next"
Page文g: <bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
CSS文g: tr.odd{background-color: #ffffff;}tr.even{background-color: #eeeeee;}
10?Conditional lg
e.g.
<span jwcid="@Conditional" condition='ognl:item.sex.equals("1")'>先生</span>
<span jwcid="@Conditional" condition='ognl:item.sex.equals("0")'>奛_</span>
conditional参数为true时运行Conditionallg中的HTML模板内容.
在Tapestry4.0以后׃支持该组件了, 可以使用其他lg来实?
1. Contrib:Choose和Contrib:When
<library id="contrib" specification-path="classpath:/org/apache/tapestry/contrib/Contrib.library"/>(.application文g中引入Contribcd)
<span jwcid="@contrib:Choose">
<span jwcid="@contrib:When" condition='ognl:user.gender.equals("1")'>先生</span>
<span jwcid="@contrib:When" condition='ognl:user.gender.equals("0")'>奛_</span>
</span>
2. Iflg
<span jwcid="@If" condition='ognl:item.sex.equals("1")'>先生</span>
<span jwcid="@If" condition='ognl:item.sex.equals("0")'>奛_</span>
3. Elselg
<span jwcid="@Else">man</span>
?===========================ts的函数执行顺?=======================================?br />
对之前的该文章进行了一些修正,主要是针对finishLoad()Ҏ?
我觉得对初学者会有一些帮助?
下面q几个函数是我在使用的,它们的执行顺序依ơ从上到下?
1.protected void finishLoad() {} ***
2.public void pageValidate(PageEvent event) {}
3.public void activateExternalPage(Object[] parameters, IRequestCycle cycle) {}
4.public void pageBeginRender(PageEvent event) {}
// 如果有表单提交,则将form中的各字D늚Dl页面类
5. ...... 赋?
6.public void submit() // 表单提交{用listenter:调用的方?
7.protected void prepareForRender(IRequestCycle cycle) {}
----------------------------------------------------
1.protected void finishLoad() {}
q个函数最先执行,但是它实际上没有什么用处(我感觉)。因为:
q个函数只在面池中没有某一个页面类、需要生成一个新的页面对象时才调用。这里就有一个陷阱:如果你的tomcat启动时用了-Dorg.apache.tapestry.disable-caching=true(Z调试方便而设)Q那么你每次h面Ӟ它都会执行(因ؓ每个request都会新生成一个页面类对象Q,造成了它L执行的假象。在实际的部|时Q会使用cachingQ则q个函数执行的机会很。所以要注意?
初始化的代码攑֜4 pageBeginRender()?
2.public void pageValidate(PageEvent event) {}
如果实现了PageValidateListener接口Q则可以在这里进行验证,比如讉K权限{。执行完1后,它就开始执行?
3.public void activateExternalPage(Object[] parameters, IRequestCycle cycle) {}
如果实现了IExternalPage接口Q则可以从这里取得由外面传过来的参数。执?后,执行到这里。在q里可以把那些参数取出,赋给面cR?
4.public void pageBeginRender(PageEvent event) {}
执行?后,执行本函数。但是这时从客户端传q来的参数还没有被赋?如果提交了表单的?。这里可以进行一些初始化操作?
5.执行?后,如果有表单提交,在这里将会取出那些|赋给对应的字Dc?注意Q只是将表单中有的Dq来)
6.public void submit()
如果有表单提交的话,在这里将q行对应的操作。因为此时各字段已经取好gQ所以可以拿来直接用?
7.protected void prepareForRender(IRequestCycle cycle) {}
最后才执行q个Ҏ。我们可以在其中q行Z在页面上昄数据而进行的操作Q比如取得什么对象什么的Q因里页面类的属性赋值已l结束,可以直接拿来使用了?
注意Q如果执行了6Q则q要执行4Q再执行7。如果没?Q?完了q接是7?
以上是我所ȝ的执行顺序,不当之处h出?nbsp;
-----------------------------------------------------
最开始学tapestry的时候,觉得“怎么有这么多地方需要持久啊”。原来以前只知道pageBeginRenderq个函数Q什么初始化操作都放在它里面。可是它是在赋g前执行,所以拿到的字段多都是空的,却都以ؓ是没有持久化的缘故。所以在客户端里放了一大堆的@HiddenQ或者session中持久,非常ȝQ,Q对tapestry也生的怀疑。现在才知道那些需要取得客L传来的参数的代码Q最好放在prepareForRender里,很多不必要的持久都可以省掉了
下蝲本文源码: ajaxform_gbk.zip 6KB
更新:
2007-01-03
修复?AJAXFormer 中第二个参数 resultDiv 处理不当的问?
增加了从服务器端q回脚本q加以执行的功能;
增加了表单提交后|络出错的错误显C功?
q些新功能都已经攑֜CZ面中了.
试通过: Resin 3.0.18, Tomcat 5.0.30, 5.5.20; 览? IE 6/Firefox 2.0.
上一文?JSP ?AJAX 的表单提交中文问题的单解x?/a> 主要是针?UTF-8 版本的进行处理的, 鉴于中国大陆地区大部分还是用 GBK ~码?JSP, 因此本文针?GBK 的实늻果进行介l?
有朋友提?当AJAX遭遇GBK的尴?/a> 里说?AJAX 使用 GBK ~码? 表单提交出Cؕ? 如前文所q? 只要全部采用 UTF-8 ~码, 是没有Q何问题的. 那么都用 GBK ?
首先要讲的是我们的文章还是一L原则: 可能少的改动原来的代码来解决中文ؕ码问? 所以本文的CZ没有用过滤器{方?
那么使用 GBK ~码到底有没有ؕ码问题呢?
W一个关键点是 AJAX 的表单提交代码必L的按照 HTTP 规范实现, 卌保持原来?GET/POST 方式不变, 也要保持里面的内容和览器提交的内容一怸? 以下内容摘自我编写的内部培训教材:
----------------- 引用开?-----------------
首先必须要介l一?HTTP 协议?GET, POST 的工作方?
当用户在Web览器地址栏中输入一个带有http://前缀的URLq按下Enter?或者在Web面中某个以http://开头的链接上单击鼠标,HTTP事务处理的第一个阶D?-建立q接阶段开始了.HTTP的默认端口是80.
随着q接的徏?HTTPp入了客户向服务器发送请求的阶段.客户向服务器发送的h是一个有特定格式的ASCII消息,其语法规则ؓ:
6KB |
< Method > < URL > < HTTP Version > <\n> { <Header>:<Value> <\n>}* <\n> { Entity Body } |
h消息的顶端是h?用于指定Ҏ,URL和HTTP协议的版?h行的最后是回R换行.Ҏ有GET,POST,HEAD,PUT,DELETE{?
在请求行之后是若q个报头(Header)?每个报头行都是由一个报头和一个取值构成的二元?报头和取g间以":"分隔;报头行的最后是回R换行. 常见的报头有Accept(指定MIME媒体cd),Accept_Charset(响应消息的编码方?,Accept_Encoding(响应消息的字W集),User_Agent(用户的浏览器信息){?
在请求消息的报头行之后是一个回车换?表明h消息的报头部分结?在这个\n之后是请求消息的消息实体(Entity Body).
Web服务器在收到客户hq作出处理之?要向客户发送应{消?与请求消息一?应答消息的语法规则ؓ:
< HTTP Version> <Status Code> [<Message>]<\n> { <Header>:<Value> <\n> } * <\n> { Entity Body } |
应答消息的第一行ؓ状态行,其中包括了HTTP版本?状态码和对状态码q行短解释的消息;状态行的最后是回R换行.状态码?位数字组??c?
例如:415,表示不支持改媒体cd;503,表示服务器不能访?最常见的是200,表示成功.常见的报头有:Last_Modified(最后修Ҏ?,Content_Type(消息内容的MIMEcd),Content_Length(内容长度){?
在报头行之后也是一个回车换?用以表示应答消息的报头部分的l束,以及应答消息实体的开?
下面是一个应{消息的例子:
HTTP/1.0 200 OK Date: Moday,07-Apr-97 21:13:02 GMT Server:NCSA/1.1 MIME_Version:1.0 Content_Type:text/html Last_Modified:Thu Dec 5 09:28:01 1996 Coentent_Length:3107 <HTML><HEAD><TITLE>...</HTML> |
那么 GET ?POST 有什么区? 区别是一个在 URL h里面附带了表单参数和? 一个是?HTTP h的消息实体中. 用下面的例子可以很容易的看到同样的数据通过GET和POST来发送的区别, 发送的数据?username=张三 :
GET 方式, 览器键?http://localhost?username=张三
GET /?username=%E5%BC%A0%E4%B8%89 HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */* Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322) Host: localhost Connection: Keep-Alive |
POST 方式:
POST / HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */* Accept-Language: zh-cn Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322) Host: localhost Content-Length: 28 Connection: Keep-Alive username=%E5%BC%A0%E4%B8%89 |
比较一下上面的两段文字, 您会发现 GET 方式把表单内Ҏ在前面的h头中, ?POST 则把q些内容攑֜h的主体中? 同时 POST 中把h?Content-Type 头设|ؓ application/x-www-form-urlencoded. 而发送的正文都是一L, 可以q样来构造一个表单提交正?
encodeURIComponent(arg1)=encodeURIComponent(value1)&encodeURIComponent(arg2)=encodeURIComponent(value2)&.....
? encodeURIComponent q回一个包含了 charstring 内容的新?String 对象QUnicode 格式Q, 所有空根{标炏V重音符号以及其他非 ASCII 字符都用 %xx ~码代替Q其?xx {于表示该字W的十六q制数?例如Q空D回的?"%20" ?字符的值大?255 的用 %uxxxx 格式存储。参?JavaScript ?encodeURIComponent() Ҏ.
下面pZ下如何在 JavaScript 中执行一?GET 或?POST h. 如果您用q?Java, 那么您可能熟悉下列的?java.net.URLConnection c进?POST 操作的代?参?Java Tip 34: POSTing via Java ):
URL url; |
以上的代码向 somepage 发送了一?POST h, 数据?name = Buford Early, email = buford@known-space.com.
?/code>JavaScript 来执?POST/GET h是同L原理, 下面的代码展CZ分别?XMLHttpRequest 对象?somepage ?GET ?POST 两种方式发送和上例相同的数据的具体q程:
GET 方式
var postContent = |
POST 方式
var postContent = |
x希望你已l能够理解如何用 JavaScript 中的 XMLHttpRequest 对象来执?GET/POST 操作, 剩下的工作就是您如何来构造这些提交的参数? 最后我l出一个将现有?form 提交代码修改为异步的 AJAX 提交的代?注意目前作者还不知道如何让 file 上传表单域也能异步上传文?. 首先L两个 JavaScript 函数:
|
函数 ajaxSubmitForm 表单要提交的内容进行封? 然后调用 ajaxSubmit 函数来执行真正的异步提交, 表单提交后所q回的结果则昄在给定的 DIV 容器中或者没有指定参数时?DOM 对象动态生成一?DIV 容器来显C结果ƈd到页面末? q样, 对原来的表单只需要改动一个地方就可以原来的表单提交改ؓ异步模式, 卛_ form 标签里加? onSubmit="ajaxSubmitForm(this);return false;" 卛_, return false 保表单不会被浏览器同步提交. 完整的例子请?a >q里.
----------------- 引用l束 -----------------
OK, 希望x为止您已l理解了如何?AJAX 来正的执行 GET/POST. 如果q个问题您解决了, 可是说后台的q问题和你直接通过表单提交几乎没有区别? q个Ҏ的具体封装已l在附g?ajax_common.js 中了.
x也该贴出来我们的 GBK ~码的客L面的内容了:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<title>AJAX Form Submit Test</title>
<script src='ajax_common.js'></script>
</head>
<body>
本页面的~码是中?<br/>
<meta http-equiv="Content-Type" content="text/html; charset=gbk"><br/>
<b>试q的服务?</b><br/>
Resin 3.0.18<br/>
Tomcat 5.5.20<br/>
Tomcat 5.0.30<br/>
<h3>AJAX Form Submit Test</h3>
Fill the form and then click submit<br>
提交方式: POST<br>
<form method="POST" id="form1" name="form1"
action="form_action.jsp"
onSubmit="former.ajaxSubmitForm();return false;">
<p><input type="hidden" name="hidden1" value="hiddenValue">
text:<input type="text" name="textf&1" size="20" value="text文本&1">
checkbox:<input type="checkbox" name="checkbox1" value="ON" checked>
radio:<input type="radio" value="V1" checked name="radio1">
select:<select size="1" name="select1">
<option selected value="option1">D1</option>
</select>
<br>
<br>
<input type="submit" name="B1" value="submit">
<input type="reset" name="B2" value="reset">
</p>
</form>
提交方式: GET<br>
<form method="GET" id="form2" name="form2"
action="form_action.jsp"
onSubmit="former2.ajaxSubmitForm();return false;">
<p><input type="hidden" name="hidden1" value="hiddenValue">
text:<input type="text" name="text文本&2" size="20" value="text文本&2">
checkbox:<input type="checkbox" name="checkbox1" value="ON" checked>
radio:<input type="radio" value="V1" checked name="radio1">
select:<select size="1" name="select1">
<option selected value="option1">D1</option>
</select>
<br>
<br>
<input type="submit" name="B1" value="submit">
<input type="reset" name="B2" value="reset">
</p>
</form>
<div id="loading" style="display:none; position:absolute;
border:1px solid orange; height:20px; width:600; left: 93px; top: 112px;
background-color: #FFFFCC; cursor:pointer;" title="Click to hide" onClick="this.style.display='none';"></div>
<div id="resultDiv" style="border:1px solid orange; background-color: #FFFFCC; cursor:pointer;" title="Click to hide" onClick="this.style.display='none';">
Form 1 的提交结果将会显C在q里.
</div>
<script type="text/javascript">
var former = new AjaxFormer($('form1'), 'resultDiv');
var former2 = new AjaxFormer($('form2'));
</script>
</body>
</html>
那么W二个关键点是服务器端的表单数据读取了.q个问题跟具体的服务器有很大关系. 对于 Resin 服务器来? 问题很少, 基本上不论是 POST ?GET, Zؕ码的概率都比较小. 但是 Tomcat ׃敢恭l了, q大概也是开源品和商业产品的区? ~Z前后一致性和兼容? 因ؓ开源的不需要提供技术支? Tomcat ?GET/POST 的编码处理方式不同的版本都不一? 像 Eclipse/Netbeans 新版本从来不需要兼容老版本的插g API 一? Hibernate/Struts/Spring 也是一? 所以学 Java 的很? 当然, q就是免?开源的代h. 跑题? 因此我们的服务器端代码大部分都是?Tomcat 的ؕ码问题的解决(POST的没有问? 主要?GET Ҏ?.
<%@ page contentType="text/html; charset=gbk" pageEncoding="gbk"%>
<html>
<%
//Send some headers to keep the user's browser from caching the response.
response.addHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT" );
response.addHeader("Last-Modified", new java.util.Date().toGMTString());
response.addHeader("Cache-Control", "no-cache, must-revalidate" );
response.addHeader("Pragma", "no-cache" );
// This will emulate a network delay, for 2 sec.
//Thread.currentThread().sleep(2000);
request.setCharacterEncoding("utf-8");
%>
<%!
/**
* 转换字符串的内码.
*
* @param input
* 输入的字W串
* @param sourceEncoding
* 源字W集名称
* @param targetEncoding
* 目标字符集名U?br />
* @return 转换l果, 如果有错误发? 则返回原来的?br />
*/
public static String changeEncoding(String input, String sourceEncoding,
String targetEncoding) {
if (input == null || input.equals("")) {
return input;
}
try {
byte[] bytes = input.getBytes(sourceEncoding);
return new String(bytes, targetEncoding);
} catch (Exception ex) {
}
return input;
}
/**
* 一个类g JavaScript ?escape 函数的功? 保q可以正确传输.
*/
public static String escape(String src) {
int i;
char j;
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length() * 6);
for (i = 0; i < src.length(); i++) {
j = src.charAt(i);
if (Character.isDigit(j) || Character.isLowerCase(j)
|| Character.isUpperCase(j))
tmp.append(j);
else if (j < 256) {
tmp.append("%");
if (j < 16)
tmp.append("0");
tmp.append(Integer.toString(j, 16));
} else {
tmp.append("%u");
tmp.append(Integer.toString(j, 16));
}
}
return tmp.toString();
}
%>
<head>
<title>Test form action page</title>
</head>
<body>
q是 GBK ~码版本的后台表单提交页?<br/>
<%
boolean isTomcat = application.getServerInfo().toLowerCase().indexOf("tomcat") != -1;
%>
Form submit method:<%=request.getMethod()%><br/>
The form content u send is:<br/>
<%
java.util.Enumeration e = request.getParameterNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = request.getParameter(name);
if(isTomcat && request.getMethod().equalsIgnoreCase("GET")) {
name = changeEncoding(name, "ISO8859-1", "UTF-8");
value = changeEncoding(value, "ISO8859-1", "UTF-8");
}
out.println("<b>" + name + "</b> = " + value + "<br/>");
}
// l前台返回一个可以执行的脚本
//response.addHeader("response_script", changeEncoding("alert('提交完成');", "ISO8859-1", "UTF-8"));
response.addHeader("response_script", escape("alert('提交完成');"));
%>
</body>
</html>
booleanisTomcat=application.getServerInfo().toLowerCase().indexOf("tomcat") !=-1; q一句主要针?Tomcat q行处理, 如果?GET Ҏ的话, 需要将表单参数?ISO8859-1 转换?UTF-8 (注意不是 GBK, 貌似 Tomcat 很喜?UTF-8?). 其它的地方和原来?UTF-8 版本的没有区? 当然如果您的站点应该用过滤器来更方便的解册个问?
结:
1. 使用一致的字符集很重要, 要么全是 GBK, 要么全是 UTF-8, 如果有条? 全部用 UTF-8, 那样工作量是最的;
2. ?AJAX 提交的时候一定要按照 HTTP 的规范来, 做到和浏览器量兼容, 其?POST 的时候不要再往 URL 地址里加参数? 你那hq规! 后果是有的服务器会不搭理你传递的q些参数! q是如我所? 参数提交之前要用 encodeURIComponent() 来{? q也是ؓ了符合浏览器的习惯做?
3. 后台如果d参数有ؕ? 尽量多?ISO8859-1, GBK, UTF-8 中间多{换几ơ试? 可以试试偶写的那?changeEncoding() Ҏ, 把几个{换后的表单值都列出? 一定有一个是正确? L可以解决问题? q个本来不应该是偶们的Q? 但是写服务器的h是老美, 其?Tomcat 作? 只熟?ISO8859-1.
4. 鉴于 TOMCAT d POST 参数的时候很出问题, 因此AJAX提交表单的时候多?POST Ҏ, 量不用 GET.
q行截屏:
其它的一些资料可以参考Blogjava上的一原创文? [原创]struts,ajaxq解决Ҏ
Ƣ迎发表和更好的观点. 谢谢! 重申本文无意代替您的 AJAX 框架, 不过在你抓狂的时候可以考虑看看他们表单提交的代? Ҏ?
本h译?XMLHttpRequest 对象介绍:
Method Ҏ | Description 描述 |
---|---|
abort() | Cancels the current request 取消当前h |
getAllResponseHeaders() | Returns the complete set of http headers as a string 完整的 HTTP 头部做ؓ一个字W串q回 |
getResponseHeader("headername") | Returns the value of the specified http header q回l定?HTTP 头的?/td> |
open("method","URL",async,"uname","pswd") | Specifies the method, URL, and other optional attributes of a request
The method parameter can have a value of "GET", "POST", or "PUT" (use "GET" when requesting data and use "POST" when sending data (especially if the length of the data is greater than 512 bytes. The URL parameter may be either a relative or complete URL. The async parameter specifies whether the request should be handled asynchronously or not. true means that script processing carries on after the send() method, without waiting for a response. false means that the script waits for a response before continuing script processing |
send(content) | Sends the request 发送请?/td> |
setRequestHeader("label","value") | Adds a label/value pair to the http header to be sent 在要发送的 HTTP 头中d 标签/取?/td> |
Property 属?/th> | Description 描述 |
---|---|
onreadystatechange | An event handler for an event that fires at every state change 每次状态改变时除非的事件处理器 |
readyState | Returns the state of the object:
0 = uninitialized |
responseText | Returns the response as a string 响应做为字W串q回 |
responseXML | Returns the response as XML. This property returns an XML document object, which can be examined and parsed using W3C DOM node tree methods and properties 响应做为XMLq回. q个属性返回一?XML 文档对象, 可以?W3C ?DOM 节点树方法和属性进行检索分?/td> |
status | Returns the status as a number (e.g. 404 for "Not Found" or 200 for "OK") 状态做为数字返?例如 404 ?Not Found" 或?200 ?"OK") |
statusText | Returns the status as a string (e.g. "Not Found" or "OK") 状态做为字W串q回(例如 "Not Found" 或?"OK") |