随笔-57  评论-129  文章-0  trackbacks-0
  2007年5月16日
改写了一下Java基类,添加了一个计数器。
用tomcat测试了一下连续若干次请求时创建的对象个数。

第【148259】个对象
天哪,服务器启动开始就是14万个对象。

第【148668】个对象
第【149091】个对象
第【149211】个对象
第【149291】个对象
第【149418】个对象
第【149541】个对象
第【149867】个对象
第【149947】个对象

回想一下以前人们为丑陋的struts1的单例Action的设计的辩护,真是可笑之极,哈哈哈哈
posted @ 2008-03-11 11:35 金大为 阅读(920) | 评论 (4)编辑 收藏

无意间看到的一片趣文:

希望有一天能看到文言文版的国外图书翻译,真的比较有趣,还有,不懂的时候,也可以顺带看看英文原文,也好顺便学学英语,呵呵。

引:

Thus spake the master programmer:

"When you have learned to snatch the error code from the trap frame, it will be time for you to leave."

师曰:『惑中取错之日,可出山矣。』

…..

全文见:

http://livecn.huasing.org/tao_of_programming.htm
posted @ 2007-12-01 15:27 金大为 阅读(240) | 评论 (0)编辑 收藏
我一直都想搞一个XML的模板引擎,大凡非xml的模板风格,第一感觉就是那么的不爽。
可是CommonTemplate例外。

CommonTemplate处处为程序员考虑周到的漂亮的语法风格,确实非常诱人。
具体的语法我就不一一列举了,大家可以到他的官方网站去翻阅。

挑几个亮点介绍一下:
  1. for循环的空处理,相信曾经麻烦了不少程序员吧。

    现在好了,CT支持如下语法:
       $for{}
       <tr>
          <td>1</td>
          <td>2</td>
          <td>3</td>
       </tr>
       $forelse
       <tr>
          <td colspan="3">没有数据</td>
       </tr>
       $end

  2. 大胆的关键字利用。


    <html>
        
    <body>
            $if{users != null && users.size > 0}
            
    <table border="1">
                $for{user : users}
                
    <tr>
                    
    <td>${for.index + 1}</td>
                    
    <td>${user.name}</td>
                    
    <td>${user.coins}</td>
                
    </tr>
                $end
            
    </table>
            $end
        
    </body>
    </html>


    大家看这段代码。一般来说,for这种常用关键字是不好用作id的,但是这里作为默认的循环状态对象的id。既解决了块对象存放的问题,又不会引起其他命名的冲突。一个字,妙!!!!

  3. 其他漂亮的特征:


    注释版语法外套,方便于测试数据填充及可视化编辑。
    单一的语法规则,方便解析与扩展。

    等等。。。。


好了,赞叹之余还是给出一点点遗憾:

boolean 运算有点丑陋。
我个人更期望 js的boolean运算风格,没有必要一碰到boolean 运算就返回true ? false
我们完全可以返回一个更有意义的值,比如,我更期望这个语句能如我所愿的执行。
 
${ variable|| "默认值"}

当能,如上支持,CT是有的,它的写法是
 
${ variable | "默认值"}

但是,我感觉,这个语法就有点复杂了,也不那么直观。
一般来说| 是按位取或,是位运算符,这里这个用法,跳跃的确实有点大,较难接受的。
posted @ 2007-11-29 21:28 金大为 阅读(1409) | 评论 (5)编辑 收藏
刚刚经历的一点小技巧,共享一下。

1。给代理函数加上空判断

一个组合模式的运用。代码如下:
class Composite impliments IF1,IF2,IF3{
   
private IF1 if1;
   
private IF2 if2;
   
private IF2 if2;
   
public Composite (if1,if2,if3){
   }
}

eclipse 生成指代方法>>>>

class Composite impliments IF1,IF2,IF3{
   
private IF1 if1;
   
private IF2 if2;
   
private IF2 if2;
   
public Composite (if1,if2,if3){
   }
   
public void method1(){
      if1.method1();
   }
   .
}

//正则表达式
// (\w+method\d)(\..*) if($1!=null){$0}
//>>>
class Composite impliments IF1,IF2,IF3{
   
private IF1 if1;
   
private IF2 if2;
   
private IF2 if2;
   
public Composite (if1,if2,if3){
   }
   
public void method1(){
      
if(if1= null){
         if1.method1();
      }
   }
   .
}

//还有一个构造函数里的属性赋值:
// (\w+)       this.$1=$1

结果,略

触类旁通,更多新的用法待你去发掘^_^
posted @ 2007-11-10 18:17 金大为 阅读(950) | 评论 (3)编辑 收藏
被一个貌似hsqldb bug的问题折磨了好几个小时。
把经过帖出来,大家帮我看看。

习惯把hql都写成预定义的形式,同时又为了避免过多的hql定义,我的惯用伎俩:通过如下方式定义hql。

 from Message
  
where packageKey=:packageKey
   
and ( null =  :fileKey or fileKey = :fileKey)
   
and ( null = :objectKey or objectKey= :objectKey)
   
and ( null = :memberKeys or memberKey in ( :memberKeys)) 


但是。今天在hqldb上测试时发现,在任何情况下 (null = ?)  都为真!!!
非常奇怪,害我调试了老半天,后来把数据库换成了mysql,ok!!

非常奇怪啊。
不过,上面的写法(null =  :fileKey)也有点怪怪的。
posted @ 2007-10-18 22:31 金大为 阅读(780) | 评论 (2)编辑 收藏
     摘要: 刚刚学习了一下网页动画中上的缓动效果,分享一下学习心得。 缓动曲线的概念: 缓动曲线是一个0为起点的连续函数曲线,x轴表示时间变化,y轴表示位移变化。曲线的斜率反映出运动的数度。 缓动效果在Flash动画中比较常见,用于模拟一些现实中常见的运动轨迹,或者制造一些超绚的效果。 而且新版本的Flash中,内置了一些常用的缓动曲线函数。 可惜,Flash的这些曲线函数不是开源的...  阅读全文
posted @ 2007-10-14 21:14 金大为 阅读(1210) | 评论 (0)编辑 收藏
目前为止,JSA依然是最强大的脚本压缩工具。
As i know,JSA is the most powerfull compressor for javascript.

for jquery1.2.1 (80,469 byte;)

 Compressor  beforegzip  aftergzip
  source:  80,469;  24,975;
 jquery default:  46,437;  14,641;
 yuicomressor  46,210;  14,452;
  JSA(without eval)  40,704;  13,604;
  JSA(with eval):
 26,157;   
 13,549;
 

JSA(webstart): http://www.xidea.org/webstart/JSA.jnlp
posted @ 2007-09-29 14:04 金大为 阅读(812) | 评论 (2)编辑 收藏

JSA这个压缩工具,是java编写的,需要安装java运行环境。
这多少给一些非jav程序员带来点不便。

现在我们发布servlet在线压缩版本。无需安装,在线压缩,给非Java用户一个更加便捷的使用方式。

项目主页:http://www.xidea.org/project/jsa/
现在的在线压缩服务器由Seaprince提供。
欢迎更多有空闲服务器资源的朋友安装JSA在线服务,我将在jsa项目主页提供链接,方便大家使用。

仍外,为了避免服务器资源被恶意滥用,我们默认启用了图片验证,服务频率限制等保护设置。
给用户带来些不便,敬请谅解。


posted @ 2007-08-22 16:28 金大为 阅读(996) | 评论 (5)编辑 收藏

今天无意间打开了一个CSDN上的个人blog,发现窗口无法拖动,Firefox的标签页也无法切换。

查看代码:

<script type="text/javascript">Include("Csdn.Blog.UserOnline");</script>  
<script type="text/javascript">Include("Csdn.Blog.ShowmeDataDeal");</script>

 

看到Include函数,马上可以想到,它很可能使用了动态包含脚本的设计。
//http://blog.csdn.net/scripts/jsframework.js  
window.Include=function(namespace, path)  
{  
   ..  
};  
S.load
=function(namespace, path)  
{  
     
}  

