我是很懒的人,认为懒是发展的动力,所以会不遗余力的去寻找合适的开发资源偷懒。因此每次时间不赶的任务都是找合适的资源时间比较多。于是就从DHTML开始一直跟随着技术的发展学习下来,其中经历了HTC、AJAX,收获不少,教训也不少,希望籍此文章能给大家提供一点提示和经验。
一、DHTML篇
从web开发开始,就已经知道JAVASCRIPT了,不过刚开始对我的作用就是在form提交的时候做基于客户端的验证。大概在2000年的时候,当时层的概念刚刚兴起,公司有个项目的某个输入要输入日期,就突发奇想,其实可以用层做一个javascript的日期选择,于是在公司同事的协助下写了第一DHTML的东西,日期选择器。当时还不懂封装和类什么的,所以就是一个简单的javascript函数。然后按图索骥,又写了一个颜色的选择器。不过在公司没干多久就走了,去了搞网络,很久没碰web开发了。当再次搞回web开发的时候,技术已经有更高的发展,开始流行htc了。
二、HTC篇
HTC的出现是由于IE浏览器的统治地位确立,由微软提出的一个组件化的东西,可惜因为微软的发展方向不在这里,所以也没提供太多支持和大力发展,随着技术的发展,Firefox等浏览器的兴起,就如昙花一现,不久就再没人问津了。
一般而言,HTC是组件化了的脚本过程。尽管引入浏览器的机制不同,但遵循相同的SDK规范。无论是脚本运行环境,还是DOM文档结构。但HTC有着极高 的扩展性。也就是说,HTC可以为我们的HTML引入高级的自定义行为(behavior)。例如自定义的attribute, method, 或者事件。这就说明,我们可以使用HTC机制来开发一个有着高级特性的,可重用的,可扩展的组件。
接触到HTC也是懒的结果。当时一个项目需要一个既可以输入又可以选择的列表框,于是就是满世界的找文档和例程。其实当时自己有个办法是可以实现的,就是在一个select前面放上一个input,用input遮盖住select的显示部分,只留下拉部分,可惜做出来的效果看上去比较难看,而且有很大缺憾,最主要还是懒吧,于是就去搜索现成的更好的解决办法。终于在一个论坛www.51js.com找到了,是用HTC封装的,感觉效果不错。在论坛上还发现了一个网站www.stedy.com(现在这个网站已经没有了,技术更新太快了),网站上有很多很好的HTC。自己找了一套回来用,可惜啊,好东西是好东西,但是用起来并不是很方便,还要汉化,修改也因为javascript经验不足,只能叹气,可惜了!于是继续寻找,找到了webfx.eae.net,在这里发现宝藏了,其中的toolbar、tree、grid一直用了很长一段时间,许多项目都用上了,从这时候开始感叹javascript的神奇,可以实现的东西是在是太多。从这时起就开始固定了下了一套开发模板。其中用得最多的HTC是日期选择和mask输入。而在其中的tree已经使用到了XMLHttpRequest,可以说是ajax开始初露锋芒吧。框架的思想已经开始萌芽了,只是大多都不成熟,俺是懒人啊,自然不去凑热闹了,偏安于自己的模板。但是感觉写起web应用来还是有点麻烦,不适合懒人啊。
三、AJAX
随着web2.0的报道铺天盖地的砸来,心动啊,因为听说适合懒人啊。于是就不断收集信息。终于在《程序员》杂志上找到一些框架网站。那还等什么,立马跑到各大框架网站下载测试版来研究。
<!--[if !supportLists]-->1、 <!--[endif]-->Qooxdoo
这个是好东西,widget很多,其开发模式也是习惯了的RAD开发方式。不过一直没用得上是因为没有splitbar,非常可惜。等了好几个版本居然还没这东西,真的有点晕厥了。现在终于有了,不过现在更喜欢的是Ext,更适合懒人,而且demo效果看起来比qooxdoo好多了。还有就是普遍采用JSON的定义方式,我喜欢啊。曾经用qooxdoo做个一个菜单,用的是非常传统的定义方式,一行定义一个菜单条目,然后组合到一个菜单,然后再组合到屏幕,不适合懒人啊。而且同事反映说慢,没办法啊,我用的那个包足足900多k,后来找到新的菜单条就立刻更换不用它了。不过看趋势是越来越大了,现在居然到<chmetcnv unitname="m" sourcevalue="1.1" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span lang="EN-US">1.1M</span></chmetcnv>了,怕怕。不过qooxdoo已经被CodeGear Delphi for PHP加入成为开发框架了,前途看来还不错。不过感觉qooxdoo还有一个缺陷就是本地化的问题,因为没深入研究,而且demo也没这方面的信息,所以只是感觉。
<!--[if !supportLists]-->2、 <!--[endif]-->Dojo
又是一个不错的框架。有我想要的东西,但是grid功能太弱了,于是没再深入研究,继续等待吧。
<!--[if !supportLists]-->3、 <!--[endif]-->YUI
也是一个不错的框架。看过演示后,因其grid功能不是很好,也没再深入研究。
<!--[if !supportLists]-->4、 <!--[endif]-->JQuery与prototype
忘记了是在搜索什么东西的时候搜索到了这个两个框架的。很喜欢这两个框架,曾经在两个之间进行过艰难的选择。JQuery的widget很多,但是感觉它的代码有点晦涩,可能是太灵活的缘故,有事后看那些widget的和例子简直是看天书啊。而且对它全部采用正则表达式做全文搜索感觉不是很好,老这样搜索,得花多少时间啊。所以最后还是选择了prototype,widget不多就自己想办法变通一下吧。最开始的成果是将网上基于prototype的validation的plugin和正在使用的smartform的优点进行组合写自己的校验类,同过一个JSON来定义form元件的验证。然后写了一个splitbar,可惜不进人意啊,功力太浅了,这个splitbar最大的问题就是在窗口的变化后会有很大问题,将就先用着吧,以后慢慢改。第三个目标就是通过定义json自动生成form和窗口了,这个难度不大,就是在如何生成label和定义宽度上尝试了几种办法,花了不少时间。本来还想基于dhtmlxgrid和dhtmlxmenu做一些合成开发的,但是发现不同体系的东西要结合在一起不是容易的事,于是就先这样用着吧。Prototype确实是一个不错的框架,可惜就是基于上面的开发太少了,很多时候要自己动手,对于懒人来说,实在是太痛苦了。不过我终于发现我一直期待的框架Extjs,实在是太令我兴奋了。
<!--[if !supportLists]-->5、 <!--[endif]-->Extjs
应该怎么来表达我对Extjs的喜爱呢?无法形容啊!为什么那么喜爱这个框架?因为适合我这样的懒人啊!适合我习惯的开发方式!它的对话框、layout、form的组织形式toolbar和menu的组织形式,都是我所喜欢的形式,也正是我自己想通过Prototype实现的东西,可惜自己做一个框架工程实在太大,所以只能实现部分功能,而且基于自己水平局限,实现的功能也不好。现在忽然有一个那么适合我这个懒人的东西出现,当然是无比兴奋了!越深入了解Extjs,越发觉这东西好使。不过唯一感觉不好的就是grid功能不适合我,不过这个问题不大,我灵光一闪,就用我喜欢dhtmlxgrid代替了。一个基本的开发模板也于近日完成了,懒人的未来工作就是粘贴复制然后修改,轻松啊。
四、基于AJAX开发的一些经验总结
说了很多废话了,不说了。下面就对我在这个过程中一些经验进行一点总结,希望能帮助大家。
<!--[if !supportLists]-->1、 <!--[endif]-->XMLHttpRequest提交form的时候乱码问题
这个问题在网上的答案基本上是进行再编码或者全部页面改未utf-8编码的。
习惯了用GB2312,所以不打算考虑转utf-8。
那就只有用编码转换了,研究过了网上的编码转换程序,妈妈啊,多少个循环啊,如果是我提交一个几千字设置1万字的文章(别笑话啊,有次开发就有客户说过这问题,为什么字数那么少,他的一篇东西都不能发完),这循环得处理多久啊?看来此路不通了。只好走老路了,传统提交办法:将form提交到一个隐藏的frame里面,处理完后输出一段js脚本调用主页面的脚本处理显示结果。
这个在Extjs里处理有些问题,需要一点转换,因为Extjs自己生成的form不带action,不带target,只有自己加上去了。我的办法是首先在form生成定义的时候加上一个id,例如:
addForm = new Ext.form.Form({id:'ADD-FORM-EL',labelAlign: 'left'});
然后用传统方式加上action和target:
var obj=Ext.get('ADD-FORM-EL').dom;
obj.name='ADD-FORM-EL'; //这个一定要加上,不然提交的form没提交数据
obj.target='postFrame';
obj.action='url';
因为我不是在form中加入提交按钮的,而是在对话框中加button按钮的,所以在保存按钮的单击事件中提交form:
Ext.get('loading-message').dom.innerHTML='正在更新……';
Ext.get('loadmask').show();
addDialog.buttons[0].disabled=true;
addDialog.buttons[1].disabled=true;
addDialog.buttons[2].disabled=true;
Ext.get('ADD-FORM-EL').dom.submit();
在后台处理完后就可以返回一个脚本文件,执行的是父对象定义好的脚本函数,例如返回:
window.parent.postResult(参数一,参数二,……)
而父对象的脚本是:
Function postResult t(参数一,参数二,……){
Ext.get('loading-message').dom.innerHTML='正在加载……';
Ext.get('loadmask').hide();
addDialog.buttons[0].disabled=false;
addDialog.buttons[1].disabled=false;
addDialog.buttons[2].disabled=false;
}
<!--[if !supportLists]-->2、 <!--[endif]-->asp不支持Json的返回
相当郁闷的事情,非常痛苦,主要原因大家可以参考以下两篇文章,有解决办法:
JSON character escaping function in classic ASP
http://www.webdevbros.net/2007/04/26/json-character-escaping-function-in-classic-asp
Generate JSON from VBScript (ASP) datatypes
http://www.webdevbros.net/?p=35&cp=4
我的解决办法就是,用xml,嘻嘻!
<!--[if !supportLists]-->3、 <!--[endif]-->dhtmlxgrid
Dhtmlxgrid是Scand LLC(http://www.scbr.com/docs/company.shtml)开发的基于ajax的组件之一,分商业版和开源版。
为什么我不用Ext自带的grid?而且有分页工具栏,省事很多。主要原因是我没找到不用双击就能直接编辑其中内容的方法。其实我只需要直接修改其中的checkbox就行,但是在demo里,修改了只是做个标记,实际还是没改,而dhtmlxgrid支持这功能,所以要还是选择了这个。
<!--[if !supportLists]-->4、 <!--[endif]-->combobox的返回值和显示值不同的处理
刚开始学习,参照例子,发现提交的值怎么老是显示值,而不是真正的值,百思不得其解,后来到英文论坛上搜了一下,才发现其中的奥秘,请开例子:
new Ext.form.ComboBox({
store: new Ext.data.SimpleStore(
{
fields: ["retrunValue", "displayText"],
data: [[1,'普通用户'],[3,'监控员'],[2,'系统管理员']]
}),
valueField :"retrunValue",
displayField: "displayText",
mode: 'local',
forceSelection: true,
blankText:'选择角色',
emptyText:'选择角色',
hiddenName:'txt3',
editable: false,
fieldLabel: '角色',
name: 'role',
triggerAction: 'all',
allowBlank:false
})
注意红色部分,那个就是提交值的input的name,这个才是你后台需要接收的值标记。
Extjs 我还在继续学习中,希望有兴趣的朋友一起交流经验,互相学习。