龙行天下

  政 博
随笔 - 23, 文章 - 0, 评论 - 12, 引用 - 0
数据加载中……

2006年5月10日

FckEditor中文配置手册详细说明

javascript调用方式:
------------------------------------
<script. type=”text/javascript” src=”FCKeditor/fckeditor.js”></scrīpt>
<textarea name=”content” cols=”80″ rows=”4″>
</textarea>
<script. type=”text/javascript”>
var FCKeditor = new FCKeditor(”content”);
oFCKeditor.BasePath = “FCKeditor/”;
oFCKeditor.Height = 400;
oFCKeditor.ToolbarSet = “Default”;
oFCKeditor.ReplaceTextarea();
</script>
------------------------------------
如果想要使用从数据库读来的文本数据或者是后台来自文件的txt/html文本数据。
只要在
------------------------------------
<textarea name=”content” cols=”80″ rows=”4″>
</textarea>
------------------------------------
中加入自己的显示内容的formbean对应字段即可
------------------------------------
<textarea name=”content” cols=”80″ rows=”4″>
<c:out value=”${contentData}” />
</textarea>
------------------------------------
这样内容就会被显示在FCKeditor编辑框中了,点击提交按钮以后就可以在后台的相应java action中得到content参数中的内容就是页面上FCKeditor中的内容数据了。可以在struts/jsf中使用。
====================================
由于给FCKeditor瘦身,所以常会报缺少对象支持等错误,只要在FCKeditor/editor/lang中加上相应的js语言文件即可。如果加载页面失败(FCKeditor未定义)还有一个可能就是引用FCKeditor/fckeditor.js文件路径不对!
关于FCKeditor瘦身要点如下:
1.将FCKeditor目录下及子目录下所有以“_”下划线开头的文件夹删除
2.FCKeditor根目录下只保留fckconfig.js, fckeditor.js, fckstyles.xml, fcktemplates.xml,其余全部删除
3.将editor/filemanager/upload目录下文件及文件夹清空
4.将/editor/filemanager/browser/default/connectors/下的所有文件删除
5.还可以将editor/skins目录下的皮肤文件删除,只留下default一套皮肤(如果你不需要换皮肤的话)
6.还可以将editor/lang目录下文件删除,只保留en.js, fcklanguagemanager.js, zh-cn.js, zh.js文件
7.如果你是使用javascrīpt来调用加载FCKeditor,那么就不需要在web.xml中配置fckeditor的tag文件。
8.还有一个问题刚开始使用FCKeditor的人常会遇到就怎么控制它的toolbar的大小和元素排列,其实很简单。
在fckconfig.js中用这样的标签[]来划分每行的元素的多少,这样就可以控制toolbar的长短和大小了,具体示例参看:fckconfig.js中的toolbarset[”Default”]
====================================
用fckconfig.js中的一些选项来控制toolbarset中控件的功能,实现功能裁剪:
1):取消超链接中的浏览服务器和上传功能,方法如下:
------------------------------------
FCKConfig.LinkBrowser = true;
FCKConfig.LinkUpload = true;
改为:
FCKConfig.LinkBrowser = false;
FCKConfig.LinkUpload = false;
------------------------------------
2):取消图片链接中的浏览服务器和上传功能,方法如下:
------------------------------------
FCKConfig.ImageUpload = true;
FCKConfig.ImageBrowser = true;
改为:
FCKConfig.ImageUpload = false;
FCKConfig.ImageBrowser = false;
------------------------------------
3):Dlg Button中取消高级功能,方法如下:
FCKConfig.LinkDlgHideAdvanced = false ;
FCKConfig.ImageDlgHideAdvanced = false ;
改为:
FCKConfig.ImageDlgHideAdvanced = true ;
FCKConfig.LinkDlgHideTarget = true ;
------------------------------------
下一篇介绍FCKeditor的上传和浏览服务器功能,以及如何在里面实现动态
超连接,转发到servlet经过filter以后去调用服务器的action
如何实现对应用户浏览自己的图片的列表实现!
====================================
FCKeditor集成java servlet可以实现文件的上传和服务器端列表读取功能FCKeditor自己提供了两个servlet来分别实现上传文件功能,和读取服务器端文件列表功能,这两个servlet分别为:
com.fredck.FCKeditor.connector.ConnectorServlet(读取文件列表)
com.fredck.FCKeditor.uploader.SimpleUploaderServlet(实现文件上传)
1.浏览服务器端文件列表
------------------------------------
web.xml文件中,比如:ConnectorServlet中的配置选项:
<init-param>
<param-name>baseDir</param-name>
<param-value>/UserFiles/</param-value>
</init-param>
意思是在浏览服务器上的baseDir配置指定里面的所有文件及其目录结构列表。
如果你的baseDir没有配置,Connector将会自动创建一个默认的文件夹
UserFiles,对应的ConnectorServlet中init()方法中代码如下:
------------------------------------
baseDir = getInitParameter(”baseDir”);
if (baseDir == null)
baseDir = “/UserFiles/”;
------------------------------------
还想说一下的是,FCKeditor的client调用server的servlet方法采用的是Ajax思想来实现。当你点击浏览服务器(browser server)的时候就会触发一个异步的javascrīpt + xmlhttp的调用响应,后台的servlet会去完成你要请求的事件,然后数据以xml方式返回给client来解析。很明显,你要实现去数据库或者其他的文件系统请求列表,你只要修改
ConnectorServlet中两个私有方法:getFolders 和 getFiles
让它去你指定的地方得到文件列表即可,这样你的文件可以放在任何你指定目录下。多说一句,很多人都想知道个人blog系统中怎么实现上传文件以后对应用户浏览自己的列表的,我的做法很简单,建立你用户名的文件夹,你上传只能上传到你的目录夹,浏览可以通过程序指定浏览对应用户下的文件夹即可,这个时候你要修改Connectorservlet中的路径即可!
------------------------------------
2.超连接重定位问题
------------------------------------
FCKeditor可以插入超连接,实现对文件的预览功能,只要我们稍微改变我们可以使FCKeditor编辑器支持对任意文件系统下的任意文件的客户端浏览和下载保存!FCKeditor本来提供的是相对URL超链接,只要我们修改ConnectorServlet中传递给客户端的地址的时候,把它改写成绝对URL然后再通过我们自己的filter的servlet实现重定向去一个下载/浏览文件的struts的action方法就可以实现在客户端对超连接文件的下载和浏览!说一下具体做法吧:
1):修改ConnectorServlet传递给客户端javascrīpt的路径,代码如下:
String currentUrl = “http://” + request.getserver +request.getServerPort + request.getContextPath + resourcePath;
以上代码请在ConnectorServlet的doGet()里面拼装!在调用CreateCommonXml()私有方法的时候参数传入:
myEl.setAttribute(”path”,currentPath);
myEl.setAttribute(”url”,currentUrl);
提醒一下resourcePath为在web.xml配置文件中ConnectorServlet中的一个初始化参数配置,等一下利用filter实现对超连接的重定位就提取URL中的这个配置参数来判断,配置如下:
<init-param>
<param-name>resourcePath</param-name>
<param-value>/fileSystem/</param-value>
</init-param>
2):建立你的filter servlet,实现对URL的截获,对符合要求的URL进行重定位到你的对应action中去即可
3):实现你的对应action来实现文件的上传和下载功能即可!
4):扩展功能-实现对URL的加密,对连接的URL中加上一串字符,最后几位作为算法校验,对不符合要求的URL连接,filter将会拒绝重定位到指定action。此外利用自己写的扩展类还可以实现对超连接的文件类型进行限制,比如你只能超连接JPG|GIF|DOC|TXT|HTML等几种后缀名的文件,对其他文件即使你指定超连接也让你浏览和下载,这些都可以在web.xml中通过修改对应servlet的配置文件的初始化参数实现。
3.页面javascrīpt修改
------------------------------------
浏览服务器的功能对应的html/javascrīpt相关的文件为:browser.html和frmresourcelist.html对应你想传递的信息你可以append在文件名的字符串后面,在GetFileRowHtml()的javascrīpt函数中实现对文件名的截取,这样client只会显示文件名,而你可以得到文件的数据库唯一标识,任何你想要的信息你都可以通过修改ConnectorServlet中的私有方法getFiles()来实现,只要修改页面frmresurcelist.html中的GetFileRowHtml()中传入变量fileName即可。你还可以在点击选中文件的时候实现一个你自己的Ajax调用,一切取决你的项目需要!
4.我不是一个javascrīpt高手,其实如果我对javascrīpt了解多一些也许对客户端的代码修改以后做出更眩的功能。可以更好的完成对FCKeditor裁剪。
-------------------------------------
5.注意点
-------------------------------------
无论怎么修改别人的东西,请一定尊重开源精神!
很多人配置好了FCKeditor的上传功能以后常会遇到xmlhttp request 404 error,后面是一串路径,其实就是你的servlet-mapping中的路径不对,你只要把xmlhttp request errot 404 后面跟的路径,copy到你的web.xml中对应红色文字的位置,如下:
<servlet-mapping>
<servlet-name>Connector</servlet-name>
<url-pattern>/FCKeditor/editor/filemanager/browser/default/connectors/jsp/connector</url-pattern>
</servlet-mapping>
别忘了SimpleUploader的servlet-mapping也要做同样的修改!
还有一个错误就是http 500错误,这个可能是你的URL请求不对,应该和FCKeditor没关系的!
======================================
fckconfig.js总配置文件,可用记录本打开,修改后将文件存为utf-8 编码格式。找到:
--------------------------------------
FCKConfig.TabSpaces = 0;
改为:
FCKConfig.TabSpaces = 1;
即在编辑器域内可以使用Tab键。
如果你的编辑器还用在网站前台的话,比如说用于留言本或是日记回复时,那就不得不考虑安全了,
在前台千万不要使用Default的toolbar,要么自定义一下功能,要么就用系统已经定义好的Basic,
也就是基本的toolbar,找到:
--------------------------------------
FCKConfig.ToolbarSets[”Basic”] = [
[’Bold’,'Italic’,'-’,'OrderedList’,'UnorderedList’,'-’,/*’Link’,*/’Unlink’,'-’,'Style’,'FontSize’,'TextColor’,'BGColor’,'-’,
‘Smiley’,'SpecialChar’,'Replace’,'Preview’] ];
这是改过的Basic,把图像功能去掉,把添加链接功能去掉,因为图像和链接和flash和图像按钮添加功能都能让前台页直接访问和上传文件, fckeditor还支持编辑域内的鼠标右键功能。
FCKConfig.ContextMenu = [’Generic’,/*’Link’,*/’Anchor’,/*’Image’,*/’Flash’,'Select’,'Textarea’,'Checkbox’,'Radio’,'TextField’,'HiddenField’,
/*’ImageButton’,*/’Button’,'BulletedList’,'NumberedList’,'TableCell’,'Table’,'Form’];
这也是改过的把鼠标右键的“链接、图像,FLASH,图像按钮”功能都去掉。
找到:
FCKConfig.FontNames = ‘Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana’;
加上几种我们常用的字体
FCKConfig.FontNames = ‘宋体;黑体;隶书;楷体_GB2312;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana’;
添加文件 /TestFCKeditor/test.jsp:
----------------------------------------
<%@ page language=”java” import=”com.fredck.FCKeditor.*” %>
<%@ taglib uri=”/TestFCKeditor” prefix=”FCK” %>
<script. type=”text/javascript” src=”/TestFCKeditor/FCKeditor/fckeditor.js”></script>
<%–
三种方法调用FCKeditor
1.FCKeditor自定义标签 (必须加头文件 <%@ taglib uri=”/TestFCKeditor” prefix=”FCK” %> )
2.script脚本语言调用 (必须引用 脚本文件 <script. type=”text/javascript” src=”/TestFCKeditor/FCKeditor/fckeditor.js”></script> )
3.FCKeditor API 调用 (必须加头文件 <%@ page language=”java” import=”com.fredck.FCKeditor.*” %> )
–%>
<%–
<form. action=”show.jsp” method=”post” target=”_blank”>
<FCK:editor id=”content” basePath=”/TestFCKeditor/FCKeditor/”
width=”700″ height=”500″ skinPath=”/TestFCKeditor/FCKeditor/editor/skins/silver/”
toolbarSet = “Default”>
内容
</FCK:editor>
<input type=”submit” value=”Submit”>
</form>
–%>
<form. action=”show.jsp” method=”post” target=”_blank”>
<table border=”0″ width=”700″>
<tr>
<td>
<textarea id=”content” name=”content” style=”WIDTH: 100%; HEIGHT: 400px”>input</textarea>
<script. type=”text/javascript”>
var FCKeditor = new FCKeditor(’content? ;
oFCKeditor.BasePath = “/TestFCKeditor/FCKeditor/” ;
oFCKeditor.Height = 400;
oFCKeditor.ToolbarSet = “Default” ;
oFCKeditor.ReplaceTextarea();
</script>
<input type=”submit” value=”Submit”>
</td>
</tr>
</table>
</form>
<%–
<form. action=”show.jsp” method=”post” target=”_blank”>
<%
FCKeditor oFCKeditor ;
oFCKeditor = new FCKeditor( request, “content” ) ;
oFCKeditor.setBasePath( “/TestFCKeditor/FCKeditor/” ) ;
oFCKeditor.setValue( “input” );
out.println( oFCKeditor.create() ) ;
%>
<br>
<input type=”submit” value=”Submit”>
</form>
–%>
添加文件/TestFCKeditor/show.jsp:
<%
String content = request.getParameter(”content”);
out.print(content);
%>
====================================
1、适时打开编辑器
------------------------------------
很多时候,我们在打开页面的时候不需要直接打开编辑器,而在用到的时候才打开,这样一来有很好的用户体验,另一方面可以消除FCK在加载时对页面打开速度的影响,点击“Open Editor”按钮后才打开编辑器界面。
实现原理:
使用JAVASCRIPT版的FCK,在页面加载时(未打开FCK),创建一个隐藏的TextArea域,这个TextArea
的name和ID要和创建的FCK实例名称一致,然后点击”Open Editor”按钮时,通过调用一段函数,使用
FCK的ReplaceTextarea()方法来创建FCKeditor,代码如下:
------------------------------------
<script. type=”text/javascript”>
<!–
function showFCK(){
var FCKeditor = new FCKeditor( ‘fbContent’ ) ;
oFCKeditor.BasePath = ‘/FCKeditor/’ ;
oFCKeditor.ToolbarSet = ‘Basic’ ;
oFCKeditor.Width = ‘100%’ ;
oFCKeditor.Height = ‘200′ ;
oFCKeditor.ReplaceTextarea() ;
}
//–>
</script>
<textarea name=”fbContent” id=”fbContent”></textarea>
2、使用FCKeditor 的 API
-------------------------------------
FCKeditor编辑器,提供了非常丰富的API,用于给End User实现很多想要定制的功能,比如最基本的数据验证,如何在提交的时候用JS判断当前编辑器区域内是否有内容,FCK的API提供了GetLength()方法;
再比如如何通过脚本向FCK里插入内容,使用InsertHTML()等;
还有,在用户定制功能时,中间步骤可能要执行FCK的一些内嵌操作,那就用ExecuteCommand()方法。
详细的API列表,请查看FCKeditor的Wiki。而常用的API,请查看FCK压缩包里的_samples/html/sample08.html。此处就不贴代码了。
3、外联编辑条(多个编辑域共用一个编辑条)
--------------------------------------
这个功能是2.3版本才开始提供的,以前版本的FCKeditor要在同一个页面里用多个编辑器的话,得一个个创建,现在有了这个外联功能,就不用那么麻烦了,只需要把工具条放在一个适当的位置,后面就可以无限制的创建编辑域了。
要实现这种功能呢,需要先在页面中定义一个工具条的容器:<div id=”xToolbar”></div>,然后再根据这个容器的id属性进行设置。
JAVASCRIPT实现代码:
--------------------------------------
<div id=”xToolbar”></div>
FCKeditor 1:
<script. type=”text/javascript”>
<!–
// Automatically calculates the editor base path based on the _samples directory.
// This is usefull only for these samples. A real application should use something like this:
// oFCKeditor.BasePath = ‘/fckeditor/’; // ‘/fckeditor/’ is the default value.
var sBasePath = document.location.pathname.substring(0,document.location.pathname.lastIndexOf(’_samples’));
var FCKeditor = new FCKeditor( ‘FCKeditor_1′ );
oFCKeditor.BasePath = sBasePath;
oFCKeditor.Height = 100;
oFCKeditor.Config[ ‘ToolbarLocation’ ] = ‘Out:parent(xToolbar)’;
oFCKeditor.Value = ‘This is some <strong>sample text</strong>. You are using FCKeditor.’;
oFCKeditor.Create();
//–>
</script>
<br />
FCKeditor 2:
<script. type=”text/javascript”>
<!–
FCKeditor = new FCKeditor( ‘FCKeditor_2′ );
oFCKeditor.BasePath = sBasePath;
oFCKeditor.Height = 100;
oFCKeditor.Config[ ‘ToolbarLocation’ ] = ‘Out:parent(xToolbar)’;
oFCKeditor.Value = ‘This is some <strong>sample text</strong>. You are using FCKeditor.’;
oFCKeditor.Create();
//–>
</script>
-------------------------------------
此部分的详细DEMO请参照_samples/html/sample11.html,_samples/html/sample11_frame.html
4、文件管理功能、文件上传的权限问题
-------------------------------------
一直以来FCKeditor的文件管理部分的安全是个值得注意,但很多人没注意到的地方,虽然FCKeditor在各个Release版本中一直存在的一个功能就是对上传文件类型进行过滤,但是她没考虑过另一个问题:到底允许谁能上传?到底谁能浏览服务器文件?
之前刚开始用FCKeditor时,我就出现过这个问题,还好NetRube(FCKeditor中文化以及FCKeditor ASP版上传程序的作者)及时提醒了我,做法是去修改FCK上传程序,在里面进行权限判断,并且再在fckconfig.js里把相应的一些功能去掉。但随之FCK版本的不断升级,每升一次都要去改一次配置程序fckconfig.js,我发觉厌烦了,就没什么办法能更好的控制这种配置么?事实上,是有的。
在fckconfig.js里面,有关于是否打开上传和浏览服务器的设置,在创建FCKeditor时,通过程序来判断是否创建有上传浏览功能的编辑器。首先,我先在fckconfig.js里面把所有的上传和浏览设置全设为false,接着我使用的代码如下:
JAVASCRIPT版本:
-------------------------------------
<script. type=”text/javascript”>
var FCKeditor = new FCKeditor( ‘fbContent’ );
<% if power = powercode then %>
oFCKeditor.Config[’LinkBrowser’] = true;
oFCKeditor.Config[’ImageBrowser’] = true;
oFCKeditor.Config[’FlashBrowser’] = true;
oFCKeditor.Config[’LinkUpload’] = true;
oFCKeditor.Config[’ImageUpload’] = true;
oFCKeditor.Config[’FlashUpload’] = true;
<% end if %>
oFCKeditor.ToolbarSet = ‘Basic’;
oFCKeditor.Width = ‘100%’;
oFCKeditor.Height = ‘200′;
oFCKeditor.Value = ‘’;
oFCKeditor.Create();
</script>
-------------------------------------
在按钮旁边加文字
-------------------------------------
打开 editor/js/ 两个js文件
fckeditorcode_gecko.js
fckeditorcode_ie.js
第一个是支持非ie浏览器的
第二个文件是支持ie浏览器的
搜索 FCKToolbarButton,可以看到许多类似这样的语句:
case ‘Save’:B = new FCKToolbarButton(’Save’, FCKLang.Save, null, null, true, null, 3); break;
‘Save’是按钮英文名字
FCKToolbarButton 的四个参数分别是:
按钮命令名称,按钮标签文字,按钮工具提示,按钮样式,按钮是否在源代码模式可见,按钮下拉菜单其中将第4项参数设置为 FCK_TOOLBARITEM_ICONTEXT 即可使按钮旁边出现文字,注意没有引号。
例如:
case ‘Preview’:B = new FCKToolbarButton(’Preview’, FCKLang.Preview, null, FCK_TOOLBARITEM_ICONTEXT, true, null, 5);
这样我们就可以将 我们经常用的3种模式源代码、预览、全屏编辑按钮都加上文字了。
解释fck样式的工作原理
-------------------------------------
fck的样式设置涉及到了两个文件,一个是你定义好的样式表文件.css,另一个是告诉fck样式表如何使用的xml文件,两个文件确一不可。
css文件的位置是不做要求的,但是需要你在应用的编辑器的页面上插入样式表文件的链接。这样才能显示出来样式。
fckstyles.xml 在与editor目录同级的目录下。该文件定义了那些样式可以使用在那些标签里面。
这就是fck自带的样式xml定义:
<?xml version=”1.0″ encoding=”utf-8″ ?>
<Styles>
<Style name=”Image on Left” element=”img”>
<Attribute name=”style” value=”padding: 5px; margin-right: 5px” />
<Attribute name=”border” value=”2″ />
<Attribute name=”align” value=”left” />
</Style>
<Style name=”Image on Right” element=”img”>
<Attribute name=”style” value=”padding: 5px; margin-left: 5px” />
<Attribute name=”border” value=”2″ />
<Attribute name=”align” value=”right” />
</Style>
<Style name=”Custom Bold” element=”span”>
<Attribute name=”style” value=”font-weight: bold;” />
</Style>
<Style name=”Custom Italic” element=”em” />
<Style name=”Title” element=”span”>
<Attribute name=”class” value=”Title” />
</Style>
<Style name=”Code” element=”span”>
<Attribute name=”class” value=”Code” />
</Style>
<Style name=”Title H3″ element=”h3″ />
<Style name=”Custom Ruler” element=”hr”>
<Attribute name=”size” value=”1″ />
<Attribute name=”color” value=”#ff0000″ />
</Style>
</Styles>
每一个<style>将来会生成一个样式的菜单项。name名称就是显示在菜单里的文字;element定义了该样式可以应用在那种html标签上,<Attribute>的 name 指定了将会修改标签的哪个属性来应用样式,value则是修改成的值。
看这个:
<Style name=”Title” element=”span”>
<Attribute name=”class” value=”Title” />
</Style>
如果你在fck选定了文字 “经典论坛 》 前台制作与脚本专栏 》 FCKeditor 实战技巧 - 1 》 编辑帖子” 应用该样式 则原来文字就会变成<span class=”Title”>经典论坛 》 前台制作与脚本专栏 》 FCKeditor 实战技巧 - 1 》 编辑帖子</span>
注意:如果编辑器呈整页编辑状态,那么整页里面也需要插入样式表链接才能显示出来样式。
============================================
FCKeditor JavaScript. API(翻译整理)
原文地址:http://wiki.fckeditor.net/Developer%27s_Guide/Javascript_API
--------------------------------------------
FCK 编辑器加载后,将会注册一个全局的 FCKeditorAPI 对象。
FCKeditorAPI 对象在页面加载期间是无效的,直到页面加载完成。如果需要交互式地知道 FCK 编辑器已经加载完成,可使用“FCKeditor_OnComplete”函数。
<script. type=”text/javascript”>
function FCKeditor_OnComplete(editorInstance) {
FCKeditorAPI.GetInstance(’FCKeditor1′).Commands.GetCommand(’FitWindow’).Execute();
}
</script>
在当前页获得 FCK 编辑器实例:
var Editor = FCKeditorAPI.GetInstance(’InstanceName’);
从 FCK 编辑器的弹出窗口中获得 FCK 编辑器实例:
var Editor = window.parent.InnerDialogLoaded().FCK;
从框架页面的子框架中获得其它子框架的 FCK 编辑器实例:
var Editor = window.FrameName.FCKeditorAPI.GetInstance(’InstanceName’);
从页面弹出窗口中获得父窗口的 FCK 编辑器实例:
var Editor = opener.FCKeditorAPI.GetInstance(’InstanceName’);
获得 FCK 编辑器的内容:
oEditor.GetXHTML(formatted); // formatted 为:true|false,表示是否按HTML格式取出
也可用:
oEditor.GetXHTML();
设置 FCK 编辑器的内容:
oEditor.SetHTML(”content”, false); // 第二个参数为:true|false,是否以所见即所得方式设置其内容。此方法常用于“设置初始值”或“表单重置”操作。
插入内容到 FCK 编辑器:
oEditor.InsertHtml(”html”); // “html”为HTML文本
检查 FCK 编辑器内容是否发生变化:
oEditor.IsDirty();
在 FCK 编辑器之外调用 FCK 编辑器工具条命令:
命令列表如下:
--------------------------------------------
DocProps, Templates, Link, Unlink, Anchor, BulletedList, NumberedList, About, Find, Replace, Image, Flash, SpecialChar, Smiley, Table, TableProp, TableCellProp, UniversalKey, Style, FontName, FontSize, FontFormat, Source, Preview, Save, NewPage, PageBreak, TextColor, BGColor, PasteText, PasteWord, TableInsertRow, TableDeleteRows, TableInsertColumn, TableDeleteColumns, TableInsertCell, TableDeleteCells, TableMergeCells, TableSplitCell, TableDelete, Form, Checkbox, Radio, TextField, Textarea, HiddenField, Button, Select, ImageButton, SpellCheck, FitWindow, Undo, Redo
--------------------------------------------
使用方法如下:
--------------------------------------------
oEditor.Commands.GetCommand(’FitWindow’).Execute();
--------------------------------------------

posted @ 2008-01-09 12:52 feingto 阅读(2983) | 评论 (0)编辑 收藏

FCKEditor的赋值和取值操作

1、获取编辑器中HTML内容

function getEditorHTMLContents(EditorName)

    
var oEditor = FCKeditorAPI.GetInstance(EditorName); 
    
return(oEditor.GetXHTML(true)); 
}


2、获取编辑器中文字内容(在博客发布时获取无html代码摘要使用)

function getEditorTextContents(EditorName)

    
var oEditor = FCKeditorAPI.GetInstance(EditorName); 
    
return(oEditor.EditorDocument.body.innerText); 
}


3、设置编辑器中内容

function SetEditorContents(EditorName, ContentStr)

    
var oEditor = FCKeditorAPI.GetInstance(EditorName) ; 
    oEditor.SetHTML(ContentStr) ; 
}

posted @ 2008-01-09 12:51 feingto 阅读(2071) | 评论 (1)编辑 收藏

Script.aculo.us开发系列(八):使用DropDrag定义拖拽行为

 

在不同的浏览器上默认的拖拽能解决的问题相当少,所以有很多的框架都能实现这么个功能.使用拖拽行为能很好的改善用户体验,尤其是在购物的时候能让用户感到很新奇和体面.Script.aculo.us使用了三个类实现拖拽和排序,它们是Draggable,Droppable,Sortable.要实现一个完整的拖拽行为,需要Draggable,和Droppable的配合使用,由于这连个类的方法比较多,我只选取比较实用的几个方法进行介绍.还是老规矩,先看看Demo:http://www1.qcxy.hb.cn/qphy/Script_Aculo_Us/DragDrop.html

Draggable

new Draggable("DraggableId"[,options])

主要选项

  • snap:推拽的最小单位,默认为false,可以是数组或者函数,将这个属性设置为[50,50],意味着最小的位移单位是50px,50px,如果设置为一个函数,这个函数的参数为(x,y),这个x,y指示当前的绝对坐标,函数应该返回二维数组,上面的例子中的Drag(UnAcceptable)推拽到页面的左上角是就会"吸附"上去,就是因为函数的作用,详细见源码
  • revert:推拽完毕之后是否回到原来的位置,默认为false,也可以是一个函数,这个函数必须返回true/false
  • handle:"提手",移动整个块的时候通常不需要在整个块的区域都可以拖拽,比如移动一个栏目,通常只需要拖拽标题(比如Google的个性化主页),将该属性设置为标题的Id
  • ghosting:推拽的过程中是否显示"影子",默认为false
  • constraint:限制能拖动的方向,默认的两个方向都可以,可以设置为"vertical","horizontal"的任意
  • zindex:"影子"的z-Index属性
  • scroll:拖拽出视图范围是否显示自动滚动
  • scrollSensitivity/scrollSpeed:默认值分为为20/15,控制滚动的敏感度和滚动速度
  • delay:拖拽前的延时,开始拖拽后经过这个时间才"回过神来"

这里需要说明的是并非所有的标签都支持该行为,详细的情况请参阅官方文档

API

  • onStart:开始拖拽调用该函数,接受两个参数(obj,oEvent)前者是$(DraggableId),后者是当前事件的event对象
  • onDrag:在拖拽过程中反复的调用该函数,同样接受两个参数(obj,oEvent)
  • change:在onDrag后调用,也会反复调用
  • onEnd:拖拽行为结束调用,即鼠标弹起时激发
  • destroy():该方法销毁元素的拖拽行为

Droppables

Droppables(注意是复数形式)是一个抽象类,不能被实例化,只有一些静态方法,常用的方法有add和move,分别增加可放置元素,和去除可放置元素

add方法:Dropables.add("ContainerId"[,options]),常用的选项

  • accept: 数组或者字符串,表示该容器接受的元素的className的集合,默认的任何元素都接收
  • hoverclass:当符合接受要求的元素拖至容器上时,其className
  • onDrop():被拖拽的符合要求的元素在这里放置时调用该函数,接受三个参数(draggable,droppable,oEvent),draggable是被拖拽元素,droppable是被放置元素,oEvent当前事件对象

remove("ContainerId"),该方法去除容器的放置行为

(上面例子的源代码)

Sortable

Sortable是一组可以通过拖拽交换位置的元素,可以先看看实例(http://www1.qcxy.hb.cn/qphy/Script_Aculo_Us/Sortables.html),同样不能被实例化,常用方法create(),serialize(),destroy().下面是create("ContainerId"[,options])的常用选项

  • ghosting:拖动时是否显示"影子",默认为false
  • constraint:允许的拖动方向,默认为两个方向都可以,值为"horizontal","vertical"中的任一
  • tag:能被拖动元素的标签,默认为"li"
  • hoverclass:拖动经过可以放置的位置是,可放置的元素的className
  • dropOnEmpty:默认为false,是否在空的元素上放置
  • handle/delayscroll/scrollSensitivity/scrollSpeed::同Draggable
  • containment:数组,存放所有的放置元素的ID,参见实例的最后一个例子
  • onUpdate():该方法接受参数$("ContainerId"),在拖动到可放置位置是调用该方法
  • onChange():结束拖拽行为时调用该方法,接受参数element,表示被拖拽的元素

serialize(sortable)方法:该方法返回当前容器内元素的次序,但是要求子元素的id必须以"item_"开头,且返回格式有讲究,看下面的例子

<div id="horizontalSortable" class="item" style="margin-top:20px; height:40px;">
      <div id="item_5">IE</div>
      <div id="item_6">FireFox</div>
      <div id="item_7">Safari</div>
      <div id="item_8">Opera</div>
</div>

Sortable.create("horizontalSortable",
{
     ghosting:true,
     tag:'div',
     constraint:'horizontal',
     hoverclass:'hoverClass2'
});

Sortable.serialize('horizontalSortable')
//-->horizontalSortable[]=5&horizontalSortable[]=6&horizontalSortable[]=7&horizontalSortable[]=8

最后看一个例子,前面提到的containment选项在某些情况下很有用,比如要实现两个容器里的元素可以互相交换子元素,即从一个容器拖至令一个容器中.来看下面的例子

<script type="text/javascript">
  Sortable.create('sortUlLeft',{containment:['sortUlLeft','sortUlRight'], dropOnEmpty:
true,ghosting:true,constraint:false,hoverclass:'hoverClass'});
  Sortable.create('sortUlRight',{containment:['sortUlLeft','sortUlRight'], dropOnEmpty:
true,ghosting:true,constraint:false,hoverclass:'hoverClass'});

</script>

上面的例子可以实现sortUlLeft,和sortUlRight的子元素互相交换

posted @ 2008-01-05 14:14 feingto 阅读(548) | 评论 (0)编辑 收藏

用script.aculo.us实现像google suggest自动完成功能

 

实现像google suggest自动完成功能

首先创建一个jsp

<%@ page language="java" pageEncoding="UTF-8"%>

<html>
<head>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/effects.js"></script>
<script type="text/javascript" src="js/controls.js"></script>
<style>
div.auto_complete {
  width: 350px;
  background: #fff;
}
div.auto_complete ul {
  border:1px solid #888;
  margin:0;
  padding:0;
  width:100%;
  list-style-type:none;
}
div.auto_complete ul li {
  margin:0;
  padding:3px;
}
div.auto_complete ul li.selected {
  background-color: #ffb;
}
div.auto_complete ul strong.highlight {
  color: #800;
  margin:0;
  padding:0;
}
</style>

</head>
<body>
<input type="text" id="autocomplete"/>
<div id="results" class="auto_complete"></div>
<script type="text/javascript">
 new Ajax.Autocompleter(
  "autocomplete",
  "results",
  "list.html", {
   method: "GET"
  }
 );
</script>
</body>
</html>

 

list.html

<ul>
<li>Aria</li>
<li>Aaaa</li>
<li>Afdsa</li>
<li>bsa</li>
</ul>

上面list.html采用静态页面返回列表,读者可以使用动态页面返回结果。

posted @ 2008-01-03 09:20 feingto 阅读(1946) | 评论 (3)编辑 收藏

怎么避免浏览器缓存静态文件

对于动态文件,比如 index.asp?id=...  或者 index.aspx?id=... 相信有经验的程序员都知道怎样禁止浏览器缓存数据了.
但是对于静态文件(css,jpg,gif等等), 在什么场合下面我们需要禁止浏览器缓存他们,怎么做?

本文讨论的主题是如何防缓存, 尤其是如何防止静态文件被缓存..


在  RE:对博客园URL的一些调整建议, 二级域名不利于客户端浏览器缓存 一文中,我提到了怎么最大化的
利用浏览器缓存功能,来提高客户端浏览速度, 减轻服务器负担的.

但是事物总是一分为二的,并不是所有的场合都要使用缓存的. 有时候我们的数据被缓存了反而会给我们带来麻烦.

对于动态数据(从数据库读取生成的那些),我们可以通过以下方法来禁止浏览器缓存。

'asp 为例 禁止缓存

Response.Buffer 
= True 
Response.ExpiresAbsolute 
= Now() - 1 
Response.Expires 
= 0 
Response.CacheControl 
= "no-cache" 
Response.AddHeader 
"Pragma""No-Cache" 

对于Ajax 的请求(不管是静态数据还是动态数据):

//以下三种方法使用其中任何一种方法都可以
xmlhttp.setRequestHeader("Cache-Control","no-cache");  
//或者
xmlhttp.setRequestHeader("If-Modified-Since","0");
//或者
xmlhttp.Open(url+'?rnd='+Math.random(),....)

如果使用 prototype.js  , 用类似这样的代码 
new Ajax.Request(url,{method:"get",requestHeaders:["Cache-Control","no-cache"]})
或者
new Ajax.Request(url,{method:"get",requestHeaders:["If-Modified-Since","0"]})
 

什么情况下,要禁止静态文件缓存:
1、经常可能要改动的 js, css.
       比如 一个html 文件, test.html 在 1.0版本中。可能是这样
     <script src="common.js"></script>
     修改后  v1.1版本:
 <script src="common.js"></script>
 <script src="foo.js"></script>
   新增加了一个foo.js  同时,也改动了common.js , 在common.js 中定义了新的类,并在foo.js 中使用了common.js. 

在这种情况下如果以前用户浏览过 1.0版本的 html 文件,那么他的浏览器自动缓存了 common.js
当他浏览新版本的时候,因为使用的是 v1.1的 foo.js 和 v1.0的 common.js ,这样将导致脚本出错。


解决方法探讨:
  因为css,js 是通过 <script src=....> 这种方式加载的,所以,很难使用 asp 的那种服务器端禁止缓存的办法。也很难使用ajax的通过设置 http请求头的办法禁止使用缓存。

看来随机数是个好办法。

//方法一:
document.write("<script src='test.js?rnd="+Math.random()+"'></s"+"cript>")

//方法二:
var js=document.createElement("script")
js.src
="test.js"+Math.random()
document.body.appendChild(js)


但是,如果采用随机数的话, js文件将永远得不到缓存,每次都必须重新从服务器加载,即使没有任何更改。
大家如果经常上国外网站的话,可以看到他们通常采用这样的方式来解决:
<script src="test.js?ver=113"></script>
其中 ver=113 的 113就是版本号,一般都是采用 CVS 或其他工具生成的开发版本号。

这样真正做到了应该缓存的时候缓存静态文件,当版本有更新的时候从获取最新的版本,并更新缓存。
对于图像 <img src="test.jps?ver=在CVS的版本号"> 来有效利用和更新缓存.


唉,现在在CSDN的Web版,不知道有多少人在重复问着同一个问题。“怎么通过程序删除清空客户端的浏览器缓存”.........

 

未完待续:

下一篇:  利用浏览器缓存来改善用户体验。。。。Ajax模式之预先加载

敬请关注,等我写完再加上链接

posted @ 2008-01-03 09:19 feingto 阅读(2555) | 评论 (1)编辑 收藏

AJAX框架/库比较和选择:ECHO2, GWT, DOJO, PROTOTYPE, JQUERY

看了几篇中英文的AJAX库/框架比较文章,为方便选择使用,特归纳如下:
首先,要在两个类别中选择,一个是编译类,一个是非编译类别。
Echo2/GWT是将JAVA代码编译成JAVASCRIPT,乍看很方便,不用掌握JS也能做出炫目界面。但这只适于不会或者不想了解JS的情况,对于还是想完全控制和定制界面的项目就不适合。
另外,有一种观点认为JAVA->JS转换是一种低级语言向高级语言转换,本身没有意义。有点像去学汇编,然后再找个工具把汇编语言代码转换成C代码来用。我虽然没完全想通这个观点,不过,我一直用C/C++,这几年才逐渐发现JAVA确实是一种进化。没准别人说的是对的呢?
在Echo2和GWT中,GWT大部分工作是在客户端,尽量少跟SERVER打交道,适合大型网站运用;ECHO2信奉“用到才加载”的信条,所以会有大量向SERVER的访问,适合企业应用。另外,个人觉得ECHO2是个更全面的的一站式框架,界面也非常炫。但它的开发工具要收费。
再谈非编译类别,它们包括DOJO、PROTOTYPE、JQEURY,下面一一介绍:
先说PROTOTYPE,它比较轻量极,能让你的代码更加简化。最经典莫过于“美圆函数”:
document.getElementById(’elementid’) 变成$(’elementid’)
它加强了JS语言的可开发性,降低了学习JS的门槛。
DOJO最吸引人的是它的事件系统和丰富的可定制组件。它可以用形如下面的语句为各种HTML元素加入事件:
dojo.event.connect(someNode, "onclick", doStuff);
正由于DOJO提供了强大功能,它分成了许多包,可以分别包含使用。
JQUERY也提供了美圆函数,它的插件系统也提供象DOJO的组件,但它没有PROTOTYPE那样简洁,也没有DOJO这么多的组件供使用,但它兼收两家优点,并且个头不大,文档也算完整,所以说它介乎于前述两者之间。
所以,如果你需要非常完整的工具组件请用DOJO,如果你想优化你的JS代码,提高书写技巧请用PROTOTYPE,如果你想两者兼顾就用JQUERY。

posted @ 2007-12-30 20:37 feingto 阅读(471) | 评论 (0)编辑 收藏

prototype.js开发笔记

     摘要: Table of Contents 1. Programming Guide 1.1. Prototype是什么? 1.2. 关联文章 1.3. 通用性方法 1.3.1. 使用 $()方法 1.3.2. 使用$F()方法 1.3.3. 使用$A()方法 1.3.4. 使用$H()方法 1.3.5. 使用$R()方法 1.3.6. 使用Try.these()方...  阅读全文

posted @ 2007-12-30 18:07 feingto 阅读(405) | 评论 (0)编辑 收藏

Prototype 1.5 Ajax 使用教程

2.3  Prototype对Ajax的支持

作为一个Ajax开发框架,Prototype对Ajax开发提供了有力的支持。在Prototype中,与Ajax相关的类和对象包括:Ajax、Ajax.Responsders、Ajax.Base、Ajax.Request、Ajax. PeriodicalUpdater和Ajax.Updater,图2-3所示为这些类和对象之间的关系及其常用属性和方法,下面分别对这些类和对象进行介绍。

图2-3  Prototype中Ajax相关类和对象关系示意图

2.3.1  Ajax对象

Ajax对象为其他的Ajax功能类提供了最基本的支持,它的实现如2.2.7节中例2-10所示,其中包括一个方法getTransport和一个属性activeRequestCount。getTransport方法返回一个XMLHttpRequest对象,activeRequestCount属性代表正在处理中的Ajax请求的个数。

2.3.2  Ajax.Base类

Ajax.Base类是Ajax.Request类和Ajax.PeriodicalUpdater类的基类。它提供了3个方法:

l  setOptions:设置Ajax操作所使用的选项。

l  responseIsSuccess:判断Ajax操作是否成功。

l  responseIsFailure:判断Ajax操作是否失败(与responseIsSuccess相反)。

Ajax.Base类的主要作用是提取出一些公用的方法,其他类通过继承的方式使用这些方法,实现代码复用。

2.3.3  Ajax.Request类

这是Prototype中最经常使用的一个Ajax相关类。Ajax.Request类的方法通常是内部使用的,因此这里就不一一列举,有兴趣的读者可以参考Prototype的源代码。这里重点讲讲如何使用Ajax.Request类,首先给出一个最简单的Ajax.Request类的应用示例,如例2-11所示,注意示例中的黑体字。

例2-11  Ajax.Request类应用示例

Ajax.Request测试页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

    <head>

        <title>chapter 3</title>

        <script type="text/javascript" language="javascript"

         src="prototype.js" ></script>

        <script type="text/javascript" language="javascript">

        function test() {

            // 创建Ajax.Request对象,发起一个Ajax请求

            var myAjax = new Ajax.Request(

                'data.html', // 请求的URL

                {

                    method: 'get',  // 使用GET方式发送HTTP请求

                    onComplete: showResponse // 指定请求成功完成时需要执行的方法

                }

            );

        }

        function showResponse(response) {

            $('divResult').innerHTML = response.responseText;

        }

        </script>

    </head>

    <body>

    <input type="button" value="click" onclick="test()" />

    <div id="divResult" />

    </body>

</html>

data.html

<input type="text" id="name" />

<input type="button" value="Click Me" onclick="sayHi()">

Ajax.Request对象在初始化时需要提供两个参数:第1个参数是将要请求页面的URL,这里使用的data.html是一个普通的HTML静态页面;第2个参数是Ajax操作的选项,在Prototype中并没有专门为Ajax操作选项定义一个类,通常都是像例2-11这样,通过匿名对象的方式设置Ajax操作的参数。在例2-11中,Ajax操作选项具有两个属性:method表示HTTP请求方式,默认是POST方式;onComplete指定了Ajax操作完成以后(即XMLHttpRequest对象的status属性为4时),页面将要执行的函数。当然,Ajax操作还包括很多其他选项,如表2-1所示。

表2-1  Ajax操作选项属性含义

属性名称

含义

method

HTTP请求方式(POST/GET/HEAD)。

parameters

在HTTP请求中传入的URL格式的值列表,即URL串中问号之后的部分。

asynchronous

是否做异步XMLHttpRequest请求。

postBody

在POST请求方式下,传入请求体中的内容。

requestHeaders

和请求一起被传入的HTTP头部列表,这个列表必须含有偶数个项目,因为列表中每两项为一组,分别代表自定义部分的名称和与之对应的字符串值。

onXXXXXXXX

在HTTP请求、响应的过程中,当XMLHttpRequest对象状态发生变化时调用的响应函数。响应函数有5个:onUninitialized、onLoading、onLoaded、onInteractive和onComplete。传入这些函数的参数可以有2个,其中第1个参数是执行HTTP请求的XMLHttpRequest对象,第2个参数是包含被执行的X-JSON响应的HTTP头。

onSuccess

Ajax操作成功完成时调用的响应函数,传入的参数与onXXXXXXXX相同。

onFailure

Ajax操作请求完成但出现错误时调用的响应函数,传入的参数与onXXXXXXXX相同。

onException

Ajax操作发生异常情况时调用的响应函数,它可以接收2个参数,其中第1个参数是执行HTTP请求的XMLHttpRequest对象,第2个参数是异常对象。

2.3.4  Ajax.Updater类

例2-11使用Ajax.Request类实现了页面的局部刷新效果,而这样类似的功能在Ajax应用中是经常使用的。因此,为了简化这种工作,Prototype框架从Ajax.Requet类中派生出一个子类——Ajax.Updater。与Ajax.Request相比,Ajax.Updater的初始化多了一个container参数,该参数代表将要更新的页面元素的id。例2-11的功能通过Ajax.Updater的实现,会变得更加简单,如例2-12所示。

例2-12  Ajax.Updater类的应用示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

    <head>

        <title>chapter 3</title>

        <script type="text/javascript" language="javascript"

         src="prototype.js" ></script>

        <script type="text/javascript" language="javascript">

        function test() {

            var myAjax = new Ajax.Updater(

                'divResult', // 更新的页面元素

                'data.html', // 请求的URL

                {

                    method: 'get'

                }

            );

        }

        </script>

    </head>

    <body>

    <input type="button" value="click" onclick="test()" />

    <div id="divResult" />

    </body>

</html>

此外,Ajax.Updater类还有另外一个功能,如果请求的页面内容中包括JavaScript脚本,Ajax.Updater类可以执行其中的脚本,只需要在Ajax操作选项中增加属性“evalScripts: true”即可。对例2-11中的data.html进行修改,在其中加入JavaScript脚本,如例2-13所示。

例2-13  data.html

<script language="javascript" type="text/javascript">

sayHi = function() {

    alert("Hello, " + $F('name') + "!");

}

</script>

<input type="text" id="name" />

<input type="button" value="Click Me" onclick="sayHi()">

调用Ajax.Updater的JavaScript脚本修改为:

function test() {

    var myAjax = new Ajax.Updater(

        'divResult', // 更新的页面元素

        'data.html', // 请求的URL

        {

            method: 'get',

            evalScripts: true

        }

    );

}

这样就可以使用data.html页面的内容更新当前页面中的<div>元素divResult,并且执行data.html页面中包含的JavaScript脚本。

这里需要注意的是例2-13中sayHi函数的写法,如果写成

function sayHi() {

    alert("Hello, " + $F('name') + "!");

}

或者

var sayHi = function() {

    alert("Hello, " + $F('name') + "!");

}

程序是不能正常运行的。这是因为Ajax.Updater执行脚本是通过eval的方式,而不是将脚本内容引入到当前页面,直接声明的function sayHi或者用var声明的sayHi函数,其作用域只是在这段脚本内部,外部的其他脚本不能访问sayHi函数。而按照例2-13的方式声明的函数,其作用域是整个window。

2.3.5  Ajax.PeriodicalUpdater类

和Ajax.Request类相似,Ajax.PeriodicalUpdater类也继承自Ajax.Base类。在一些Ajax应用中,需要周期性地更新某些页面元素,例如天气预报、即时新闻等等。实现这样的功能通常要使用JavaScript中的定时器函数setTimeout、clearTimeout等,而有了Ajax.PeriodicalUpdater类可以很好地简化这类编码工作。

新建一个Ajax. PeriodicalUpdater类的实例需要指定3个参数:

l  container:将要更新的页面元素id;

l  url:请求的URL地址;

l  options:Ajax操作选项。

和Ajax.Updater类相似,Ajax.PeriodicalUpdater类也支持动态执行JavaScript脚本,只需在Ajax操作选项中增加(evalScripts: true)属性值即可。

Ajax.PeriodicalUpdater类支持两个特殊的Ajax操作选项:frequency和decay。frequency参数很容易理解,既然是定时更新页面元素,或者定时执行脚本,那么多长时间更新或者执行一次呢?frequency指的就是两次Ajax操作之间的时间间隔,单位是秒,默认值为2秒。

如果仅指定frequency参数,程序会按照固定的时间间隔执行Ajax操作。这样的更新策略合理吗?答案取决于请求URL中数据的更新频率。如果请求的数据会很有规律地按照固定频率改变,那么只要设置一个合适的frequency值,就可以很有效地实现页面的定时更新。然而实际应用中的数据往往不会那么理想,例如新闻,可能在一天中只有特定的一段时间更新频率会很高,而在其他时间则几乎没有变化。经常遇到这样的情况该怎么办呢?Ajax.PeriodicalUpdater类支持的decay属性就是为了解决这个问题而产生的。当option中带有decay属性时,如果请求返回的数据与上次相同,那么下次进行Ajax操作的时间间隔会乘以一个decay的系数。

为了比较明显地看到decay属性的效果,在请求的测试页面中加入记录时间的脚本,代码如例2-14所示。

例2-14  Ajax.PeriodicalUpdater类应用示例

ex10.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

    <head>

        <title>chapter 3</title>

        <script type="text/javascript" language="javascript"

         src="prototype.js" ></script>

        <script type="text/javascript" language="javascript">

        var str='';

        var intcount=0;

        function test() {

            var myAjax = new Ajax.PeriodicalUpdater(

                'divResult', // 定时更新的页面元素

                'script1.html', // 请求的URL

                {

                    method: 'get', // HTTP请求的方式为GET

                    evalScripts: true, // 是否执行请求页面中的脚本

                    frequency: 1, // 更新的频率

                    decay: 1 // 衰减系数

                }

            );

        }

        </script>

    </head>

    <body>

    <input type="button" value="click" onclick="test()" />

    <div id="divResult" ></div>

    <div id="divResult2" ></div>

    </body>

</html>

script1.html:

<script language="javascript" type="text/javascript">

// Ajax.PeriodicalUpdater调用函数计数

// 在<div>元素divResult2中增加一行结果,并记录当前时间和

// Ajax.PeriodicalUpdater的调用次数

intcount++;

str = $('divResult2').innerHTML;

$('divResult2').innerHTML = str + "count = " + intcount+ ": " + new Date() + "<br>";

</script>

例2-14的运行结果如图2-4所示。

图2-4  Ajax.PeriodicalUpdater类应用示例

可以看到,由于请求返回的数据一直没有发生变化,每次请求时间的间隔是上一次的2倍(decay=2)。如果某一次请求返回的数据发生了变化,那么执行请求的时间间隔则恢复到初始值。

2.3.6  Ajax.Responders对象

Ajax.Responders对象维护了一个正在运行的Ajax对象列表,在需要实现一些全局的功能时就可以使用它。例如,在Ajax请求发出以后需要提示用户操作正在执行中,而操作返回以后则取消提示。利用Ajax.Responders对象就可以实现这样的功能,如例2-15所示。

例2-15  Ajax.Responders对象应用示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

    <head>

        <title>chapter 3</title>

        <script type="text/javascript" language="javascript"

         src="prototype.js" ></script>

        <script type="text/javascript" language="javascript">

        function test() {

            var myAjax = new Ajax.Request(

                'data.html',

                {

                    method: 'get',

                    onComplete: showResponse

                }

            );

        }

        function showResponse(response) {

            $('divResult').innerHTML = response.responseText;

        }      

        var handle = {

            onCreate: function() {

                Element.show('loading'); // 当创建Ajax请求时,显示loading

            },

            onComplete: function() {

                // 当请求成功返回时,如果当前没有其他正在运行中的Ajax请求,隐藏loading

                if (Ajax.activeRequestCount == 0) {

                    Element.hide('loading');

                }

            }

        };

        // 将handle注册到全局的Ajax.Responders对象中,使其生效

        Ajax.Responders.register(handle);

        </script>

    </head>

    <body>

    <input type="button" value="click" onclick="test()" />

    <div id="divResult" ></div>

    <div id='loading' style="display:none">

        <img src="loading.gif">Loading...

    </div>

    </body>

</html>

例2-15中定义了一个handle对象,其中包含onCreate和onComplete函数。页面中发出任何一个Ajax请求时都会调用onCreate方法,而请求完成时都会调用onComplete方法。例2-15的运行结果如图2-5所示。

posted @ 2007-12-30 18:03 feingto 阅读(552) | 评论 (0)编辑 收藏

对xml进行增、删、改的很好例子

rule.hta
================

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<TITLE>XML Editer</TITLE>
<HTA:APPLICATION ID="oHTA"
APPLICATIONNAME="myApp"
BORDER="thick"
BORDERSTYLE="normal"
CAPTION="yes"
ContextMenu="yes"
ICON=""
MAXIMIZEBUTTON="yes"
MINIMIZEBUTTON="yes"
scroll="no"
selection="no"
SHOWINTASKBAR="yes"
SINGLEINSTANCE="yes"
SYSMENU="yes"
VERSION="1.0"
WINDOWSTATE="normal"
>

<style type="text/css">
</style>
</HEAD>

<script language="javascript">

// load the xml file
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.resolveExternals = false;
xmlDoc.load("rule.xml");

// load the xsl file
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
xslDoc.async = false;
xslDoc.resolveExternals = false;
xslDoc.load("rule.xsl");

// create the xslt object
var xslt = new ActiveXObject("Msxml2.XSLTemplate");
xslt.stylesheet = xslDoc;
var xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;

var checked_count = 0;
var cur_page = 1;
var total_page = 1;

function OutputDocument(number){
xslProc.addParameter("ename", number);
xslProc.addParameter("startno", (cur_page - 1)*10);
xslProc.addParameter("endno", cur_page*10);
xslProc.transform();

return xslProc.output;
}

function delete_node(node){
if( node.hasChildNodes() ) { 
var kids = node.childNodes; 
for(var i=0;i<kids.length;i++) { 
delete_node(kids);
}
}
node.parentNode.removeChild(node);
}

function delete_rule(id){
var node = xmlDoc.selectSingleNode("/rules/rule[event/id="+id+"]");
delete_node(node);
}

function modify_node(node){
node.selectSingleNode("event/id").text = modify_id.value;
node.selectSingleNode("event/name").text = modify_name.value;
if( modify_state.checked ) {
node.selectSingleNode("enable").text = "true";
} else {
node.selectSingleNode("enable").text = "false";
}
}

function modify_rule(id){
var node = xmlDoc.selectSingleNode("/rules/rule[event/id="+id+"]");
modify_node(node);
}

function add_rule(){
var id = xmlDoc.createElement("id");
id.appendChild(xmlDoc.createTextNode(add_id.value));
var name = xmlDoc.createElement("name");
name.appendChild(xmlDoc.createTextNode(add_name.value));

var event = xmlDoc.createElement("event");
event.appendChild(id);
event.appendChild(name);

var enable = xmlDoc.createElement("enable");
if( add_state.checked ) {
enable.appendChild(xmlDoc.createTextNode("true"));
} else {
enable.appendChild(xmlDoc.createTextNode("false"));
}

var rule = xmlDoc.createElement("rule");
rule.appendChild(event);
rule.appendChild(enable);

var parent = xmlDoc.selectSingleNode("/rules");
if( parent.hasChildNodes() ) {
parent.insertBefore(rule, parent.firstChild);
} else {
parent.appendChild(rule);
}
}

function gotoPage(pageno){
if( pageno < 1 ) {
cur_page = 1;
} else if( pageno >= total_page ) {
cur_page = total_page;
} else {
cur_page = pageno;
}
Transform();
}

function saveXML(){
xmlDoc.save("rule.xml");
}

function protectsubmit(val){
if( val == 1 ) { //add
if( add_id.value < 10000 || add_name.value == "" ) {
window.alert("事件号必须是5位整数且事件名不能为空");
} else if( xmlDoc.selectSingleNode("/rules/rule/event/id[. = " + add_id.value + "]") ) {
window.alert("事件号" + add_id.value + "已经存在");
} else {
add_rule();
saveXML();
Transform();
}
} else if( val == 2 ) { //modify
var id = viewTable.rows[getFirstCheckedLine()].cells[2].innerText;
if( modify_id.value < 10000 || modify_name.value == "" ) {
window.alert("事件号必须是5位整数且事件名不能为空");
} else if( id != modify_id.value && xmlDoc.selectSingleNode("/rules/rule/event/id[. = " + modify_id.value + "]") ) {
window.alert("事件号" + modify_id.value + "已经存在");
} else {
if( confirm("确认修改?") ) {
modify_rule(id);
saveXML();
Transform();
}
}
} else if( val == 3 ) { //delete
if( !confirm("确认删除?") ) {
return;
}
for( var i = 1; i < viewTable.rows.length; i++ ) {
var id = viewTable.rows.cells[2].innerText;
if( eval("viewchk_" + id + ".checked") == true ) {
delete_rule(id)
}
}
saveXML();
Transform();
} else if( val == 4 ) { //select all
checked_count = viewTable.rows.length - 1;
for( var i = 1; i < viewTable.rows.length; i++ ) {
var id = viewTable.rows.cells[2].innerText;
eval("viewchk_" + id + ".checked = true");
}
changeState();
} else if( val == 5 ) { //cancel all
checked_count = 0;
for( var i = 1; i < viewTable.rows.length; i++ ) {
var id = viewTable.rows.cells[2].innerText;
eval("viewchk_" + id + ".checked = false");
}
changeState();
}
}

function getFirstCheckedLine(){
for( var i = 1; i < viewTable.rows.length; i++ ) {
var id = viewTable.rows.cells[2].innerText;
if( eval("viewchk_" + id + ".checked") == true ) {
return i;
}
}
return 0;
}

function checkOVItem(val){
if( eval("viewchk_" + val+".checked") == true ) {
checked_count++;
} else {
checked_count--;
}
changeState();
}

function changeState(){
if( checked_count ) {
delete_btn.disabled = false;
cancel_all_btn.disabled = false;
} else {
delete_btn.disabled = true;
cancel_all_btn.disabled = true;
}
if( (checked_count + 1) == viewTable.rows.length ) {
select_all_btn.disabled = true;
} else {
select_all_btn.disabled = false;
}

if( checked_count == 1 ) {
modify_btn.disabled = false;
modify_id.disabled = false;
modify_name.disabled = false;
modify_state.disabled = false;
var id = getFirstCheckedLine();
modify_id.value = viewTable.rows(id).cells(2).innerText;
modify_name.value = viewTable.rows(id).cells(3).innerText;
if( viewTable.rows(id).cells(1).innerText == "有效" ) {
modify_state.checked = true;
} else {
modify_state.checked = false;
}
} else {
modify_btn.disabled = true;
modify_id.disabled = true;
modify_name.disabled = true;
modify_state.disabled = true;
modify_id.value="请选择一条规则";
modify_name.value="请选择一条规则";
}
}

function showPageInfo(){
if( total_item.value == 0 ) {
total_page = 1;
} else {
total_page = Math.floor((9 + parseInt(total_item.value)) / 10);
}
var txt = " 共"+total_item.value+"条记录";
var prev_page = cur_page - 1;
var next_page = parseInt(cur_page) + 1;
if( cur_page > 1 ) {
txt += " <input type='button' value='<' onClick='gotoPage(" + prev_page + ")'/>"
} else {
txt += " <input type='button' value='<' onClick='gotoPage(" + prev_page + ")' disabled/>"
}
if( cur_page < total_page ) {
txt += " <input type='button' value='>' onClick='gotoPage(" + next_page + ")'/>"
} else {
txt += " <input type='button' value='>' onClick='gotoPage(" + next_page + ")' disabled/>"
}

txt += " 第<input type='text' id='page_number' size='4' maxlength='4' value='" + cur_page + "' onBlur='gotoPage(this.value)'/>页 共" + total_page + "页";
page_info.innerHTML = txt;
// window.alert(txt);
}

function Transform(){
var txt = document.getElementById("ename").value;
var str = OutputDocument(txt);
rule_list.innerHTML = str;
checked_count = 0;
showPageInfo();
changeState();
// window.alert(str);
}
</script>

<BODY onLoad="Transform()">

<table width="550" border="1" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
<tr>
<td>
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
<TR height=5><td colspan=10 style="font-size:0px;"></td></TR>
<TR height=25>
<td colspan=3 align=center>事件名包含:</td>
<td colspan=3 align=center><input type="text" value="" id="ename" size="35" maxlength="16"/></td>
<td colspan=4><input type="button" value="搜索" onClick="Transform()"/></td>
</TR>
<TR height=1><td colspan=10 bgcolor=#2b7297></td></TR>
<TR height=30>
<td width=45 align=center><b>添加</b></td>
<td width=5 align=center><font color=gray>|</font></td>
<td width=50 align=center>事件号</td>
<td width=55 align=center><input type="text" name="add_id" value="" size="5" maxlength="5" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"></td>
<td width=55 align=center>事件名</td>
<td width=* align=center><input type="text" name="add_name" maxlength="48" value=""></td>
<td width=70 align=center>是否使用</td>
<td width=30 align=center>
<input type='checkbox' name='add_state' checked>
</td> 
<td width=5 align=center><font color=gray>|</font></td>
<td width=70 align=center><input type="button" name="add_btn" value="确定" onClick="protectsubmit(1)"></td>
</TR>
<TR height=1><td colspan=10 bgcolor=#2b7297></td></TR>
<TR height=30>
<td width=45 align=center><b>修改</b></td>
<td width=5 align=center><font color=gray>|</font></td>
<td width=50 align=center>事件号</td>
<td width=55 align=center>
<input type="text" name="modify_id" value="<请选择一条规则>" size="5" maxlength="5" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" disabled></td>
<td width=55 align=center>事件名</td>
<td width=* align=center>
<input type="text" name="modify_name" maxlength="48" value="<请选择一条规则>" disabled></td>
<td width=70 align=center>是否使用</td>
<td width=30 align=center>
<input type='checkbox' name='modify_state' disabled>
</td> 
<td width=5 align=center><font color=gray>|</font></td>
<td width=70 align=center><input type="button" name="modify_btn" value="确定" onClick="protectsubmit(2)"></td>
</TR>
<TR height=1><td colspan=10 bgcolor=#2b7297></td></TR>
<TR height=30>
<td colspan=5 align=left class=tablefont></td>
<td align=right><input type="button" name="select_all_btn" value="全部选择" onClick="protectsubmit(4)"></td>
<td colspan=2 align=right><input type="button" name="cancel_all_btn" value="全部不选" onClick="protectsubmit(5)" disabled></td>
<td align=center></td>
<td align=center><input type="button" name="delete_btn" value="删除" onClick="protectsubmit(3)" disabled></td>
</TR>
<TR height=30><td colspan=4>规则列表</td><TD colspan=6 align=right><div id="page_info" name="page_info"/></TR>
<TR>
<TD colspan=10><div id="rule_list" name="rule_list"/></TD>
</TR>
<TR height=5><td colspan=10></td></TR>
</table>
</td>
</tr>
<tr>
</tr>
</table>

</BODY>
</HTML>


rule.xml
============
<?xml version="1.0" encoding="GB2312"?>
<?xml:stylesheet type="text/xsl" href="rule.xsl"?>
<rules>
<rule>
<event>
<id>10001</id>
<name>TFTP下载文件</name>
</event>
<enable>false</enable>
</rule>
<rule>
<event>
<id>10002</id>
<name>TFTP上传文件</name>
</event>
<enable>false</enable>
</rule>
<rule>
<event>
<id>10003</id>
<name>telnet登录成功</name>
</event>
<enable>false</enable>
</rule>

</rules>

rule.xsl
=============
<?xml version="1.0" encoding="GB2312"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method= "html"/>
<xsl:param name="ename">undefined</xsl:param>
<xsl:param name="startno">undefined</xsl:param>
<xsl:param name="endno">undefined</xsl:param>

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="rules"/>
</body>
</html>
</xsl:template>

<xsl:template match="rules">
<input type="hidden" name="total_item">
<xsl:attribute name="value"><xsl:value-of select="count(rule[contains(event/name, $ename)])"/></xsl:attribute>
</input>
<TABLE id="viewTable" name="viewTable" width="100%" border="1" bordercolor="#85979f" cellSpacing="0" cellPadding="0" style="border-collapse:collapse;">
<tr height="25">
<TD width="10%" align="center">选择</TD>
<TD width="10%" align="center">状态</TD>
<TD width="10%" align="center">事件号</TD>
<TD width="*" align="center">事件名</TD>
</tr>

<xsl:for-each select='rule[contains(event/name, $ename)]'>
<xsl:sort select="event/id"/>
<xsl:if test="position()> $startno and position()<= $endno">
<tr>
<td align="center">
<input type='checkbox'>
<xsl:attribute name="name">viewchk_<xsl:value-of select="event/id"/></xsl:attribute>
<xsl:attribute name="value"><xsl:value-of select="event/id"/></xsl:attribute>
<xsl:attribute name="onClick">checkOVItem(<xsl:value-of select="event/id"/>)</xsl:attribute>
</input>
</td>
<xsl:choose>
<xsl:when test="enable[. = 'true']">
<td align="center">有效</td>
</xsl:when>
<xsl:otherwise>
<td align="center">禁用</td>
</xsl:otherwise>
</xsl:choose>
<td align="center"><xsl:value-of select="event/id"/></td>
<td><xsl:value-of select="event/name"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</TABLE>
</xsl:template>

</xsl:stylesheet>

posted @ 2007-12-29 15:44 feingto 阅读(348) | 评论 (0)编辑 收藏

prototype.js 1.4版开发者手册(强烈推荐)

     摘要: .reference table{border:1px dashed darkblue;} .reference th{border:1px dashed darkblue;color:white;background-color:darkblue;} .reference td{border:1px dashed darkblue;corlor:black;background-color:w...  阅读全文

posted @ 2007-12-29 14:59 feingto 阅读(326) | 评论 (0)编辑 收藏

showModalDialog/showModelessDialog实例,父窗口向子窗口传递值,子窗口设置父窗口的值,子窗口关闭的时候返回值到父窗口.关闭刷新父窗口

下面是showModalDialog/showModelessDialog使用例子,父窗口向子窗口传递值,子窗口设置父窗口的值,子窗口关闭的时候返回值到父窗口.关闭刷新父窗口,希望对象我这样的WEB开发的菜鸟有所帮助.

(一)showModalDialog使用例子,父窗口向子窗口传递值,子窗口设置父窗口的值,子窗口关闭的时候返回值到父窗口.


farther.html
---------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<script language="javascript">
<!--
function openChild(){

var k = window.showModalDialog("child.html",window,"dialogWidth:335px;status:no;dialogHeight:300px");
if(k != null)
document.getElementById("txt11").value = k;
}
//-->
</script>
</HEAD>

<BODY>
<br>传递到父窗口的值:<input id="txt9" type="text" value="3333333333333"><br>
返回的值:<input id="txt11" type="text"><br>
子窗口设置的值:<input id="txt10" type="text"><br>


<input type ="button" value="openChild" onclick="openChild()">
</BODY>
</HTML>
---------------------------------------------------------------
child.html
--------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<meta http-equiv="Expires" CONTENT="0">
<meta http-equiv="Cache-Control" CONTENT="no-cache">
<meta http-equiv="Pragma" CONTENT="no-cache">

</HEAD>

<BODY>
<br>父窗口传递来的值:<input id="txt0" type="text"><br>
输入要设置父窗口的值:<input id="txt1" type="text"><input type ="button" value="设置父窗口的值" onclick="setFather()"><br>
输入返回的值:<input id="txt2" type="text"><input type ="button" value="关闭切返回值" onclick="retrunValue()">
<input type ="button" value="关闭刷新父窗口" onclick="">

</BODY>
</HTML>

<script language=javascript>
<!--
var k=window.dialogArguments;
//获得父窗口传递来的值
if(k!=null)
 {
 document.getElementById("txt0").value = k.document.getElementById("txt9").value;
 }
 //设置父窗口的值
function setFather()
{
 k.document.getElementById("txt10").value = document.getElementById("txt1").value
}
//设置返回到父窗口的值
function retrunValue()
{
var s = document.getElementById("txt2").value;
window.returnValue=s;
window.close();
}
//-->
</script>

----------------------------
说明:
由于showModalDialog缓存严重,下面是在子窗口取消客户端缓存的设置.也可以在服务器端取消缓存,参考:
http://adandelion.cnblogs.com/articles/252137.html
<meta http-equiv="Expires" CONTENT="0">
<meta http-equiv="Cache-Control" CONTENT="no-cache">
<meta http-equiv="Pragma" CONTENT="no-cache">
------------------------------------------------------------------------------------------------------------------------
(二)下面是关闭刷新父窗口的例

farther.html
---------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<script language="javascript">
<!--
function openChild()
{

 var k = window.showModalDialog("child.html",window,"dialogWidth:335px;status:no;dialogHeight:300px");
 if(k == 1)//判断是否刷新
 {
  alert('刷新');
  window.location.reload();
 }
}
//-->
</script>
</HEAD>

<BODY>
<br>传递到父窗口的值:<input id="txt9" type="text" value="3333333333333"><br>
<input type ="button" value="openChild" onclick="openChild()">
</BODY>
</HTML>
----------------------------------------------------
child.html
--------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<meta http-equiv="Expires" CONTENT="0">
<meta http-equiv="Cache-Control" CONTENT="no-cache">
<meta http-equiv="Pragma" CONTENT="no-cache">

</HEAD>

<BODY>
<br>父窗口传递来的值:<input id="txt0" type="text"><br>

<input type ="button" value="关闭刷新父窗口" onclick="winClose(1)">
<input type ="button" value="关闭不刷新父窗口" onclick="winClose(0)">

</BODY>
</HTML>

<script language=javascript>
<!--
var k=window.dialogArguments;
//获得父窗口传递来的值
if(k!=null)
 {
 document.getElementById("txt0").value = k.document.getElementById("txt9").value;
 }

//关闭窗口返回是否刷新的参数.
function winClose(isRefrash)
{

window.returnValue=isRefrash;
window.close();
}
//-->
</script>

--------------------------
说明
1.下面是取消客户端缓存的:
<meta http-equiv="Expires" CONTENT="0">
<meta http-equiv="Cache-Control" CONTENT="no-cache">
<meta http-equiv="Pragma" CONTENT="no-cache">
也可以在服务器端取消缓存,参考:
http://adandelion.cnblogs.com/articles/252137.html

2.向父窗口传递阐述在ASP.NET中也可以是用aaa.aspx?id=1的方式传递.

3.不刷新父窗口的话在父窗口中直接这样一来设置可以.
<script>
window.showModalDialog("child.html",window,"dialogWidth:335px;status:no;dialogHeight:300px");
</script>
4.在子窗口中若要提交页面的话要加入:,这样就不会打开新窗口了.
<head>
<base target="_self">
</HEAD>

本文参考了:http://dev.csdn.net/develop/article/15/15113.shtm ,里面有showModalDialog/showModelessDialog的详细使用说明

posted @ 2007-12-29 14:33 feingto 阅读(1389) | 评论 (0)编辑 收藏

制作Javascript弹出窗口技巧九则

        经常上网的朋友可能会到过这样一些网站,一进入首页立刻会弹出一个窗口,或者按一个连接或按钮弹出,通常在这个窗口里会显示一些注意事项、版权信 息、警告、欢迎光顾之类的话或者作者想要特别提示的信息。其实制作这样的页面效果非常的容易,只要往该页面的HTML里加入几段Javascript代码 即可实现。下面俺就带您剖析它的奥秘。

  1、最基本的弹出窗口代码
  其实代码非常简单:
  < SCRIPT LANGUAGE="javascript">
  < !--
  window.open ("page.html")
  -->
  < /SCRIPT>
  因为这是一段Javascript代码,所以它们应该放在< SCRIPT LANGUAGE="javascript">之间。 < !-- 和 -->是对一些版本低的浏览器起作用,在这些老浏览器中不会将标签中的代码作为文本显示出来。要养成这个好习惯啊。
  window.open ("page.html") 用于控制弹出新的窗口page.html,如果page.html不与主窗口在同一路径下,前面应写明路径,绝对路径(http://)和相对路径(../)均可。
  用单引号和双引号都可以,只是不要混用。
  这一段代码可以加入HTML的任意位置,< head>和< /head>之间可以,< body>间< /body>也可以,越前越早执行,尤其是页面代码长,又想使页面早点弹出就尽量往前放。 也可以,越前越早执行,尤其是页面代码长,又想使页面早点弹出就尽量往前放。

  2、经过设置后的弹出窗口
  下面再说一说弹出窗口的设置。只要再往上面的代码中加一点东西就可以了。我们来定制这个弹出的窗口的外观,尺寸大小,弹出的位置以适应该页面的具体情况。
  < SCRIPT LANGUAGE="javascript">
  < !--
  window.open ("page.html", "newwindow", "height=100, width=400, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no")
  //写成一行
  -->
  < /SCRIPT>
  参数解释:
  < SCRIPT LANGUAGE="javascript"> js脚本开始;
  window.open 弹出新窗口的命令;
  "page.html" 弹出窗口的文件名;
  "newwindow" 弹出窗口的名字(不是文件名),非必须,可用空"代替;
  height=100 窗口高度;
  width=400 窗口宽度;
  top=0 窗口距离屏幕上方的象素值;
  left=0 窗口距离屏幕左侧的象素值;
  toolbar=no 是否显示工具栏,yes为显示;
  menubar,scrollbars 表示菜单栏和滚动栏。
  resizable=no 是否允许改变窗口大小,yes为允许;
  location=no 是否显示地址栏,yes为允许;
  status=no 是否显示状态栏内的信息(通常是文件已经打开),yes为允许;
  < /SCRIPT> js脚本结束

  3、用函数控制弹出窗口
  下面是一个完整的代码:
  < html>
  < head>
  < script LANGUAGE="JavaScript">
  < !--
  function openwin() {
  window.open ("page.html", "newwindow", "height=100, width=400, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no")
  //写成一行
  }
  //-->
  < /script>
  < /head>
  < body onload="openwin()">
  ...任意的页面内容...
  < /body>
  < /html>
  这里定义了一个函数openwin(),函数内容就是打开一个窗口。在调用它之前没有任何用途。
  怎么调用呢?
  方法一:< body onload="openwin()"> 浏览器读页面时弹出窗口;
  方法二:< body onunload="openwin()"> 浏览器离开页面时弹出窗口;
  方法三:用一个连接调用:< a href="#" onclick="openwin()">打开一个窗口< /a>
  注意:使用的"#"是虚连接。
  方法四:用一个按钮调用:< input type="button" onclick="openwin()" value="打开窗口">

  4、同时弹出2个窗口
  对源代码稍微改动一下:
  < script LANGUAGE="JavaScript">
  < !--
  function openwin() {
  window.open ("page.html", "newwindow", "height=100, width=100, top=0, left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no")
  //写成一行
  window.open ("page2.html", "newwindow2", "height=100, width=100, top=100, left=100,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no")
  //写成一行
  }
  //-->
  < /script>
  为避免弹出的2个窗口覆盖,用top和left控制一下弹出的位置不要相互覆盖即可。最后用上面说过的四种方法调用即可。
  注意:2个窗口的name(newwindows和newwindow2)不要相同,或者干脆全部为空。OK?

  5、主窗口打开文件1.htm,同时弹出小窗口page.html
  如下代码加入主窗口< head>区:
  < script language="javascript">
  < !--
  function openwin() {
  window.open("page.html","","width=200,height=200")
  }
  //-->
  < /script>
  加入< body>区:
  < a href="1.htm" onclick="openwin()">open< /a>即可

  6、弹出的窗口之定时关闭控制
  下面我们再对弹出的窗口进行一些控制,效果就更好了。如果我们再将一小段代码加入弹出的页面(注意是加入到page.html的HTML中,可不是主页面中,否则...),让它10秒后自动关闭是不是更酷了?
  首先,将如下代码加入page.html文件的< head>区:
  < script language="JavaScript">
  function closeit() {
  setTimeout("self.close()",10000) //毫秒
  }
  < /script>
  然后,再用< body onload="closeit()"> 这一句话代替page.html中原有的< BODY>这一句就可以了。(这一句话千万不要忘记写啊!这一句的作用是调用关闭窗口的代码,10秒钟后就自行关闭该窗口。)

  7、在弹出窗口中加上一个关闭按钮
  < FORM>
  < INPUT TYPE="BUTTON" VALUE="关闭" onClick="window.close()">
  < /FORM>
  呵呵,现在更加完美了!

  8、内包含的弹出窗口---一个页面两个窗口
  上面的例子都包含两个窗口,一个是主窗口,另一个是弹出的小窗口。通过下面的例子,你可以在一个页面内完成上面的效果。
  < html>
  < head>
  < SCRIPT LANGUAGE="JavaScript">
  function openwin()
  {
  OpenWindow=window.open("", "newwin", "height=250, width=250,toolbar=no,scrollbars="+scroll+",menubar=no");
  //写成一行
  OpenWindow.document.write("< TITLE>例子< /TITLE>")
  OpenWindow.document.write("< BODY BGCOLOR=#ffffff>")
  OpenWindow.document.write("< h1>Hello!< /h1>")
  OpenWindow.document.write("New window opened!")
  OpenWindow.document.write("< /BODY>")
  OpenWindow.document.write("< /HTML>")
  OpenWindow.document.close()
  }
  < /SCRIPT>
  < /head>
  < body>
  < a href="#" onclick="openwin()">打开一个窗口< /a>
  < input type="button" onclick="openwin()" value="打开窗口">
  < /body>
  < /html>
  看看OpenWindow.document.write()里面的代码不就是标准的HTML吗?只要按照格式写更多的行即可。千万注意多一个标签或少一个标签就会出现错误。记得用OpenWindow.document.close()结束啊。

  9、终极应用--弹出的窗口之Cookie控制
  回想一下,上面的弹出窗口虽然酷,但是有一点小毛病(沉浸在喜悦之中,一定没有发现吧?)比如你将上面的脚本放在一个需要频繁经过的页面里(例如首页),那么每次刷新这个页面,窗口都会弹出一次,是不是非常烦人?:-(
  有解决的办法吗?当然有!我们使用cookie来控制一下就可以了。首先,将如下代码加入主页面HTML的< HEAD>区:
  < script>
  function openwin(){
  window.open("page.html","","width=200,height=200")
  }
  function get_cookie(Name) {
  var search = Name + "=" var returnvalue = "";
  if (document.cookie.length > 0) {
  offset = document.cookie.indexOf(search)
  if (offset != -1) {
  offset += search.length
  end = document.cookie.indexOf(";", offset);
  if (end == -1)
  end = document.cookie.length;
  returnvalue=unescape(document.cookie.substring(offset, end))
  }
  }
  return returnvalue;
  }
  function loadpopup(){
  if (get_cookie("popped")=="){
  openwin()
  document.cookie="popped=yes"
  }
  }
  < /script>
  然后,用< body onload="loadpopup()">(注意不是openwin而是loadpop啊!)替换主页面中原有的< BODY>这一句即可。你可以试着刷新一下这个页面或重新进入该页面,窗口再也不会弹出了。真正的Pop-Only-Once!
  写到这里弹出窗口的制作和应用技巧基本上算是完成了,俺也累坏了,一口气说了这么多,希望对正在制作网页的朋友有所帮助俺就非常欣慰了。
  需要注意的是,JS脚本中的的大小写最好前后保持一致。 

posted @ 2007-12-29 14:24 feingto 阅读(297) | 评论 (0)编辑 收藏

jsp中的时间操作

jsp中的时间操作

经常看见jsp版里有人问时间操作的问题,这些问题一般包括:取当前时间,把一个指定的字符串时间转化成时间类型,求两个时间之间的天数,求一段时间以前的时间,求一段时间以后的时间,在这里就把这些问题汇总一下。
<%@  page  contentType="text/html;charset=gb2312"%>
<%@ page import="java.text.*"%>
<%@ page import="java.util.*"%>
<%
//字符串转化成时间类型(字符串可以是任意类型,只要和SimpleDateFormat中的格式一致即可)
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("M/dd/yyyy hh:mm:ss a",java.util.Locale.US);
java.util.Date d = sdf.parse("5/13/2003 10:31:37 AM"); 
out.println(d);
out.println("<br>");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String mDateTime1=formatter.format(d);
out.println(mDateTime1);
out.println("<br>");
out.println(d.getTime());
out.println("<br>");
//当前时间
Calendar cal  = Calendar.getInstance();
//  SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss G E D F w W a E F");
String mDateTime=formatter.format(cal.getTime());
out.println(mDateTime);
out.println("<br>");
//1年前日期
java.util.Date myDate=new java.util.Date(); 
long myTime=(myDate.getTime()/1000)-60*60*24*365;
myDate.setTime(myTime*1000);
String mDate=formatter.format(myDate);
out.println(mDate);
out.println("<br>");
//明天日期
myDate=new java.util.Date();
myTime=(myDate.getTime()/1000)+60*60*24;
myDate.setTime(myTime*1000);
mDate=formatter.format(myDate);
out.println(mDate);
out.println("<br>");
//两个时间之间的天数
SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date date= myFormatter.parse("2003-05-1");
java.util.Date mydate= myFormatter.parse("1899-12-30");
long  day=(date.getTime()-mydate.getTime())/(24*60*60*1000);
out.println(day);
out.println("<br>");
//加半小时
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
java.util.Date date1 = format.parse("2002-02-28 23:16:00");
long Time=(date1.getTime()/1000)+60*30;
date1.setTime(Time*1000);
String mydate1=formatter.format(date1);
out.println(mydate1);
out.println("<br>");
//年月周求日期
SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM F E");
java.util.Date date2= formatter2.parse("2003-05 5 星期五");
SimpleDateFormat formatter3 = new SimpleDateFormat("yyyy-MM-dd");
String mydate2=formatter3.format(date2);
out.println(mydate2);
out.println("<br>");
//求是星期几
mydate= myFormatter.parse("2001-1-1");
SimpleDateFormat formatter4 = new SimpleDateFormat("E");
String mydate3=formatter4.format(mydate);
out.println(mydate3);
out.println("<br>");
%>

posted @ 2006-05-10 10:41 feingto 阅读(665) | 评论 (1)编辑 收藏