仔细阅读这两个函数代码,发现它是通过XMLHttpRequest对象同步装载脚本资源的(对IE,它采用userdata缓存优化)。而这必将导致一种完全阻塞问题(这种问题我在仍外一篇blog上描述过:http://jindw.javaeye.com/blog/66702)。

说到阻塞问题,我想大家可能会以为只是一种下载延迟,其实不然。
下载延迟不是完全阻塞,浏览器依然可以响应用户事件。而同步XHR请求阻塞是一种完全的阻塞。
浏览器在脚本运行与事件响应共用同一个线程(我的猜测)。任何脚本尚在运行时(包括被同步XHR请求阻塞的时间),浏览器将无法响应任何用户事件(无法拖放窗口、切换标签、重画页面等等,就像程序死了一样)。与普通的下载延迟造成的阻塞,感觉明显不同。

我对这个问题可以说深有体会,起初,在构建JSI1的项目站点时。因为网站放在sourceforge上,访问数度不是一般的慢,几个简单的例子,浏览器就要完全阻塞好几妙钟。正是厌恶这种完全阻塞的现象,我才开发了JSI2。

事实上,现在的一堆堆js框架中,采用XHR同步装载资源的有不少,JSVM、dojo、a9engine、hax的pies;其中JSVM, dojo都提供打包工具,将可能装载的脚本打包到启动文件中,所以也可以避免XHR同步请求。不过这样也就失去了部分动态装载的意义了。

总之,我非常讨厌这种完全阻塞现象,认为这个严重影响用户体验。
可能也有些主观因素把,希望听听大家的看法。


posted @ 2007-08-12 22:22 金大为 阅读(767) | 评论 (0)编辑 收藏
最近看见一个JavaEye上关于Java基本类型编译优化的帖子。
貌似高深莫测,其实疑点重重。吧内容转贴过来,希望在这里找到更合理的解释。
引用网上看得一些文章

 int a = 3;
 int b = 3;

  编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处 理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值

不知道真正的原理是不是那样的?

如果是的话能证明吗?

这些描述我也看过,很是不解。

如果说这种基本类型也需要用这种指针的风格,还要共享数据,那么后续的操作处理起来不是更麻烦吗?
每次写操作都要查找已有常量。甚至开辟新的空间存储新值。
再说这个指针怎么的也要个32位吧。为什么就不能直接吧值放进去,硬是要通过指针跳来跳去的,有意义吗?
这优化了吗?

反正在我看来,这是不可能的。

希望有高手出来澄清一下,给个合理的解释。

如果是对的,那也应该给出有点说服力的证据。
如果是错的,那么建议大家吧这篇文章的源头揪出来,这个确实误人不浅。

不过java对 String 这类不可变对象的处理,编译器确实有类似优化,不过也只是编译期。
这种系统类库受到点编译器的特别关注倒是很合理的。



posted @ 2007-07-30 08:29 金大为 阅读(1158) | 评论 (12)编辑 收藏

* 类库导出支持(完全脱离JSI环境)
    从JSI托管类库中,选择文件/对象集,导出为单一脚本文件,完全脱离JSI装载环境。
    也就是说,届时JSI不仅可以作为一个运行时的脚本管理框架,也可以当作一个部署时的脚本定制、打包工具。

    我是看Ext的定制工具后产生这个想法的,JSI的依赖定义API完全可以用作一个通用的脚本定制、打包工具的依赖描述语言。

* Ext集成(欢迎Ext用户加入)
    集成Ext,一方面可以弥补JSI组件的缺乏。另一方面可以优化Ext的装载延迟。
ext目前大小为:462,031字节,JSI2Alpha版的内核为35,140字节,不到Ext的十分之一(文件大小均在文本压缩之前记数)。集成Ext后,用户可以使用JSI导入函数,按需导入那些页面上直接使用到的元素。

一些细节的想法:
    初步决定使用jquery为其基础类库(prototype不必担心,JSI可以隔离脚本冲突,不会影响到prototype用户)。
    装载单元划分的两种想法:
    1.按照 http://extjs.com/download/build 中描述的定制模块划分(可能做些文件合并,避免零碎 件的装载开销)
    2.按照Ext内部包划分(Ext 下载包的packages目录下好像已经做了文件合并)

我个人还没用过Ext,非常希望有Ext用户合作。


posted @ 2007-07-12 12:35 金大为 阅读(858) | 评论 (0)编辑 收藏

大约两年前私下编写一个wiki时使用的代码生成工具,最近想继续这个wiki项目(http://sourceforge.net/projects/txdoc),也顺便吧这个代码生成工具整理出来。

PPT见:http://www.blogjava.net/jindw/archive/2007/06/30/127195.html

eclipse项目,文件太大,SF文件发布系统最近问题多多,只好分成三分上传在javaeye blog:http://jindw.javaeye.com/blog/98436

其中,代码生成工具及一些基础类库在web/WEB-INF/lib/xdoclet-xidea-plus.jar文件中(附源码)

 


目录结构
    src/main:   源文件
    src/gen:     生成的源文件及配置文件
    src/test:    测试类
    build:       ant 脚本(build.xml)、ant配置、构建过程的临时目录(temp)
    web:         web根目录
    lib:          编译器附加类库(如ant任务需要的lib)
    doc:         文档目录
    doc/xdoclet: xdoclet参考文档
   
   
一.创建持久类:
  1.改类为一个有诺干属性的简单java类
  2.为持久类打上hibernate标记:
     必要标记:hibernate.class(指定该类为持久类,无必选属性,可选属性参考xdoclet文档)
            hibernate.id (指定持久类主键,必选属性generator-class,指定主键生成算法,常用算法有uuid.hex、hilo、assigned....)
     常用标记:hibernate.property(指定持久属性,无必选属性)
            hibernate.cache(预定义查询,必选属性 name,query)
            hibernate.one-to-many,hibernate.many-to-one等,指定对象关系,比较复杂,建议先看hibernate官方文档、xdoclet文档
             
  3.打开项目下build/build.xml、运行hibernate任务,该任务将生成hibernate映射文件、hibernate dao实现、hibernate的spring配置,及dao配置。
    其中hibernateDao实现常用DAO方法,并定义以后将使用的常量:如预定义查询名、预定义查询参数名、集合名,等等。
   
  4.持久类的路径一般为:src/main/{package}/po/{TableName}.java ,生成的DAO路径为src/main/{package}/dao/{TableName}Dao.java
 
二.创建Spring服务实现:
  1.Spring服务实现无任何接口约束,普通java对象即可。
  2.将需要使用的hibernate Dao 声明为该服务类的属性(spring.property标记)。
  3.为服务类打上spring标记:
    必要标记:spring.bean(parent:对于所有需要spring事务支持的javabean,必须声明parent属性值为"transactionProxy";
             生成工具将根据类名为spring bean自动生成默认 id,)
    常用标记:spring.property(spring 属性)。
          spring.transaction(对于parent=transactionProxy的bean,需要为需要声明是事务支持的方法声明事务属性,具体请参考xdoclet文档)
  4.打开项目下build/build.xml、运行spring任务,该任务将生成spring配置文件。
 
三.创建XWork Action,一般为*/action/*.java
  1.Action需要实现com.opensymphony.xwork.Action,如果我们需要xwork的国际化支持,继承ActionSupport基类,必然需要实现TextProvider接口。
  2.为Action打上xwork标记:
    必要标记:xwork.package(必要属性有name),
            xwork.action(必要属性name,表示某方法为Action方法,将映射到一个具体的url地址),
            xwork.result(必要属性name,该标记定义在定义了xwork.action的地方,可定义多个,表示该Action的结果集)
    常用属性: xwork.spring-ref (属性的set方法上,其值将从spring context中获取)
   
  3.为Action制作结果集页面:
    若未在 xwork.result标记中定义value属性,其值未ActionName+"-"+resultName,若有大写字符,将用"-"隔开,并转小写;
    value值即未页面地址。可以为jsp,velocity,xsl等等。
 
  4.打开项目下build/build.xml、运行xwork任务,该任务将生成xwork配置文件。
 
 

 
posted @ 2007-07-06 14:37 金大为 阅读(1033) | 评论 (1)编辑 收藏

带ID的函数表达式:

var fn = function fnid(){};  

按照ECMA262定义,上面这段脚本等价于:

with({fnid:null}){  
  
var fn = fnid = function(){};  
}  

 


注意:fnid在with外是不可见的,但是IE没有严格遵守ECMA规范(同样的情况发生在catch语法上)。在IE上相当于:
var fnid = function(){};  
var fn = fnid;  

在刚刚发布的JSA1beta上,还不能处理这个问题(新版本将这周内发布)。同时,鉴于这种语法在不同浏览器上表现不同,还是建议尽量避免使用(这点上,我个人还是更喜欢ie的方式)。

var语句:
太常用了,但是,没有注意还是很容易出问题。
var 用来声明全局或函数变量,但是,只是申明,重复申明也不能置空,范围是函数或者全局空间,位置在函数或脚本顶端,与块无关,这些与常用高级语言区别很大。

怪癖的代码

var vaiable =0;  
function test(){  
   variable 
=1;//别担心,不会改动全局变量vaiable  
   //do ..  
   var vaiable;//变量申明无顺序(一律置顶),只是赋值有顺序。  
}  

 

常见错误有:

var flag;//这里可能有人(包括我自己)喜欢自做聪明的利用一下变量的初始值undefined  
while(!flag){//没准那个角落里面已经给当前函数内同名变量给赋值了就惨了  
  //..  
}  

 

posted @ 2007-06-30 16:47 金大为 阅读(1239) | 评论 (3)编辑 收藏

已经有一年多没做java这块了,今天翻出这个一年前写的代码生成工具,准备开放出来,或许对某些人还有点用处。

这个代码生成器是基于xdoclet2的改进版。
  所做工作:
  * 生成Hibernate 映射文件及相应得spring的配置文件。
  * 生成Hibernate DAO 文件及命名查询名称常量(新)。
  * 生成Spring配置文件(支持事务申明)。
  * 生成xwork配置文件(增加多包及spring属性支持)。
  * 验证资源冗余及缺失。

先吧PPT放出来,如果有人(包括我自己)能用上再吧代码整理一下,放出来。


ppt下载:
http://www.blogjava.net/Files/jindw/codegen.rar

posted @ 2007-06-30 08:44 金大为 阅读(996) | 评论 (6)编辑 收藏

装饰引擎简介:

系统默认的装饰引擎为:org.xidea.decorator.DecoratorEngine。
JSI装载后,将做如下操作:
  1. 判断有无装饰器命名空间声明(xmlns:d= "http://www.xidea.org/taglib/decorator")
  2. 若有,将在文档装载结束后,启动装饰引擎,初始化当前可用的装饰提供者表。(装饰提供者是一个JavaScript包,在注册这种装饰包时可同时指定他的别名,别名*表示默认包)
  3. 遍历当前文档,凡是该命名空间的节点,都被看作需要装饰的元素。若当前文档存在装饰元素,启用遮罩(关机效果),页面将不可操作(仍可查阅)。
  4. 查找装饰元素对应的装饰类(通过tagName判断类名),采用异步方式动态装载这些装饰器类(不会装载到全局空间),并更新当前进度信息,同时设置装饰器之间的关系(parent,children)。
  5. 以深度遍历的方式遍历这些节点,注册组件(以后可以通过$JSI.getComponent函数获取装饰器对象),依次执行他们的before操作,和decorate操作。
  6. 完成装饰,取消遮罩,页面进入可用状态。

装饰器规范简介:

装饰器指的是所有拥有decorate成员方法的类。一般来说,可将一组装饰器归为同一个包中(太复杂的装饰器,可将具体逻辑放置在其他包中),能后在配置文件中定义装饰包。
scripts/config.js   $JSI.addDecoratorProvider("org.xidea.decorator","xidea","*");

装饰器类包含两个方法before、docorate分别在遍历前(子节点未装饰)和遍历后(子节点装饰完成)调用。

同时,装饰引擎遍历时还将注入如下三个属性:
  1. parent:父装饰器
  2. children:子装饰器集合
  3. attributes:装饰器属性集对象(只有一个成员函数:get(attrName)  )

JSI现有装饰器集合简介

目前JSI2最高版本2.0预览版 (2007-04-16)包含如下装饰器:
  1. DatePicker
    日期选择控件,参照xul datepicker标签,支持弹出方式(默认值 type='pop'),和内嵌式(type='grid')
  2. Editor
    编辑器控件,参照xul editor标签
  3. Spinner
    Spinner控件(window时间日期管理中,年份调节的控件),参照backbase 的 Spinner标签
  4. TabBox、Tabs、Tab、TabPanels、TabPanel
    TabBox(标签页)控件,参照xul tabbox标签
  5.  Code
    代码语法高亮显示控件,参照SyntaxHighlighter的显示风格
  6. Include
    片断包含标签,支持xpath选取文档片断,支持xslt转换

这些装饰器的演示见:
http://www.xidea.org/project/jsi/decorator/index.html

目前JSI自带的装饰器不够丰富,而且都还是初级阶段,不够完善。现在发布的这些装饰器,主要是为了演示JSI的工作方式,编码风格,希望能吸引第三方团队、公司在这个基础上开发出自己的更加实用的装饰器集合。

JSI及其装饰引擎采用LGPL协议。可以商业应用,当能,更希望能开源。

目前就我一人之力,开发一套完整的装饰器,尚需时日,这次将这个半成品拿出来演示,主要是为了展示一下jsd的风格,希望能吸引其他开发者,共同参与这个工程,有兴趣丰富JS自带I装饰器集合的网友,请msn与我联系:jindw◎xidea。org
posted @ 2007-06-27 10:35 金大为 阅读(748) | 评论 (0)编辑 收藏
JSI组件模型是一种用来装饰简单html元素的框架,使用简单的xml标记,标识其装饰行为,比如将一个普通的input装饰成一个日期输入控件,将一 个html ul标记装饰成菜单或树,将一个textarea装饰成一个代码语法高亮显示区域,或一个wysiwyg html编辑器。
JSI启动后将自动检查decorator标记,构建层次结构,自动做相关类的寻找、导入和装饰操作;实现零脚本代码的web富客户端编程。

代码示例:

  1. 日期选择器 (DatePicker):

     <d:datepicker>  
      
    <input type="text" name="test2" />  
    </d:datepicker>   

  2. 编辑器示例 (Editor):

     <d:editor>  
      
    <textarea name='editorText'>This is some <strong>sample text</strong>. You are using <a  
        
    href="http://www.fckeditor.net/">FCKeditor</a>.</textarea>  
    </d:editor>   

  3. Spinner控件(Spinner 类似window时间日期管理中,年份调节的控件):
     <d:spinner start='0' end='8' step='2'>  
      
    <input type="text" name="test2" value='0' />  
    </d:spinner>   

  4. 客户端包含(Include):
     <d:include url='menu.xml' xslt="menu.xsl"></d:include>    

  5. 代码语法高亮显示控件(Code):
     <d:code language="js">  
     
    <textarea>alert(‘Hello World’)</textarea>  
    </d:code>   

  6. 标签页控件(TabBox参照xul tabbox标签):

     <d:tabbox>  
      
    <d:tabs>  
        
    <d:tab>tab1</d:tab>  
        
    <d:tab>tab2</d:tab>  
        
    <d:tab>tab3</d:tab>  
      
    </d:tabs>  
      
    <d:tabpanels>  
        
    <d:tabpanel>content1</d:tabpanel>  
        
    <d:tabpanel>content2</d:tabpanel>  
        
    <d:tabpanel>content3</d:tabpanel>  
      
    </d:tabpanels>  
    </d:tabbox>   


  7. 综合示例:
来一个复杂一点的完整的例子,以日期选择控件的演示页面为例
页面上有: 标签页装饰器(TabBox….)、源代码高亮显示装饰器(Code)、日期选择装饰器(DatePicker)、包含装饰器(Include)
<?xml version="1.0" encoding="utf-8"?>  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml"  
  xmlns:d
="http://www.xidea.org/taglib/decorator" xml:lang="zh_CN"  
  lang
="zh_CN">  
<head>  
<script src="../scripts/boot.js"></script>  
<title>DatePicker 示例</title>  
</head>  
<body>  
<h2>DatePicker 示例</h2>  
<!-- 开始标签页装饰器 -->  
<d:tabbox>  
  
<d:tabs>  
    
<d:tab>效果</d:tab>  
    
<d:tab>代码</d:tab>  
  
</d:tabs>  
  
<d:tabpanels>  
    
<d:tabpanel>  
      
<!-- 开始日期装饰器(内嵌式) -->  
      
<d:datepicker type='grid'>  
        
<input type="text" name="test1" />  
      
</d:datepicker>  
      
<!-- 开始日期装饰器(弹出式) -->  
      
<d:datepicker>  
        
<input type="text" name="test2" />  
      
</d:datepicker>  
    
</d:tabpanel>  
    
<d:tabpanel>  
      
<!-- 开始代码高亮显示 -->  
      
<d:code language="xml">  
        
<textarea>  
      
&lt;!-- 开始日期装饰器(内嵌式) --&gt;  
      
&lt;d:datepicker type='grid'&gt;  
        
&lt;input type="text" name="test1" /&gt;  
      
&lt;/d:datepicker&gt;  
      
&lt;!-- 开始日期装饰器(弹出式) --&gt;  
      
&lt;d:datepicker&gt;  
        
&lt;input type="text" name="test2" /&gt;  
      
&lt;/d:datepicker&gt;</textarea>  
      
</d:code>  
    
</d:tabpanel>  
  
</d:tabpanels>  
</d:tabbox>  
<select style="margin-left:120px"><option>弹出的datepicker 可覆盖IE select</option></select>  
<hr />  
<!-- 开始Include装饰器,包含装饰器菜单 -->  
<d:include url='menu.xml' xslt="menu.xsl"></d:include>  
</body>  
</html> 



装饰结果:






云想衣裳花想容--JSI组件模型介绍(二)已经发布,那里有装饰过程及其原理的介绍:
http://www.javaeye.com/topic/71425


posted @ 2007-06-27 10:24 金大为 阅读(804) | 评论 (0)编辑 收藏

众所周知, Scriptaculous所依赖的Prototype库与jQuery存在冲突。所以同时使用比较困难。

JSI针对每一个装载的脚本都有完全独立的执行上下文。所以这个问题能在JSI上彻底解决。

下面的例子,我们将在同一个页面上同时使用Scriptaculous jQuery 类库。证实一下JSI隔离冲突功能。

示例页面(hello-jquery-aculo.html):

<html> 
<head> 
<title>Hello jQuery And Scriptaculous</title> 
<!-- 加入引导脚本 --> 
<script src="../scripts/boot.js"></script> 
<script> 
//导入jQuery  
$import(
"org.jquery.$"); 
//导入Scriptaculous  
$import(
"us.aculo.script.Effect");  
 
  
$(document).ready(
function(){ 
  
//使用jQuery添加一段问候语 
  $(
"<p id='helloBox' style='background:#0F0;text-align:center;font-size:40px;cursor:pointer;'>Hello jQuery And Scriptaculous</p>")       .appendTo('body');  
  $('#helloBox').ready(
function(){  
   
//使用Scriptaculous高亮显示一下刚才添加的内容  
    new Effect.Highlight('helloBox');  
  }).click(
function(){  
   
//当用户单击该内容后使用jQuery实现渐出  
    $('#helloBox').fadeOut();  
  });  
 });  
</script>  
</head>    
<body>    
<p>文档装载后,jQuery将在后面添加一段问候语;并使用Scriptaculous高亮显示(Highlight);在鼠标点击后在使用jQuery渐出(fadeOut)。</p>  
</body>  
</html>  

posted @ 2007-06-26 07:46 金大为 阅读(787) | 评论 (0)编辑 收藏
Java的成功,离不开它那个庞大的类库,不单是sun的类库,很多细节的实现都取自第三方(如xml解析采用Apache的实现)。

JSI暂时不大算编写丰富的公共API,但是我们可以集成其他成熟的类库,同时隔离他们的依赖,隔离各个脚本的执行上下文,消除命名冲突的危险。

这里我们详细介绍一个复杂一点的实例:类似Windows XP文件浏览器左侧的滑动折叠面板(任务菜单)效果。

我们先集成Scriptaculous Effect类库,并且在这个基础上按我个人的习惯对一个面板折叠效果做一个简单的封装,展示框架的类库封装功能。

1。集成Scriptaculous类库:

这里我们不做过多介绍,详细情况请参考集成实战;我们发布的版本中已经把Scriptaculous放置于us.aculo.script包中,您可以把这些作为系统内置的类库使用。

2。编写我们的折叠面板函数(example/effect.js):
/*
 * 滑动面板实现. 
 * 当指定元素可见时,将其第一个子元素向上滑动至完全被遮掩(折叠)。 
 * 当指定元素不可见时,将其第一个子元素向下滑动至完全显示(展开)。 
 
*/  
function slidePanel(panel){  
  panel 
= $(panel);  
  
if(panel.style.display=='none'){  
    
//调用Scriptaculous Effect的具体滑动展开实现  
    new Effect.SlideDown(panel);  
  }
else{  
    
//调用Scriptaculous Effect的具体滑动闭合实现  
    new Effect.SlideUp(panel);  
  }  
}  

3。编写包定义脚本(example/__$package.js):
//添加slidePanel(滑动面板控制)函数  
this.addScript("effect.js","slidePanel",null);  
//给effect.js脚本添加对us.aculo.script包中effects.js脚本的装载后依赖this.addScriptDependence("effect.js",  
"us/aculo/script/effects.js",false);

4。在网页上运用上面的类库:
<html>  
  
<head>   
  
<title>重用aculo Effect脚本实例</title>  
  
<link rel="stylesheet" type="text/css" href="/styles/default.css" />  
  
<script src="/scripts/boot.js"></script>  
  
<script>  
    $import(
"example.slidePanel");  
  
</script>  
  
</head>  
  
<body>  
    
<div class="menu_header"  
        onclick
="slidePanel('menu_block1')">  
        面板 1  
    
</div>  
    
<div class="menu_block" id="menu_block1">  
      
<ul>  
        
<li>text1</li>  
        
<li>text2</li>  
        
<li>text3</li>  
      
</ul>  
    
</div>  
</body>  
</html> 

onclick="slidePanel('menu_block1')"这个事件函数将在我们点击面板标题时触发,能后会调用Scriptaculous Effect的具体实现去实现我们需要的滑动折叠功能。


 

壁立千仞 无欲则刚――控制依赖


java可以随意的使用第三方类库,可是JavaScript却没那么幸运,随着类库的丰富,烦杂的依赖关系和可能的命名冲突将使得类库的发展越来越困难。程序的易用性也将大打折扣。

命名冲突的危险无形的增加你大脑的负担;随着使用的类库的增加,暴露的依赖也将随之增加,这是复杂度陡增的极大祸根,将使得系统越来越复杂,越来越难以控制。潜在的问题越来越多,防不胜防。

JSI的出现,可以解决上述问题,我们建议类库的开发者将自己类库的依赖终结在自己手中,避免依赖扩散,以提高类库的易用性。

同样使用上面的例子,假如我们想抛开JSI,实现同样的功能,那我们的页面代码将是(类库代码不用改动):

<html>  
  
<head>   
  
<title>重用aculo Effect脚本实例</title>  
  
<link rel="stylesheet" type="text/css" href="/styles/default.css" />  
  
<!--  
  <script src="/scripts/boot.js"></s cript>  
  <script>  
    $import("example.slidePanel");  
  </sc ript>  
   
-->  
<script src="/scripts/net/conio/prototype/v1_5/prototype.js">  
</script>  
<script src="/scripts/us/aculo/script/v1_7/effects.js">  
</script>  
<script src="/scripts/us/aculo/script/v1_7/builder.js">  
</script>  
<script src="/scripts/example/effect.js">  
</script>  
  
</head>  
  
<body>  
    
<div class="menu_header"  
        onclick
="slidePanel('menu_block1')">  
        面板 1  
    
</div>  
    
<div class="menu_block" id="menu_block1">  
      
<ul>  
        
<li>text1</li>  
        
<li>text2</li>  
        
<li>text3</li>  
      
</ul>  
    
</div>  
</body>  
</html>  

这个例子的html代码明显比上面的复杂了,一堆堆的script标签,而且还是有序的;还出现在页面上,重构起来也极其麻烦。

可以看出,JSI的加入可以让类库更加易用,html代码更为简洁,最终用户已经不必关心所用类库的依赖了。

JSI中每一个脚本有一个单独的执行上下文。各个脚本顶部变量你可以随便使用,不必担心不同脚本中的命名冲突,不会污染全局变量空间,这种方式可以用于解 决某些类库间变量冲突的问题(如jQuery和Prototype的$函数)。我们甚至可以做到同一个页面上间接加载同一种类库的两个不同版本,不相互影 响。

使用JSI后,很多细节我们可以在包中封装掉,不需要告诉类库使用者太多。大大增加类库的易用性。同时,类库封装的支持可以让我们在第三方库的基础上轻松的按自己的喜好编写自己的类库,同时避免依赖扩散造成的复杂度增加。

使用JSIntegration唯一多出的负担就是编写包定义文件,不过想想这种定义文件可是一劳永逸的(以后就不需要每次导入脚本的时候都小心翼翼的判 断那个脚本先导入那个后导入,有那些间接使用到的类库需要导入,等等),而且有了包结构后对于代码组织、重用,以及文档的编写阅读,都将非常有利。
posted @ 2007-06-25 10:14 金大为 阅读(651) | 评论 (0)编辑 收藏

何谓安需装载?

脚本程序一般都是下载后执行 ,当脚本库非常庞大时,一次性下载起来非常费时,传统的解决方式是,按功能模块把脚本写在不同的文件中,页面上手动加入script标签装载指定内容,但 是这有一些缺点,类库的使用者需要知道没个脚本之间的关系,顺序要求等等,而不可能要求每个类库使用者都对其非常熟悉,出错的可能性很大。于是很多框架开 始支持导入指令,想使用什么一个导入函数就完了,不必一堆堆的script文件,不用小心翼翼的关注着他们的依赖关系。

安需装载可分如下三种模式:

  • 即时同步按需装载阻塞,JSI、JSVM、dojo)
    最简单的按需装载实现,通过XMLHttpRequest同步装载脚本文件实现。问题是,浏览器使用这种方式同步获取资源时将导致浏览器阻塞:停止响应用户事件、停止页面重画操作。所以,虽然编程最为简单,但是用户体验最差。
  • 异步装载无阻塞,JSI2.0+)。
    异步导入,不必多做解释,用户体验好,但是因为其异步特征,处理起来比较麻烦。
  • 延迟同步按需装载无阻塞,JSI2.0+)
    JSI通过动态预装载功能实现的一种同步获取资源的方法,虽然也是同步,但没有阻塞,可以算时兼顾易用性和用户体验的机决方按。缺点时
    有一定延迟,当前脚本标签中不可用。

