2007年6月2日
改寫了一下Java基類,添加了一個計數器。
用tomcat測試了一下連續若干次請求時創建的對象個數。
第【148259】個對象
天哪,服務器啟動開始就是14萬個對象。
第【148668】個對象
第【149091】個對象
第【149211】個對象
第【149291】個對象
第【149418】個對象
第【149541】個對象
第【149867】個對象
第【149947】個對象
回想一下以前人們為丑陋的struts1的單例Action的設計的辯護,真是可笑之極,哈哈哈哈
posted @
2008-03-11 11:35 金大為 閱讀(932) |
評論 (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 金大為 閱讀(261) |
評論 (0) |
編輯 收藏
我一直都想搞一個
XML的模板引擎 ,大凡非xml的模板風格,第一感覺就是那么的不爽。
可是CommonTemplate例外。
CommonTemplate處處為程序員考慮周到的漂亮的語法風格,確實非常誘人。
具體的語法我就不一一列舉了,大家可以到他的
官方網站 去翻閱。
挑幾個亮點介紹一下:
for循環的空處理,相信曾經麻煩了不少程序員吧。
現在好了,CT支持如下語法:
$for{ }
< tr >
< td > 1 </ td >
< td > 2 </ td >
< td > 3 </ td >
</ tr >
$forelse
< tr >
< td colspan ="3" > 沒有數據 </ td >
</ tr >
$end
大膽的關鍵字利用。
< 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。既解決了塊對象存放的問題,又不會引起其他命名的沖突。一個字,妙!!!!
其他漂亮的特征:
注釋版語法外套,方便于測試數據填充及可視化編輯。
單一的語法規則,方便解析與擴展。
等等。。。。
好了,贊嘆之余還是給出一點點遺憾:
boolean 運算有點丑陋。
我個人更期望 js的boolean運算風格,沒有必要一碰到boolean 運算就返回true ? false
我們完全可以返回一個更有意義的值,比如,我更期望這個語句能如我所愿的執行。
${ variable|| " 默認值 " }
當能,如上支持,CT是有的,它的寫法是
${ variable | " 默認值 " }
但是,我感覺,這個語法就有點復雜了,也不那么直觀。
一般來說| 是按位取或,是位運算符,這里這個用法,跳躍的確實有點大,較難接受的。
posted @
2007-11-29 21:28 金大為 閱讀(1434) |
評論 (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 金大為 閱讀(960) |
評論 (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 金大為 閱讀(796) |
評論 (2) |
編輯 收藏
摘要: 剛剛學習了一下網頁動畫中上的緩動效果,分享一下學習心得。
緩動曲線的概念:
緩動曲線是一個0為起點的連續函數曲線,x軸表示時間變化,y軸表示位移變化。曲線的斜率反映出運動的數度。
緩動效果在Flash動畫中比較常見,用于模擬一些現實中常見的運動軌跡,或者制造一些超絢的效果。
而且新版本的Flash中,內置了一些常用的緩動曲線函數。
可惜,Flash的這些曲線函數不是開源的...
閱讀全文
posted @
2007-10-14 21:14 金大為 閱讀(1231) |
評論 (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 金大為 閱讀(824) |
評論 (2) |
編輯 收藏
JSA 這個壓縮工具,是java編寫的,需要安裝java運行環境。
這多少給一些非jav程序員帶來點不便。
現在我們發布servlet在線壓縮版本。無需安裝,在線壓縮,給非Java用戶一個更加便捷的使用方式。
項目主頁:http://www.xidea.org/project/jsa/
現在的在線壓縮服務器由Seaprince 提供。
歡迎更多有空閑服務器資源的朋友安裝JSA在線服務,我將在jsa項目主頁提供鏈接,方便大家使用。
仍外,為了避免服務器資源被惡意濫用,我們默認啟用了圖片驗證,服務頻率限制等保護設置。
給用戶帶來些不便,敬請諒解。
posted @
2007-08-22 16:28 金大為 閱讀(1026) |
評論 (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 金大為 閱讀(786) |
評論 (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 金大為 閱讀(1171) |
評論 (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 金大為 閱讀(870) |
評論 (0) |
編輯 收藏
大約兩年前私下編寫一個wiki時使用的代碼生成工具,最近想繼續這個wiki項目(http://sourceforge.net/projects/txdoc ),也順便吧這個代碼生成工具整理出來。
PPT見:http://www.aygfsteel.com/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 金大為 閱讀(1052) |
評論 (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 金大為 閱讀(1257) |
評論 (3) |
編輯 收藏
已經有一年多沒做java這塊了,今天翻出這個一年前寫的代碼生成工具,準備開放出來,或許對某些人還有點用處。
這個代碼生成器是基于xdoclet2的改進版。
所做工作:
* 生成Hibernate 映射文件及相應得spring的配置文件。
* 生成Hibernate DAO 文件及命名查詢名稱常量(新)。
* 生成Spring配置文件(支持事務申明)。
* 生成xwork配置文件(增加多包及spring屬性支持)。
* 驗證資源冗余及缺失。
先吧PPT放出來,如果有人(包括我自己)能用上再吧代碼整理一下,放出來。
ppt下載:http://www.aygfsteel.com/Files/jindw/codegen.rar
posted @
2007-06-30 08:44 金大為 閱讀(1012) |
評論 (6) |
編輯 收藏
裝飾引擎簡介:
系統默認的裝飾引擎為:org.xidea.decorator.DecoratorEngine。
JSI裝載后,將做如下操作:
判斷有無裝飾器命名空間聲明(xmlns:d= "http://www.xidea.org/taglib/decorator")
若有,將在文檔裝載結束后,啟動裝飾引擎,初始化當前可用的裝飾提供者表。(裝飾提供者是一個JavaScript包,在注冊這種裝飾包時可同時指定他的別名,別名*表示默認包)
遍歷當前文檔,凡是該命名空間的節點,都被看作需要裝飾的元素。若當前文檔存在裝飾元素,啟用遮罩(關機效果),頁面將不可操作(仍可查閱)。
查找裝飾元素對應的裝飾類(通過tagName判斷類名),采用異步方式動態裝載這些裝飾器類(不會裝載到全局空間),并更新當前進度信息,同時設置裝飾器之間的關系(parent,children)。
以深度遍歷的方式遍歷這些節點,注冊組件(以后可以通過$JSI.getComponent函數獲取裝飾器對象),依次執行他們的before操作,和decorate操作。
完成裝飾,取消遮罩,頁面進入可用狀態。
裝飾器規范簡介:
裝飾器指的是所有擁有decorate成員方法的類。一般來說,可將一組裝飾器歸為同一個包中(太復雜的裝飾器,可將具體邏輯放置在其他包中),能后在配置文件中定義裝飾包。
scripts/config.js $JSI.addDecoratorProvider("org.xidea.decorator","xidea","*");
裝飾器類包含兩個方法before、docorate分別在遍歷前(子節點未裝飾)和遍歷后(子節點裝飾完成)調用。
同時,裝飾引擎遍歷時還將注入如下三個屬性:
parent:父裝飾器
children:子裝飾器集合
attributes:裝飾器屬性集對象(只有一個成員函數:get(attrName) )
JSI現有裝飾器集合簡介
目前JSI2最高版本2.0預覽版 (2007-04-16)包含如下裝飾器:
DatePicker
日期選擇控件,參照xul datepicker標簽,支持彈出方式(默認值 type='pop'),和內嵌式(type='grid')
Editor
編輯器控件,參照xul editor標簽
Spinner
Spinner控件(window時間日期管理中,年份調節的控件),參照backbase 的 Spinner標簽
TabBox、Tabs、Tab、TabPanels、TabPanel
TabBox(標簽頁)控件,參照xul tabbox標簽
Code
代碼語法高亮顯示控件,參照SyntaxHighlighter的顯示風格
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 金大為 閱讀(772) |
評論 (0) |
編輯 收藏
JSI組件模型是一種用來裝飾簡單html元素的框架,使用簡單的xml標記,標識其裝飾行為,比如將一個普通的input裝飾成一個日期輸入控件,將一
個html ul標記裝飾成菜單或樹,將一個textarea裝飾成一個代碼語法高亮顯示區域,或一個wysiwyg html編輯器。
JSI啟動后將自動檢查decorator標記,構建層次結構,自動做相關類的尋找、導入和裝飾操作;實現零腳本代碼的web富客戶端編程。
代碼示例:
日期選擇器 (DatePicker):
< d:datepicker > < input type ="text" name ="test2" /> </ d:datepicker >
編輯器示例 (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 >
Spinner控件(Spinner 類似window時間日期管理中,年份調節的控件):
< d:spinner start ='0' end ='8' step ='2' > < input type ="text" name ="test2" value ='0' /> </ d:spinner >
客戶端包含(Include):
< d:include url ='menu.xml' xslt ="menu.xsl" ></ d:include >
代碼語法高亮顯示控件(Code):
< d:code language ="js" > < textarea > alert(‘Hello World’) </ textarea > </ d:code >
標簽頁控件(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 >
綜合示例:
來一個復雜一點的完整的例子,以日期選擇控件的演示頁面為例
頁面上有: 標簽頁裝飾器(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 > < !-- 開始日期裝飾器(內嵌式) -- > < d:datepicker type='grid' > < input type="text" name="test1" / > < /d:datepicker > < !-- 開始日期裝飾器(彈出式) -- > < d:datepicker > < input type="text" name="test2" / > < /d:datepicker > </ 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 金大為 閱讀(815) |
評論 (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 金大為 閱讀(802) |
評論 (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 金大為 閱讀(670) |
評論 (0) |
編輯 收藏
何謂安需裝載?
腳本程序一般都是下載后執行
,當腳本庫非常龐大時,一次性下載起來非常費時,傳統的解決方式是,按功能模塊把腳本寫在不同的文件中,頁面上手動加入script標簽裝載指定內容,但
是這有一些缺點,類庫的使用者需要知道沒個腳本之間的關系,順序要求等等,而不可能要求每個類庫使用者都對其非常熟悉,出錯的可能性很大。于是很多框架開
始支持導入指令,想使用什么一個導入函數就完了,不必一堆堆的script文件,不用小心翼翼的關注著他們的依賴關系。
安需裝載可分如下三種模式:
即時同步按需裝載 ( 阻塞, JSI、JSVM、dojo) 。
最簡單的按需裝載實現,通過XMLHttpRequest同步裝載腳本文件實現。問題是,瀏覽器使用這種方式同步獲取資源時將導致瀏覽器阻塞:停止響應用戶事件、停止頁面重畫操作。所以,雖然編程最為簡單,但是用戶體驗最差。
異步 按 需 裝載 ( 無阻塞, JSI 2.0+ )。
異步導入,不必多做解釋,用戶體驗好,但是因為其異步特征,處理起來比較麻煩。
延遲同步按需 裝載 ( 無阻塞, JSI 2.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(); })
延遲同步按需 裝載 ( 無阻塞, JSI 2.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 金大為 閱讀(626) |
評論 (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 金大為 閱讀(660) |
評論 (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 金大為 閱讀(705) |
評論 (0) |
編輯 收藏
這次發布的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 金大為 閱讀(754) |
評論 (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 金大為 閱讀(128) |
評論 (0) |
編輯 收藏
剛發布JSA的webstart版,順便吧這個古董級別的小程序也發布一下。
僅供那些和我一樣棋術平平的無聊人士打發時間。
高手就不必了:)
當能,如果是想找個地方出出氣,也可以,呵呵。
http://www.xidea.org/webstart/chess.jnlp
沒有棋譜,所以,開局的棋力很差。中局還行。
posted @
2007-06-14 10:51 金大為 閱讀(748) |
評論 (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 金大為 閱讀(938) |
評論 (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 金大為 閱讀(739) |
評論 (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 金大為 閱讀(1391) |
評論 (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 金大為 閱讀(750) |
評論 (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參數都將忽略。暫時只有添加函數,沒有刪除函數(有刪除的必要嗎?)。
不同之處:
這個事件處理函數集與其他常見方式的卻別有:
this支持。IE的attach方法添加的函數,運行時this指向window對象,JSI吧這點給糾正過來,與w3c的addEventListener行為一致。
事件類型直接體現在函數名中,這樣有利于書寫上的錯誤及早發現。
事件格式化,將事件的訪問方式格式化為W3C的方式。
自動清理,這也不算不同吧,現在大多數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 金大為 閱讀(732) |
評論 (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 金大為 閱讀(227) |
評論 (2) |
編輯 收藏
如題:
JSA介紹:http://www.javaeye.com/article/77776
posted @
2007-06-05 18:34 金大為 閱讀(310) |
評論 (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 金大為 閱讀(631) |
評論 (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 金大為 閱讀(1631) |
評論 (0) |
編輯 收藏
先申明一下,我討厭Ajax這個名詞。舊藥裝新瓶。(像那個80來歲的楊某一樣令人討厭,呵呵)。
正題:
Ajax所謂的異步加載,為何需要異步,可以說異步操作通常都是一個成熟的程序設計人員會盡力回避的東西。復雜度徒增,不好控制,容易出錯。
但是,這個問題放在瀏覽器上就是另外一個情形,瀏覽器上的腳本+事件通常只有一個線程。那些看是多線程的函數:setTimeout,
setInterval,其實都不會插入或中斷任何一個其他的在執行中的任務,而且一旦你的腳本尚在運行,那么不管你是否在掛起等待,所有的事件都將阻
塞。窗口重畫,拖動...也都得靠邊站著,感覺就像是某個程序進入一個死循環了。
以前得腳本都是做一些簡單得事情,需要的時間,用戶基本上都感覺不到,后來XMLHttpRequest的興起,問題出來了,訪問網絡資源,你得受網速得
限制,如果同步的獲取,那你就等吧,等個幾秒幾分幾十分的,不是不可能。這時瀏覽器可沒那么聰明,站旁邊傻等,什么窗口重畫,移動啊,都裝個沒聽見。
瀏覽器傻了,用戶可不傻,靠,這個網站咋的,吧我的瀏覽器都搞死了?加入黑名單,或者碰到個脾氣好點的,把你辛辛苦苦、沒日沒夜、綿綿數月敲下來的腳本,一律禁止運行... 傻了把,可憐的腳本程序員。
看似瀏覽器的問題嘛,可是,誰叫你是中年諸葛亮呢,扶不起的阿斗你也得背著,朽木上刻章方顯你的出眾嘛。于是異步操作遍地開花,第N次世界大亂從此開始。
確實這里使用異步操作很有見成效,先告訴xmlhttp后臺加載網絡資源。一邊涼快涼快,加載完了通知一下。喝喝茶,看看報,N+1秒鐘過去了,報告: 001.xml全體元素集合完畢,帳前待命...,ok,..... (機密,隱藏...)。
不錯把,你不必焦急的盯著屏幕上所不期望的白大塊,不用使勁的失望的拖動著沒有的鼠標。你只需要東瞧瞧西瞅瞅,隨意的打發點時間,一會,東西準備好了,歸你了,愛怎么辦就怎么辦吧。
沒看明白?簡單點說吧,就是把資源加載這一操作放在腳本線程之外,那么就不會有長時間運行的腳本,那么用戶就覺得你的程序響應快。就是是說ajax,其實asynchronism也就這一個地方而已。
記住一點,瀏覽器上單純的腳本程序,本身是不支持多線程的,異步也就無從談起,而現在所說的異步,都不是純粹的ECMAScript,都是利用瀏覽器帶有的某些原生對象實現的。
雕蟲小技而已,結果吹得雞毛滿天飛。眾嘴紜紜之勢,眾目睽睽之下,公雞下蛋,鯉魚上坡,皆有可能。
posted @
2007-06-02 14:11 金大為 閱讀(998) |
評論 (13) |
編輯 收藏