使用方法(JSI示例)

以一个代码语法着色程序为例:
类库位置:example/codedecorator/code.js
页面位置:example/xxx.html
  • 即时同步按需装载
    $import("example.codedecorator.Code");

    var code1 = new Code();
    code1.id 
    = "libCode";
    code1.decorate(); 

  • 异步装载
    $import("example.codedecorator.Code",function(Code){
     
    var code1 = new Code();
     code1.id 
    = "libCode";
     code1.decorate();
    }) 

  • 延迟同步按需装载无阻塞,JSI2.0+)
    <script>"../scripts/boot.js"></script>
    <script>
    $import(
    "example.codedecorator.Code",true);
    </script>

    <script>
    var code1 = new Code();
    code1.id 
    = "libCode";
    code1.decorate();
    </script>

示例说明:

在线测试

http://jsintegration.sourceforge.net/example/code.html

http://www.xidea.org/project/jsi/example/code.html

参考:

JSI 导入函数: function $import(path, callbackOrLazyLoad, target )

posted @ 2007-06-25 09:24 金大为 阅读(608) | 评论 (0)编辑 收藏

这个问题算是个老问题了。
所以,标题加上一个再字。

我主要说一下模拟这个事件时候容易出现的问题。

对于FF,Opera9,原生DOMContentLoad支持,就不说了,最头疼的是IE。
我最初考虑这个问题的时候,想到的是document的readyState属性。
偷窥一下Dojo的源码,发现它也是基于这个属性去做的,那时,我基本就认准了这个方法。
于是再后来JSI1和JSI2早期的预览版本中,都是基于这个属性做的,后来,有个朋友向我反应,说JSI的装饰引擎在IE上启动比FF慢很多,我当时就猜测,是否是这个DOMContentLoad的问题。

经过测试,发现,确实,readyState必须等待图片装载完成之后才能置为complete。
于是到网上搜索一下其他办法,最终 Dean Edwards的blog上描述的一个基于script defer属性的解决办法胜出:http://dean.edwards.name/weblog/category/dom/onload/
不过,使用document.write打印一段脚本,我真的不喜欢:(

在评论里面我们可以看到一些其他的建议,有人认为 readyState == 'complete' 加 readyState==‘interactive’这个状态可以准确模拟DOMContentLoad。我开始简单测试一下,貌似可行,但是后来发现 readyState==‘interactive’可能受alert等函数影响,就是说,一般情况下,readyState== ‘interactive’时,dom是装载完了的,但是,当你文档装载过程中,调用了alert函数,那么,readyState将提前置为 ‘interactive’。

总之,目前来说,我知道的,只有两个办法可以真正实现IE上模拟DOMContentLoad

    1.htc ondocumentready(需要额外的HTC文件)
    2.script defer(必须使用document.write打印一段脚本标记,jquery目前采用的方式)

最常见的一个错误:
    document.readyState(Dojo目前(0.4.1)采用的方式)

再说一下JSI的DOMContentLoad实现的使用接口。

js.html.EventUtil.addDOMReadyListener(<Function>listener ,<boolean>runAnyCase )

第二个参数用于确保listener 在任何时候都会被调用(FF DOMContentLoad事件如果在事件发生之后设置listener是无效的)

posted @ 2007-06-25 09:13 金大为 阅读(647) | 评论 (0)编辑 收藏

装载效率测试
测试页面见:test/load-eff-test.html

为了测试结果更显客观,我选择了第三方类库的装载测试:
'com.yahoo.yui.*',
'net.conio.prototype.*',
'net.fckeditor.*',
'org.jquery.*',
'us.aculo.script.*'
共22个脚本文件(对于JSI来说还有诺干包定义文件)。

FF2:  
标记导入时间(原始方式):
469,469,1047,484,484,437,469,484  
同步导入时间:
469,453,484,437,469,453  
延迟导入时间:
921,765,891,906,953,906,922  
异步导入时间:
859,1093,1141,1031,1641,1125,1078,1093,1157,1141  
  
IE7:  
标记导入时间:
343,297,297,344,328,328  
同步导入时间:
281,250,235,235,234,234,250,265  
延迟导入时间:
922,422,406,391,391,391,407,391  
异步导入时间:
625,672,672,703,703,672,703,704,688  



运行时间测试
测试脚本管理后对新能的影响,影响因素有:全局变量和局部变量的查找时间差异,eval的脚本和script标记直接插入的脚本的可能差异。(这 个测试不具有普遍性,这里我主要是测试了一下浏览器对局部变量的访问速度【JSI里面访问变量都是装载单元内的局部变量】,所以故意测试了大量局部变量访 问的操作)
测试页面见:test/runtime-eff-test.html

FF2:  
jsiTime:        
845,    927,    598,    687,    764,  
scriptTime:     
1432,   950,    1305,   1278,   1219,  
evalTime:       
1644,   1373,   1322,   1186,   1360,  
execTime:       
0  
dscriptTime:    
1432,   950,    1305,   1278,   1219,     
  
IE7:  
jsiTime:    
295,    205,    157,    315,    156,    142,    375,    328,    172,    172,      
scriptTime: 
172,    172,    189,    140,    251,    187,    217,    203,    172,    234,      
evalTime:   
236,    249,    139,    172,    281,    171,    172,    108,    436,    359,      
execTime:   
219,    234,    314,    157,    220,    266,    204,    234,    187,    95,   
dscriptTime:    
187,    265,    294,    326,    187,    328,     141,   221,    127,    249,       



上面的基数太小,随机误差太大,调整原始数据从新测试一遍jsiTime和scriptTime

jsiTime:    576,    658,    688,    703,    611,    608,          
scriptTime: 
706,    608,    562,    547,    655,    657,    


总结:

JSI的装载性能表现不错,完全不必计较。
托管代码的运行性能也没有太大区别,不过,因为。JSI托管脚本使用的变量基本都是装载单元内的局部变量(本地声明变量,或者外部依赖的引用或值拷贝),所以,对于FF这类局部变量比全局变量访问速度快不少的解释引擎,JSI托管脚本可以达到更好的运行效率。

有个奇怪的问题,JSI在装载类库时,与传统模式相比,肯定增加了些额外的运算,但是,貌似JSI的同步装载模式下,装载脚本的耗时比传统模式还少(IE 表现明显)?为何?
欢迎大家对这奇怪的现象提出自己的猜想,我稍后贴出我对此问题的看法^_^

posted @ 2007-06-22 15:01 金大为 阅读(695) | 评论 (0)编辑 收藏

 

JSI简介:

JSI 是一个 开放的、无侵入的 脚本库管理框架,内核不提供任何具体功能,有一些功能子项目,如网页装饰引擎。

更多信息请查看:http://www.xidea.org/project/jsi/


JSA简介:
JSA最初是做JSI编译处理的一个小工具,现在也可以用来混淆、压缩脚本。支持swing和ant task两种工作方式。
可以通过webstart启动:启动JSA(允许访问文件系统)沙箱内运行(功能受限)




这次发布的JSI2Alpha相对于以前的预览版本,做了一次全面的重构;同时对API做了些简化。

目前JSI2的公开API有:


/* 导入函数 */  
$import(
<string>path,<boolean|Function>callbackOrLazyLoad[可选参数],<Object>target[可选参数])  
  
/* 日志设置相关 */  
$JSI.setDefaultLogLevel(level)  
$JSI.setLogLevel(pathPattern,level)  
  
/* 装饰引擎相关函数 */  
$JSI.addDecoratorProvider(pkg,alias…) 
//添加装饰包.  
$JSI.decorate ( ) //准备执行装饰器任务,一般在配置文件(config.js)中调用.   
  
/* 用于包定义的Package成员函数,在__package__.js中调用(this指向当前package对象) */  
this.addScript(scriptPath,objectNames)//添加脚本及其声明的对象(函数、方法名).   
this.add*Dependence(thisPath,targetPath,beforeLoad)//添加脚本依赖.  
this.setImplementation(realPackage)//设置具体实现包(当前包只是其别名,并无任何内容)。 

 


我们会尽量将JSI做成与具体功能无关(专著于脚本管理)。

对于js.*.*这个类库,做了些精简。
只保留下列元素

 

#js.html //保留这个包,因为这些实在太常用了。  
   * BrowserInfo  
   
* EventUtil  
   
* StyleUtil  
  
#js.util
//保留这个包主要因为异步装载用到这些类库  
   * LoadTask  
   
* Request  
   
* ScriptLoadTask  
   
* TaskQueue  

 

发布文件说明:
自该版本启,source目录将不再打包。
但是在scripts目录下新增boot-with-source.js文件,该文件中包含全部源代码的数据。
里面编码的源代码可以通过我们的文档工具查看。让大家习惯一下这个工具的使用:)

JSA1beta:增加了对JSI2的编译支持,同时对于普通脚本的压缩,也增加了一些功能:
1. ant task 增加多文件分组合并。
2. swing ui 修正文件编码的bug。

下载:
javaeye group: http://jsi.group.javaeye.com/shares
sourceforge: <系统最近好像有问题,我的文件一直没能上传成功,要过一段时间再说> 。。。。。

posted @ 2007-06-22 14:36 金大为 阅读(740) | 评论 (0)编辑 收藏
今天抽空测试了一下JSI当前状态的浏览器兼容性,一个头疼的问题困扰了很久。
找出问题出自,怀疑是一个opera的bug。

function test(x){
  
try{
    
if(x){
      
return 1;
    }
else{
      
return 2;
    }
  }
catch(e){
    x
=1;
  }
finally{
    x
=2;
  }
}

语法检查就通不过,报告错误:
le://localhost/D:/eclipse/workspace/JSI/web/scripts/core.js
Event thread: BeforeExternalScript

opera8报错,opera9好像就没有这个问题。
贴出来,让有类似问题的人省点心。
posted @ 2007-06-20 21:42 金大为 阅读(119) | 评论 (0)编辑 收藏

刚发布JSA的webstart版,顺便吧这个古董级别的小程序也发布一下。
仅供那些和我一样棋术平平的无聊人士打发时间。

高手就不必了:)
当能,如果是想找个地方出出气,也可以,呵呵。


http://www.xidea.org/webstart/chess.jnlp



没有棋谱,所以,开局的棋力很差。中局还行。

posted @ 2007-06-14 10:51 金大为 阅读(737) | 评论 (2)编辑 收藏
测试了一下trimpath模板引擎和一个我以前编写xml模板引擎,显示测试结果,828/16。

太让我振奋了。原想,如果效率太低我就放弃这个项目,貌似结果:这个流行的js模板引擎,和我没做优化的xml模板引擎还有这么大的差距???

仔细检查一下,晕倒,测试模板数据搞错了:(

纠正过来,测试数据显示,trimpath比xml模板引擎要快好几倍:(

而且,如果模板内使用的循环次数越多,差距越大:(

比较扫兴的结果。
决定吧这个东西从jsi系统api中删除。

不过,感觉,虽然有这点差距,xml模板引擎还是可以作为一个备用选择。
基于js标记库,类el表达式,对于熟悉jsp2.0,jstl的程序员来说,还是比较易懂,扩展也相对简单(trimpath没怎么研究,或许是错的)。

下载测试:
(XML Template是从jsi中拉出来的,部分测试中没有用到的依赖没有包括进去)

posted @ 2007-06-08 16:15 金大为 阅读(919) | 评论 (2)编辑 收藏
  一直没有找到好用的 javascript格式化工具,不过UE有个非常漂亮的功能,多行编辑,可以轻松的批量缩进。
  但是eclipse呢?很遗憾,没有,不过用正则表达式可以轻松完成这个功能,匹配整行,替换时在行前加上缩进空格。

find:^.*
replace With:  $0

说到这个正则,鄙视一下js的正则语法,居然匹配组是 $1 $2 $3 ....索引从1开始,但是匹配全部为什么要来个$&?  多么难记??还是eclipse的$0方便
而且js的match函数返回的数组还是 [全匹配,组1,组2....],全匹配索引就是0嘛! 居然要来个$&??
扼杀我们的联想天性。

posted @ 2007-06-08 11:33 金大为 阅读(725) | 评论 (0)编辑 收藏
今天和网友聊起在javascript里面实现DateFormat 的话题。

把想法发布一下,当是笔记。

格式化:
  1、先用正则把日期表达式分段:
    var tokens = "yyyy-MM-dd(没有时间)".match(/y+|M+|d+|m+|[^yMdm]+/g)
    //结果数组为:yyyy,-,MM,-,dd,(没有时间)
  2、将其中的yyyy MM dd 替换成相映的处理对象
 
  3、格式化时,先复制数组,依次遍历,如果元素是处理对象,那么元素值替换成处理结果。

  4、将新数组join。即为需要结果。

  5、parse时。先复制数组,若元素为字符串,精确匹配。若未处理对象,读取需要的值,匹配失败,则终止操作,返回结果。




想法而已,实际实现时可能还有很多现在无法意料的事情:)

posted @ 2007-06-07 16:27 金大为 阅读(1384) | 评论 (3)编辑 收藏
为了jsi2 alpha的尽快发布,我对jsi 的系统api重构了一下,删除了一些不够成熟或者没有必要的api(将他们拖到org.xidea.* 命名空间下)。


更新(2007-6-9)
接上,移除了xml命名空间及其内容,装饰引擎。io包并入util了,移除了一些脚本,如xml 模板引擎、装饰引擎实现等。。。
基本上做到了功能无关了
只剩下html包和util包。lang包这种语言兼容包不说。

现在的类库只有(数据拷贝自JSI jsdoc):

#js.html //保留这个包,因为这些实在太常用了,
   * BrowserInfo
   //保留Decorator是因为装饰器初始化,还是受到点特别关照
   * Decorator
   * EventUtil
   * StyleUtil

#js.util//保留这个包主要因为异步装载用到这些类库
    * LoadTask
    * Request
    * ScriptLoadTask
    * TaskQueue


现在的类库只有(数据拷贝自JSI jsdoc):

#js.html //保留这个包,因为这些实在太常用了,
   * BrowserInfo
   
//保留Decorator是因为装饰器初始化,还是受到点特别关照
   * Decorator
   
* EventUtil
   
* StyleUtil

#js.util
//保留这个包主要因为异步装载用到这些类库
   * LoadTask
   
* Request
   
* ScriptLoadTask
   
* TaskQueue 

欢迎大家提出自己的看法:)



posted @ 2007-06-07 11:48 金大为 阅读(732) | 评论 (12)编辑 收藏
JSI 自身提供一些常用API,数量极少,尽量以一种正式的风格提供,尽量回避争议。
有些是启动文件用到的,如任务队列支持,还有如装饰引擎直接用到的,如BrowserInfo、EventUtil、StyleUtil等。
对于启动文件中未直接用到的,如果风格的争议太大,都将剔除出去。


BrowserInfo对象:

/**
 * BrowserInfo 对象,用于判断浏览器的相关信息,如浏览器类型、quirks模式、客户端语言(简体中文?英语..未实现)、操作系统(未实现)等等。
 * @public
 
*/
var BrowserInfo = {
  isIE : falseChecker,
  isOpera : falseChecker,
  isGecko : falseChecker,
  isNetscape : falseChecker,
  isMozilla : falseChecker,
  isFirefox : falseChecker,
  isKhtml : falseChecker,
  isSafari : falseChecker,
  isKonqueror : falseChecker,
  isQuirks : 
function(){…}
};

其中最常用的要数 is<浏览器类别>(最小版本号码,最大版本号)。
此外,我还将BrowserInfo的函数拷贝到navigator对象上,这个有无必要呢?
//@Deprecated ???
for(var n in BrowserInfo){
  window.navigator[n] 
= BrowserInfo[n];
}

不同之处:

现在在浏览器判断上面,一般是用常量表示,比如isIE之类的,JSI的BrowserInfo使用函数,以便提供更强大更灵活的功能。

EventUtil
EventType 对象的成员函数有:

addListener(el, type, fn, cap)
removeListener(el, type, fn, cap)

add
<Eventtype>Listener(element, listener, captrue)
如addLoadListener,addMousedownListener,addMouseoutListener    
remove
<Eventtype>Listener(element, listener, captrue)
createEvent(type, canBubble, cancelable)
dispatchEvent(el, even)

其中: <Eventtype>代表一种事件类型。
W3C事件类型有:
var events = ['click','mousedown','mouseup','mouseover','mousemove','mouseout','load','unload','abort','error','select','change','submit','reset','focus','blur','resize','scroll'].
             concat(['DOMFocusIn','DOMFocusOut','DOMActivate']);


此外,还添加了一种事件类型:DOMLoad。就是mozilla的DOMContentLoaded事件,在Dom树构造完成但图片资源等可能未完成时触发。
对于这种事件类型, element,  captrue参数都将忽略。暂时只有添加函数,没有删除函数(有删除的必要吗?)。

不同之处:

这个事件处理函数集与其他常见方式的却别有:
  1. this支持。IE的attach方法添加的函数,运行时this指向window对象,JSI吧这点给纠正过来,与w3c的addEventListener行为一致。
  2. 事件类型直接体现在函数名中,这样有利于书写上的错误及早发现。
  3. 事件格式化,将事件的访问方式格式化为W3C的方式。
  4. 自动清理,这也不算不同吧,现在大多数JS库都提供这个功能,就是在离开页面时清理全部注册事件。但是这对一些单页程序是无效的(OPOA,本人也比较讨厌这种模式,呵呵),以后是否可以提供一个purgeElement函数,用于清理指定元素及其子元素的事件呢?
非常希望大家积极发表自己的看法,该修改就修改,如果争议太大,那么我将吧这些从系统API中移除。

程序下载

这个API也可以脱离JSI使用,只是,在编写的时候,因为有了JSI的保护,我使用了不少内部变量,为避免可能的冲突,做了如下处理。


var BrowserInfo = function(){
  
//#include(browser-info.js).
  return BrowserInfo;
}

var EventUtil = function(){
  
//#include(event-util.js).
  return EventUtil;
}

下载地址


posted @ 2007-06-06 12:17 金大为 阅读(720) | 评论 (0)编辑 收藏

QQ群里无聊的对话,贴出来:

小马猴(53958317) 20:31:20
那二进制还中国发明的呢
五风楼客(63515213) 20:36:02
哦,二进制与中国什么关系,还真不知道呢,呵呵?
五风楼客(63515213) 20:36:23
那个朝代的事呢?
小马猴(53958317) 20:35:43
据说是莱布尼茨在周易中发现了二进制
海阔天空(149788288) 20:35:46
我也孤陋寡闻了
小马猴(53958317) 20:36:02
就是那个八卦图
五风楼客(63515213) 20:37:04
^_^,强
五风楼客(63515213) 20:37:49
今天才知道,我们大中国计算机技术领先西方三千年:)
海阔天空(149788288) 20:37:16
是啊是啊,中国领先的多着呢

五风楼客(63515213) 20:38:09
不止,估计有个四千年左右把:)
呵呵
小马猴(53958317) 20:37:22
不过外国人看周易,发明了计算机,中国人看周易,发明了算命。
小马猴(53958317) 20:38:25
搜狐这两天就请了帮看风水的人去看他总部呢。那些看风水的就是什么周易什么什么研究会的。
五风楼客(63515213) 20:39:20
找张八卦图看看,能不能发现什么玄机呢:)
海阔天空(149788288) 20:38:56
八卦新闻
五风楼客(63515213) 20:40:08
不管什么新闻,俺是一直非常鄙视搜狐的。
小马猴(53958317) 20:39:23
我估计八卦图说不定是中国古代发明的图灵机呢
小马猴(53958317) 20:39:29
哈哈
Tu-160(382392596) 20:41:50
哈哈哈
海阔天空(149788288) 20:42:03
八卦是好东西啊,两仪生四向,四向生八卦
海阔天空(149788288) 20:42:17
下面一句是什么来着
五风楼客(63515213) 20:44:06
太极生两仪 两仪生四向 四向生八卦 八卦生万物
小马猴(53958317) 20:43:49
嗯,于是莱布尼茨从这句话悟出了二进制
五风楼客(63515213) 20:45:19
呵呵,原来最早使用8进制的不是玛雅人,是俺们先辈,呵呵
海阔天空(149788288) 20:44:34
确实有2进制的意思啊

海阔天空(149788288) 20:44:43
中国古代是用16进制吧?
五风楼客(63515213) 20:45:51
恩,至少重量单位是的
五风楼客(63515213) 20:46:23
小时候还经常听老人们说16量的秤,呵呵
海阔天空(149788288) 20:47:05
一打
霖雨(3366414) 20:47:35
半斤八两

posted @ 2007-06-06 08:19 金大为 阅读(218) | 评论 (2)编辑 收藏
如题:
JSA介绍:http://www.javaeye.com/article/77776
posted @ 2007-06-05 18:34 金大为 阅读(297) | 评论 (4)编辑 收藏
JSI2 Alpha即将发布,关于两类特殊文件的命名方式,想听听大家的建议:

包定义文件,原先为 __$package.js
  缺点:$符号再linux上处理有点麻烦,通过shell命令创建时需要使用转义字符(\$)

预装载缓存脚本(编译结果,用于支持延迟同步非阻塞式装载),原先与原文件同名,只是映射到其他目录.
  缺点:同一个包的资源处在不同目录,发布,部署都有点麻烦.


现在的修改想法:

方式一:

__[package].js
file.js
file[preload].js

缺点:[]也算特殊字符.
优点:看起来比较直观,也不容易和已有文件冲突.linux系统中,通过控制台还是可以直接创建的,不用转义.

方式二:

__package__.js
file.js
file__preload__.js

缺点:看起来没有上面的直观.已有别的类库采用这个名字,不便于编辑工具识别 .
优点:无特殊字符.

大家感觉如何?给点建议吧:)
posted @ 2007-06-03 14:31 金大为 阅读(622) | 评论 (3)编辑 收藏
    JSI是一个简单、无侵入(被管理的脚本无需考虑JSI的存在)的脚本管理框架, JSI的出现,可以做到如下几点:

* 按需装载。
* 管理依赖,避免依赖的保露、扩散,提高类库的易用性。
* 执行环境的隔离,避免名称冲突。

类库装载

    动态装载类库是按需装载的基础,JSI的装载方式有三种:即时同步装载(可能阻塞)、延迟同步装载(需要编译)、异步装载。这里先演示一下最简单的方式,即时同步导入:

示例:重写一下jQuery的hello world。
….
<!-- 加入引导脚本 -->
<script src="../scripts/boot.js"></script>
….
<script>
//导入jQuery的$函数
$import("org.jquery.$");
//使用jQuery的$函数
$(document).ready(function(){
  alert(
"Hello World");
 });
</script>
….

    这是默认的导入方式,当能,如果网络环境不好,这可能产生阻塞问题。所以JSI2开始增加了仍外两种导入模式。延迟同步导入,异步导入。具体用法请查看文章后面的导入函数参考。

依赖管理

    Java可以随意的使用第三方类库,可是JavaScript却没那么幸运,随着类库的丰富,烦杂的依赖关系和可能的命名冲突将使得类库的发展越来越困难。程序的易用性也将大打折扣。

    命名冲突的危险无形的增加你大脑的负担;随着使用的类库的增加,暴露的依赖也将随之增加,这是复杂度陡增的极大祸根,将使得系统越来越复杂,越来越难以控制。潜在的问题越来越多,防不胜防。

    所以,我们建议类库的开发者将自己类库的依赖终结在自己手中,避免依赖扩散,以提高类库的易用性。

    为了演示一下JSI的依赖管理,我们编写一个复杂一点的类库:类似Windows XP文件浏览器左侧的滑动折叠面板(任务菜单)效果。

1.编写我们的折叠面板函数(org/xidea/example/display/effect.js):
/**
 * 滑动面板实现.
 * 当指定元素可见时,将其第一个子元素向上滑动至完全被遮掩(折叠)。
 * 当指定元素不可见时,将其第一个子元素向下滑动至完全显示(展开)。
 
*/
function slidePanel(panel){
  panel 
= $(panel);
  
if(panel.style.display=='none'){
    
//调用Scriptaculous Effect的具体滑动展开实现
    new Effect.SlideDown(panel);
  }
else{
    
//调用Scriptaculous Effect的具体滑动闭合实现
    new Effect.SlideUp(panel);
  }
}

2.编写包定义脚本,申明其内容及依赖(org/xidea/example/display/__$package.js):
//添加slidePanel(滑动面板控制)函数
this.addScript("effect.js","slidePanel",null);
//给effect.js脚本添加对us.aculo.script包中effects.js脚本的装载后依赖this.addScriptDependence("effect.js",
"us/aculo/script/effects.js",false);
//给effect.js脚本添加对net.conio.prototype包中$函数的装载后依赖this.addScriptObjectDependence("effect.js",
"net.conio.prototype.$",false);

3.HTML代码:
<html>
  
<head> 
  
<title>重用aculo Effect脚本实例</title>
  
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
  
<script src="/scripts/boot.js"></script>
  
<script>
    $import(
"org.xidea.display.slidePanel");
  
</script>
  
</head>
  
<body>
    
<div class="menu_header"
        onclick
="slidePanel('menu_block1')">
        面板 1
    
</div>
    
<div class="menu_block" id="menu_block1">
      
<ul>
        
<li>text1</li>
        
<li>text2</li>
        
<li>text3</li>
      
</ul>
    
</div>
</body>
</html>

    onclick="slidePanel('menu_block1')"这个事件函数将在我们点击面板标题时触发,能后会调用Scriptaculous Effect的具体实现去实现我们需要的滑动折叠功能。

    这个效果只是八行代码,比较简单,但是它用到了Scriptaculous Effect类库,Scriptaculous Effect又简接用到了Prototype类库,所以,传统方式使用起来还是比较复杂,有一堆脚本需要导入prototype.js,effects.js,builder.js,更加痛苦的是这些脚本的导入还要遵守一定的顺序。

    但是,如果我们使用JSI 明确申明了这些依赖,那么使用起来就简单多了,只一个import就可以完全搞定。
    此外 这里还有一个额外的好处,我们类库中依赖的那些脚本,并不会对外部保露,在页面上是不可见的,也就是说,这些依赖完全终结在刚才编写的类库中,不必担心使用这些类库带来的名称污染问题。


环境隔离

    众所周知, Scriptaculous所依赖的Prototype库与jQuery存在冲突。所以同时使用比较困难。
    下面的例子,我们将在同一个页面上同时使用Scriptaculous和 jQuery 类库。示范一下JSI隔离冲突功能。
示例页面(hello-jquery-aculo.html):
<html>
<head>
<title>Hello jQuery And Scriptaculous</title>
<!-- 加入引导脚本 -->
<script src="../scripts/boot.js"></script>
<script>
//导入jQuery
$import("org.jquery.$");
//导入Scriptaculous
$import("us.aculo.script.Effect");

$(document).ready(
function(){
  
//使用jQuery添加一段问候语
  $("<p id='helloBox' style='background:#0F0;text-align:center;font-size:40px;cursor:pointer;'>\
Hello jQuery And Scriptaculous</p>
")
    .appendTo('body');
  $('#helloBox').ready(
function(){
    
//使用Scriptaculous高亮显示一下刚才添加的内容
    new Effect.Highlight('helloBox');
  }).click(
function(){
    
//当用户单击该内容后使用jQuery实现渐出
    $('#helloBox').fadeOut();
  });
 });
</script>
</head>
<body>
<p>文档装载后,jQuery将在后面添加一段问候语;并使用Scriptaculous高亮显示(Highlight);在鼠标点击后在使用jQuery渐出(fadeOut)。</p>
</body>
</html>




其他话题

    JSI组件模型:
    页面装饰引擎:用于装饰朴素html元素的框架,实现零脚本代码的web富客户端编程,更多细节请访问jsi官方网站。


参考:

    脚本导入函数
    脚本导入函数是JSI唯一的一个在页面上使用的系统函数。

  function $import(path, callbackOrLazyLoad, target )
      path 类库路径
      callbackOrLazyLoad 可选参数,如果其值为函数,表示异步导入模式;如果其值为真,表示延迟同步导入模式,否则为即时同步导入(默认如此)。
      Target 可选参数(默认为全局变量,所以说,这种情况等价于直接声明的全局变量),指定导入容器。
名词解释:
    * 自由脚本
通过<script>标记引入或直接编写的脚本,我们不建议在使用JSIntegration之后,仍旧使用script src导入JSI启动脚本(boot.js)之外的脚本。
    * 托管脚本
通过$import函数直接或间接加载的脚本。这些脚本将在一个独立的执行上下文装载,不会污染全局环境。
    * 脚本依赖
若要使用A,需要导入B,则A依赖B。
A、B可以是脚本文件,也可以是脚本文件中的某个脚本元素。
    * 类库使用者
类库的使用者,您只需再页面上书写脚本,导入类库,编写自己的简单脚本,一般情况请不要编写js文件,那是类库开发者做的事.
    * 类库开发者
在此框架下开发出方便实用的脚本库,您需要编写一些通用脚本,同时设置脚本依赖,做到任何类/函数,导入即可运行。


posted @ 2007-06-02 14:16 金大为 阅读(1622) | 评论 (0)编辑 收藏
先申明一下,我讨厌Ajax这个名词。旧药装新瓶。(像那个80来岁的杨某一样令人讨厌,呵呵)。

正题:

    Ajax所谓的异步加载,为何需要异步,可以说异步操作通常都是一个成熟的程序设计人员会尽力回避的东西。复杂度徒增,不好控制,容易出错。

    但是,这个问题放在浏览器上就是另外一个情形,浏览器上的脚本+事件通常只有一个线程。那些看是多线程的函数:setTimeout, setInterval,其实都不会插入或中断任何一个其他的在执行中的任务,而且一旦你的脚本尚在运行,那么不管你是否在挂起等待,所有的事件都将阻 塞。窗口重画,拖动...也都得靠边站着,感觉就像是某个程序进入一个死循环了。

    以前得脚本都是做一些简单得事情,需要的时间,用户基本上都感觉不到,后来XMLHttpRequest的兴起,问题出来了,访问网络资源,你得受网速得 限制,如果同步的获取,那你就等吧,等个几秒几分几十分的,不是不可能。这时浏览器可没那么聪明,站旁边傻等,什么窗口重画,移动啊,都装个没听见。

    浏览器傻了,用户可不傻,靠,这个网站咋的,吧我的浏览器都搞死了?加入黑名单,或者碰到个脾气好点的,把你辛辛苦苦、没日没夜、绵绵数月敲下来的脚本,一律禁止运行... 傻了把,可怜的脚本程序员。

    看似浏览器的问题嘛,可是,谁叫你是中年诸葛亮呢,扶不起的阿斗你也得背着,朽木上刻章方显你的出众嘛。于是异步操作遍地开花,第N次世界大乱从此开始。

    确实这里使用异步操作很有见成效,先告诉xmlhttp后台加载网络资源。一边凉快凉快,加载完了通知一下。喝喝茶,看看报,N+1秒钟过去了,报告: 001.xml全体元素集合完毕,帐前待命...,ok,..... (机密,隐藏...)。

    不错把,你不必焦急的盯着屏幕上所不期望的白大块,不用使劲的失望的拖动着没有的鼠标。你只需要东瞧瞧西瞅瞅,随意的打发点时间,一会,东西准备好了,归你了,爱怎么办就怎么办吧。

    没看明白?简单点说吧,就是把资源加载这一操作放在脚本线程之外,那么就不会有长时间运行的脚本,那么用户就觉得你的程序响应快。就是是说ajax,其实asynchronism也就这一个地方而已。

    记住一点,浏览器上单纯的脚本程序,本身是不支持多线程的,异步也就无从谈起,而现在所说的异步,都不是纯粹的ECMAScript,都是利用浏览器带有的某些原生对象实现的。

    雕虫小技而已,结果吹得鸡毛满天飞。众嘴纭纭之势,众目睽睽之下,公鸡下蛋,鲤鱼上坡,皆有可能。
posted @ 2007-06-02 14:11 金大为 阅读(970) | 评论 (13)编辑 收藏
循环反转示例:

  for(var i = 0;i<data.length;i++){
    
//.
  }
  
//反转后代码
  for(var i = data.length-1;i>=0;i--){
    
//.
  }

这类优化的作用是明显的,但是具体有多大作用呢?

用一个长度为100 000 的数组测试一下:
515/313
500/313
516/312
516/328
516/328

可见,循环反转后,只需要原来3/5的时间.
但是,这种东西到底有多大价值?FF上200次循环仅需要1毫秒的时间.所以,个人认为,只要循环的内容不是太长,使用不算非常频繁,那么没有太大必要.
加入循环的长度需要通过函数取得,且不变,那么,反转的效率还是可观的,在IE上,函数调用消耗是普通操作的十多倍.

测试代码:
var incTime = 0;
var decTime = 0;
var inc = 0;
var data = new Array(10*10000);
//while(inc++<50)
{
  
var t1 = new Date();
  
for(var i = 0;i<data.length;i++){
  }
  
var t2 = new Date();
  
for(var i = data.length-1;i>=0;i--){
  }
  
var t3 = new Date();
  incTime
+=(t2-t1);
  decTime
+=(t3-t2);
}

prompt(
"incTime/decTime",incTime +'/'+decTime)


posted @ 2007-05-31 12:30 金大为 阅读(906) | 评论 (5)编辑 收藏
JSI的实现中,有这样一种需求,将有自带命名空间的脚本元素名数组转换成没有命名空间的变量名数组.
比如 :
['YAHOO.util.XXXX,YAHOO.util.YYYY,YAHOO.event.XX'] ->['YAHOO']

以前一直是较长的一段处理代码,今天突发奇想,这个用正则表达式处理效果如何?

于是,就这种处理,分别测试了正则表达式和javascript代码的效率.

测试数据如下(regTime /codeTime):
620/4536
729/4068
719/4250
645/4152
655/4642

FF和IE结果差不多,上面是FF2的数据

总结:
经常看见很多地方对正则表达式的效率的怀疑,但是这个问题放在javascript里面,好像情况又不同了. 适当使用正则式,反而可以大大提高效率.
在javascript这类\较慢的解释型语言里面,少即快,能用原生代码就不要自己写.

测试代码:
var data = [];
for(var i = 0;i<20;i++){
  data[i] 
= "NS"+i/10+'.'+i
}
document.write(
  
//(data == data.sort()) +"/"+
  data +"<hr>")
var i = 0;
var regTime = 0;
var codeTime = 0;
var inc = 0;
var reg = /(\b[\$\w]+)[\$\w\.]*(,\1\b[\$\w\.]*)*/g;

var regResult,codeResult;
while(inc++<100){
  
var i=0;
  
var t1 = new Date();
  
while(i++<100){
    regResult 
= data.join(',').replace(reg,'$1').split(',');
  }

  
var t2 = new Date();
  
while(i++<200){
    codeResult 
= [];
    
var flagMap = {};
    
for(var j=data.length-1;j>=0;j--){
      key 
= data[j];
      key 
= key.substr(0,key.indexOf('.'));
      
if(!flagMap[key]){
        codeResult[codeResult.length] 
= (key);
        
//codeResult.push(key);
        flagMap[key] = true;
      }
    }
  }
  
var t3 = new Date();
  regTime 
+=(t2-t1);
  codeTime
+=(t3-t2);
}
document.write(
  
"regResult:"+
  regResult)
document.write(
  
"<hr>codeResult:"+
  codeResult)
prompt(
"regTime /codeTime",regTime  +'/'+codeTime)

posted @ 2007-05-30 13:22 金大为 阅读(909) | 评论 (0)编辑 收藏
一直都认为,javascript的函数调用是一个相对耗时的操作。
开始JSI的优化,这些问题现在必须认真考虑了,测试一把:

一个简单的++操作,直接操作和函数内操作(注,函数参数对原始类型是值传递,所以这不会影响被传入的变量,这里测试里面,两类操作的行为是不一样的)

FF2测试结果(callTime/opTime):
2871/2582
2919/2675
2734/2704
2953/2516
3732/3346

IE7测试结果:
3140/376
3173/327
3238/247
3265/235
3217/299

通过测试可见,函数调用的消耗基本可以忽略。每次调用时间仅为:
3000/(200*1000*5) ==0.3毫秒 ,这个时间还包含函数内部的++操作

从示例可见,FF的函数调用消耗基本可以府略,IE虽然相当于十倍++类简单操作,但依然不足以重视。

奇怪的是,第一次碰见ie的运行效率高于ff的情况。

测试代码
var i = 0;
var callTime = 0;
var opTime = 0;
var inc = 0;
function plus(z){z++};
while(inc++<200){
  
var i=0;
  
var x = 1;
  
var t1 = new Date();
  
while(i++<1000){
    plus(x);
    plus(x);
    plus(x);
    plus(x);
    plus(x);
  }

  
var t2 = new Date();
  
while(i++<2000){
    x
++;
    x
++;
    x
++;
    x
++;
    x
++;
  }
  
var t3 = new Date();
  callTime
+=(t2-t1);
  opTime
+=(t3-t2);
}

prompt(
"callTime/opTime",callTime +'/'+opTime)





posted @ 2007-05-29 18:00 金大为 阅读(918) | 评论 (0)编辑 收藏
前几天无意中看到一个网友blog上关于这个循环效率的问题,说要尽量避免使用。
有点害怕,我在JSI中可是用了不少,呵呵。
测试一下,负担终于可以放下来了:

测试对象:
一个对象模拟map,测试for in 循环
两个数组,测试for(;;)循环

连续4次运行时间比。
957/1278;955/1357;1014/1282;968/1392


明显,要实现类似map的功能,还是for in 快点。

上面的数据是ff2上的结果,ie7上也差不多,差距更小一点。

测试代码:
function C(i){
  
return i<62?
    String.fromCharCode(i
+=
      i
<26?65
        :i
<52?71//97-26
          :-4//48-26-26
    )
      :i
<63?'_'
        :i
<64?'$'
          :C(i
>>6)+C(i&63)
}
var map = {};
var arr1 = [];
var arr2 = [];

for(var i = 0;i<1000;i++){
  
var c = C(i);
  map[c] 
= i;
  arr1.push(c);
  arr2.push(i);
}
var i = 0;
var mapTime = 0;
var arrTime = 0;
var inc = 0
while(inc++<500){
  
var t1 = new Date();
  
for(var n in map){
    n 
= map[n];
  }
  
var t2 = new Date();
  
for(var j = 0;j<1000;j++){
    n 
=arr1[j];
    n 
=arr2[j];
  }
  
var t3 = new Date();
  mapTime
+=(t2-t1);
  arrTime
+=(t3-t2);
}

prompt(
"mapTime/arrTime",mapTime +'/'+arrTime)


posted @ 2007-05-27 17:18 金大为 阅读(1480) | 评论 (13)编辑 收藏
无赖,自己外语太差,就算想去也难办,呵呵。

怀疑 sourceforge是不是在搞贩人服务呢?

posted @ 2007-05-27 10:36 金大为 阅读(134) | 评论 (0)编辑 收藏
刚刚修正了一个JSA的bug。

顺便测试了一下文本压缩的性能,和纯packer 压缩,ShrinkSafe+packer压缩。
压缩大小:
jquery-jsa-s.js(JSA的语法压缩):29766
jquery.compressed.js(ShrinkSafe语法压缩):33992

jquery-jsa-st.js(JSA的语法压缩+文本压缩):19526
jquery-packer.js(Packer文本压缩):20977
jquery.compressed-packer.js(ShrinkSafe语法压缩+Packer文本压缩):21839

有点奇怪的是,文本压缩和语法压缩是有一定互补性的,但是ShrinkSafe+Packer比单纯的Packer文本压缩效率还低??
我想可能是ShrinkSafe做的一些语法补全(可省略的 {、}、;、),jQuery编码的风格导致。

Firefox测试数据(10次压缩时间的毫秒数,连续5回测试数据)

jquery-jsa-st.js:784
jquery-packer.js:1265
jquery.compressed-packer.js:1529

jquery-jsa-st.js:718
jquery-packer.js:922
jquery.compressed-packer.js:766

jquery-jsa-st.js:753
jquery-packer.js:872
jquery.compressed-packer.js:828

jquery-jsa-st.js:1438
jquery-packer.js:1484
jquery.compressed-packer.js:1735

jquery-jsa-st.js:687
jquery-packer.js:1236
jquery.compressed-packer.js:1234


IE5 测试数据(连续三回测试数据)

jquery-jsa-st.js:766
--------------------------------------------------------------------------------
jquery-packer.js:9765
--------------------------------------------------------------------------------
jquery.compressed-packer.js:10547


jquery-jsa-st.js:671
--------------------------------------------------------------------------------
jquery-packer.js:9002
--------------------------------------------------------------------------------
jquery.compressed-packer.js:10265


jquery-jsa-st.js:704
--------------------------------------------------------------------------------
jquery-packer.js:8232
--------------------------------------------------------------------------------
jquery.compressed-packer.js:10314

总结

文本压缩是个比较耗时的操作,像JQuery这样大的类库普遍需要接近100毫秒的解压时间。
如果需要兼容IE5这种老古董,那么最好不要用packer的文本压缩,太耗时。
JSA1 对文本压缩做了些改进,表现还可以。

如果要计较脚本文本压缩后的解压开销,建议使用JSA的语法压缩,配合服务器端的gzip压缩。
不推荐dojo 的ShrinkSafe,原因是它的几个安全问题。
posted @ 2007-05-24 09:28 金大为 阅读(951) | 评论 (0)编辑 收藏
面试官:熟悉哪种语言
应聘者:Java。

面试官:你会Hibernate吗
应聘者:知道,动物冬天经常Hibernate,但我从来不冬眠

面试官:tomcat了解么
应聘者:小时看过。现在也喜欢看

面试官:用过 apache 的东西吗
应聘者:没有,我没开过也没座过直升机。

面试官:知道什么叫class么
应聘者:不知道。

面试官:知道什么叫类么
应聘者:我这人实在,工作努力,不知道什么叫累

面试官:知道什么是接口吗?
应聘者:我这个人工作认真。从来不找借口偷懒

面试官:知道什么是package?
应聘者:不知道。

面试官:知道什么是包?
应聘者:我这人实在  平常不带包 也不用公司准备了

面试官:知道什么叫对象么?
应聘者:知道,不过我工作努力,上进心强,暂时还没有打算找对象。。

面试官:知道什么是继承么
应聘者:我是孤儿没什么可以继承的

面试官:你知道google是干什么的么?
应聘者:等我先百度一下。


posted @ 2007-05-19 11:27 金大为 阅读(170) | 评论 (0)编辑 收藏
最近在搞JSI 的重构,少来冒泡了。
发一个中午的刚用到的小技巧:

在关机效果实现上,现在一般根据浏览器特征分别使用 虑镜/样式/图片 去模拟。

其中Opera是不支持网页透明的,只能用png的alpha透明模拟。
所以,我们需要一张特别的小图片。一个象素,alpha透明。

但是这个单象素图片的出现,感觉有点怪怪的,而且当网速很慢的时候,装载这个小图片还会延迟,效果不好。

不过,Opera的另外一个特性,可以避免这个问题:data:协议的支持。

对于这种小图片,完全可以编码到样式里面

background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mM4ffp0AwAHqALiYeNxSgAAAABJRU5ErkJggg==)


好了,如此一来,关机效果的实现,就没有图片这个累赘了。


图片的生成:

图片的生成,浪费我一个中午的时间:(
开始本想找个软件做掉,最后没发现一个如意的,干脆,自己看看api,自己写了一下:
代码如下:
    public static void main(String[] args) throws IOException {
        BufferedImage image 
= new BufferedImage(11,
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d 
= image.createGraphics();
        
// RGBA #cccccc80
        g2d.setColor(new Color(0xcc0xcc0xcc0x80));
        g2d.fillRect(
0011);
        g2d.dispose();
        IIOImage iioImage 
= new IIOImage(image, nullnull);
        ImageTypeSpecifier type 
= ImageTypeSpecifier
                .createFromRenderedImage(image);
        ImageWriter writer 
= (ImageWriter) ImageIO.getImageWriters(type, "png")
                .next();
        ByteArrayOutputStream out 
= new ByteArrayOutputStream();
        writer.setOutput(ImageIO.createImageOutputStream(out));
        writer.write(
null, iioImage, null);
        BASE64Encoder encoder 
= new BASE64Encoder();
        String result 
= encoder.encode(out.toByteArray()).replaceAll("[\r\n]",
                
"");
        System.out.println(
"data:image/png;base64," + result);
    }


需要其他颜色,自己修改一下代码即是。
posted @ 2007-05-18 15:30 金大为 阅读(1294) | 评论 (1)编辑 收藏
第一次见到媒体的关注,精神为之一振。
^_^

一定好好做,不让关注她的人群失望:)
posted @ 2007-05-16 13:09 金大为 阅读(137) | 评论 (0)编辑 收藏