Friday, October 31, 2008

实现了一个简单的js test工具集

一时兴起, 实现了一个简单的js测试框架, 结构如下:
==========================================================================
//测试项
var TestEntry = function(id){
return {
//目前只实现了一个简单的方法, 其他的可以自由扩展
assertTrue: function(result){
var r = ET.get(id);
r.append(result? "Ok" : "Error");
r.addClass(result? "ok" : "error");
}
}
}
//测试执行器
var Test=function(){
var mc;
return {
init:function(dom){
ET.get(dom || document.body).append("<div
id='messageconsole'><b>Message console:</b></div>");
mc = ET.get("messageconsole");
},
addTest: function(msg){
var id = UUID.generate("v4");
mc.append("<br><b class='item'>test "+msg+" <b class='result'
id='"+id+"'></b></b>");
return TestEntry(id);
},
reset: function(){
mc.html("<br>");
},
report: function(){
//设置延时是为了, 等待异步执行的部分ajax测试完成
setTimeout(function(){
var total = ET.getByJQSelector("b.item").length;
var error = ET.getByJQSelector("b.error").length;
var ok = ET.getByJQSelector("b.ok").length;
mc.append("<br><br>"+
"<b class='item'>Totally "+total+" tests,</b>"+
"<b class='passed'> passed "+ok+" tests,</b>"+
"<b class='failed'> failed "+error+" tests,</b>"+
"<b class='unfinished'> unfinished "+(total-ok-error)+" tests</b>");
},
1000);
}
}
}();
==========================================================================
css代码:
.item {
color: blue;
}

.result, .unfinished, .failed {
color: red;
}
.passed {
color: #55FF55;
}
==========================================================================
用法:
Test.init();

//普通测试项
Test.addTest("log message here").assertTrue(1+2==3);

//异步操作的测试
var ajaxTest = Test.addTest("ajax request test");
Ajax.request({data:{id:1}, url:'../getName.htm', callback:function(data){
ajaxTest.assertTrue(data.name='apple');
}
});

Test.report();

解释说明:
Test.addTest在系统中添加一条测试记录,
返回一个TestEntry, 用返回的TestEntry的assert系列方法, 来断定此测试项的正确与否

Thursday, October 30, 2008

[转] 北京的慢性驱逐令

原文: http://home.donews.com/donews/article/1/130211.html
很有同感的一篇文章, 转来分享一下


离开北京已经有一年多了,但至今还是常有人不理解地问:"为什么你在北京有房有车有公司,却会在一夜之间决定彻底离开北京?"问的朋友多了,于是,我想倒不如把我是如何"被北京抛弃"的原因说说,也好省些口舌。

北京的慢性驱逐令

1996年的建军节乘火车到北京,直至20078月与人签订售房合同,我在北京整整生活了11个年头。其间,住过中央社会主义学院的办公楼,住过小南庄的居民楼,住过万寿寺的老院子,直至自己买楼置业。过去的11年历历在目。

说句实话,我还是比较喜欢北京人的,虽然对老北京不够上进和锐气有些失望,但多元的北京文化不像上海的市侩、小气,也不像南方人的生意、烦躁。恬淡、性情的文化使外来的人们感觉不到太强的排外感。倒是外来的人群对老北京有些"排内"。

然而,我终究是成不了北京人的。

1998年,我跳槽到一家新的报社工作,报社提出员工档案要统一放到(原)电子人才中心管理,我托老爹去浙江丽水市最早分配的工作单位调档。结果告知:因为原来与单位签订的5年劳动合同没有执行完,我就擅自离职,剩余年限需按每年1000元交钱后才能调档。

我当时就有砍人的冲动:当时在丽水工作半年,一个月400元工资,一共才发了我二千多元的工资,现在居然要收我4000元——半年白干不说,还要倒贴钱。如果是大城市,我也就认了,丽水这么个"浙江的西藏"也值得我打破脑袋往里钻?

单位领导还算"仁慈":你还没干满一年,按理,要照五年计算,我们就只算了你四年的钱。

后 来有一次,总编曾经提出可以帮我的户口"弄"到北京。当然,我因此会欠他老大的人情,我还不得不和报社签订长期的"卖身契"。考虑到用"自由换户口"不是 什么划算的"交易",我也就没应这茬——户口这种老掉牙的玩意迟早会死掉的,说不定十年后就没什么用了,社会总不会倒退吧?

2000年底,我去了《计算机世界》报社。突然有一天,当时一位领导不知抽了什么风,要求员工把档案在限期时间前必须把档案调到北京市人才,否则工资只能拿到正常工资的1/3

这一下,全报社的同事都忙活了起来,我当然也不例外。当时我的档案还在电子人才,当我去电子人才办调档手续的时候,被告知:户口不在北京的人员档案不能在北京不同档案管理中心之间直接调档,须先调回户口所在地,再调过来。

于是,我把档案调回到了老家县城的人才中心。再委托人将档案调至北京市人才。过了很长时间,每次打电话,北京市人才总说没有我的档案。只好打电话问县人才,告之:档案被北京市人才退回去了。

又打电话问北京市人才,工作人员说,你的档案在县人才,我们没法接收,你必须先高到当地地市一级以上的人才才可以调过来。

我又托老爸将档案调到了当地市人才。又过了很长时间,北京市人才又说档案被打回去了,原因是我当初没有转正就离职,档案里没有"干部"身份。我终于明白了:北京是"干部"呆的地方,不是"干部"就免进。

从此,我患上了档案过敏症——一提到档案,脑袋嗡嗡作响。

报社和我类似的情况很多,领导的"高招"最后不得不不了了之。

过去在北京没有户口是无法上车牌的。尽管一直想自己买辆车,但一想到上车牌还是找北京本地户口的人"挂靠",这又是件脑袋大的事。

2001年十月,北京市宣布拥有工作寄住证(工作居住证的前身)的人可以允许上车牌。我的"寄住"证是前一家单位办的,没有按规定交回,不过快到期了。我赶紧挑了辆车去上牌,工作人员疑惑地看着我:这个玩意儿能上车牌吗?

你没看新闻吗?我心里忐忑不安地回答,紧盯着工作人员打电话询问的每一个动作和表情。看到他的脸皮松驰着,我心安了一点——总算有自己的车牌了!

2002年小家伙出生后,麻烦又要开始了:有小孩的日子过得很快,以后的上学又成了一个麻烦事。交赞助费倒在其次,更担心以后考大学——北京的教学应试能力没法和浙江比,小孩要在北京上学,回浙江考大学就惨了。原来大学同班的北京同学分数要低200分左右,这种成绩在浙江是上不了大学的。分数线的差异可能要了小孩未来的命。

我第一次感到自己对中国的改革过乐观了:几千年的户籍制度改革比蜗牛都慢,而小孩却长得飞快。也许我们这一辈子是看不到真正的自由户籍制度的了。

离京:无奈的选择

选择离开北京不是件容易的事,毕竟人的一生不会有太多的11年。在北京,我从一个毛头小伙成了一个中年人。但最终,我决定离开北京——我想无论我多努力,我终究成不了北京人。

2007年春节回家后,我断然决定:准备离开北京,停止公司开展新业务,老项目执行完后就关闭公司,卖房子离开。

对南方人来说,北京是脏,北京是干,但其实这些都可以适应,而一次次政策性的歧视让人有不如奴隶的感觉——即使是奴隶,他的努力工作也多少会搏得主人的一些欢心;而那些对外地人的羁绊却像故宫的一重重门槛一样走不到头,而且坚不可摧。

所以,故宫我是不喜欢去的,除了有一次陪长辈,我从未进去游玩过——在我看来,这是一个阵旧的,封建的象征,体制的"故宫"我已经走厌了,再不愿去看那形式的故宫。

2007年回到杭州,买了一套房子,找了一份工作,今年上半年时把户口转到了杭州,小孩也顺利地进入了小学。打工的日子花钱没像以前那么随意了,但我还是认为自己的决定并没有错。

窗外秋雨迷离,我回过头去看看自己的脚印,一步一步从浙江走到北京,又走回到浙江。那一段激情燃烧的岁月,那一段北京的创业史都随风而去,只在记忆里隐约可见。

一段时间里,我一直在想:是我抛弃了北京,还是北京抛弃了我?我想也许在北京看来,我是一个寄住者,我去北京是和北京人抢地盘、抢资源的,所以,我遇到的事总会在有意无意地驱逐我。一些朋友从国外回来,最后又走了,我于是想:是祖国抛弃了他们,还是他们抛弃了祖国?

中 国太多的东西沉淀了几千年,以至于每个人对它熟视无睹。当人们习惯成自然的时候,不合理也变成了合理。就像有多少人知道蛋白精的存在却当成了一件合理的 事,这是一种可怕的沉沦,这种沉沦的更可怕之处在于沉沦者的不自知——用人血馒头治痨病的人还隐藏于每一个人的心灵深处,它因此影响着中国的政治、经济、 文化和所有的社会环境。

JQuery 树插件介绍: jQuery SimpleTree Drag&Drop plugin

发现一个很好的树插件: jQuery SimpleTree Drag&Drop, 感觉很好, 代码质量不错, 支持拖拽, 风格清晰, 这里推荐一下. Demo看这里.

Saturday, October 18, 2008

Taffy DB : A JavaScript database for your browser

Taffy DB : A JavaScript database for your browser

Taffy DB is a free and opensource JavaScript library that acts as thin data layer inside Web 2.0 and Ajax applications.

What makes it cool:
  • Under 10K!
  • Simple, JavaScript Centric Syntax
  • Fast
  • Easy to include in any web application
  • Compatible with major Ajax libraries: YUI, JQuery, Dojo, Prototype, EXT, etc
  • CRUD Interface (Create, Read, Update, Delete)
  • Sorting
  • Looping
  • Advanced Queries

Think of it as a SQL database in your web browser.

Link To Taffy DB

Wednesday, October 15, 2008

最近动向

  1. 正在比较深入的研究前台开发, 写一些小的框架.
  2. 研究SEO, Google Adsense, 正处于实验阶段, 本站就是实验室, 争取把"小楼听雨"给优化到google, baidu搜索结果的第一页, 这个任务可以比较重, 呵呵.
  3. 整理, 搭建公司的基础架构, 这一块任务比较重, 需要考虑的比较详细.
  4. 另外的一个django站点, 纯凭自己的爱好做着玩的也会在最近上线, 正好用来研究前台开发, 呵呵.
  5. 以后有了什么经验, 会及时拿来分享.

Tuesday, October 14, 2008

A ibatis code generator - iBATOR

iBATOR is a code generator for iBATIS. iBATOR will introspect a database table (or many tables) and will generate iBATIS artifacts that can be used to access the table(s). This abates some of the initial nuisance of setting up objects and configuration files to interact with database tables. iBATOR seeks to make a major impact on the large percentage of database operations that are simple CRUD (Create, Retrieve, Update, Delete). You will still need to hand code SQL and objects for custom queries, or stored procedures.

iBATOR will generate:

  • SqlMap XML Files
  • Java Classes to match the primary key and fields of the table(s)
  • DAO Classes that use the above objects (optional)
Example Class Usage Notes:
  • Example Class has ored Criteria list and every Criteria has many anded filed list
I want to implement a ibatis code generator some day, But I find it "unfortunately".

Saturday, October 11, 2008

Get Computed Style Attribute

when a dom style has been setted more than one times in css file, the final style should be computed, such as:
css file:

#abc{
color: red;
}

div #abc{
color: red;
}

html file:
...

<div><span id='abc'>text in span...</span></div>
...

js code:

var spanEl = document.getElementById('abc');
var ret = document.defaultView.getComputedStyle( spanEl, null );
var color = ret.getPropertyValue("color");

so we can get the right style which appled to dom.

js简单继承的实现 - 网上做法修正篇

网上有些继承prototype实现上有bug例如:

function base() {
this.member = ["dnnsun_Member",2,3,4];
}
var child=function(){
};

child.prototype=new base;
var c1 = new child();
var c2 = new child();
c1.member[1]=333;
alert(c2.member[1]);

结果是: 333

base中如果有集合, 对象属性, 这种简单继承导致的后果是所有的child的实例都共享了base的同一个member属性. 所以要尽量避免此种情况, 尽量在父类中只是定义方法, 变量改为传入的方式. 估计这也是为什么jquery, ext等框架不强制继承的子类必须subclass_instance instanceof superclass==true的原因.

Event driven web application - javascript event bus

I implemented a javascript event bus for asynchronized web application, and this article hasn't any relationship with Ajax and Dom events
Using Event bus benefit your web application development, such as:
  1. low coupling between moudles
  2. flexible event dispatcher
  3. partible bussiness logic
  4. consistent code style
This is a very sample demo code to guide you.
I have two components in my web app, one is a tree, another is a grid list, when current highlighted tree node was been deleted, the grid list should load it's next sibling node's data.

normally, we could write in tree.js:

//delete current hightlighted tree node
...
GridList.clear();
GridList.load(next_sibling_node.name)
...
but GridList was defined in grid.js, so tree and grid moudle was high coupled.

in new asynchronized web application. we can write in tree.js:

//delete current hightlighted tree node
EventBus.publish("tree-node-deleted", node);

and write in grid.js:

EventBus.subscribe("tree-node-deleted", function(argObj){
GridList.clear();
GridList.load(argObj.name)
});

I think this is a good experence in web development.

Wednesday, October 08, 2008

利用event bus来降低前台业务代码耦合度, Event bus - javascript, js实现

/*
demo:
var observer = function(paramObj){
alert("bomb event comes!" + paramObj);
}

//add business event listener
EventBus.subscribe("tree-node-change",observer);
//remove business event listener
//EventBus.unsubscribe("tree-node-change",observer);
//publish business event
EventBus.publish("tree-node-change",{oldName:"abc", newName:"cdef", id: 123});
*/

/*
ReadMe:
Goal: Using business event dispatcher to reduce code couple between web moudle,
目标: 为了尽可能的减少模块之间业务逻辑的耦合度, 而开发了这个消息总线, 主要用于业务逻辑的事件传递
使用规范: 每个js模块尽可能通过事件去通信, 减少模块之间的直接调用和依赖(耦合)
*/

var EventBus = function(){
var observers={};

var publish=function(eventName, argObj){
var obs = observers[eventName];

if(!obs){
return;
}

for(var i=0;i<obs.length;i++){
obs[i](argObj);
}
}

var subscribe=function(eventName, observer){
var obs = observers[eventName];

if(!obs){
obs=[];
observers[eventName]=obs;
}

obs.push(observer);
}

var unsubscribe=function(eventName, observer){
var obs = observers[eventName];

if(!obs){
return;
}

for(var i=0;i<obs.length;i++){
if(obs[i]==observer){
obs.splice(i,1);
break;
}
}
}

var unsubscribeByObserver=function(observer){
for(var eventName in observers){
removeByName(eventName, observer);
}
}
return {
publish:publish,
subscribe:subscribe,
unsubscribe:unsubscribe,
subscribeByObserver:unsubscribeByObserver
}
}();

Monday, October 06, 2008

[转] 小三的爱情扒皮必修课 - 画皮精彩影评

   说是,小三必修课
    
    其实,是所有情场中人的扒皮戏。
    
    《画皮》是一个惊喜,有些是无心,有些是故意。
    
    因为戏路太善良,我们总是忍不住笑场。
    
    然而,面对,那些太刻意的真情告白……我们如果不笑,难道要跟着哭吗?
    
    这场戏,需要些时间沉淀,然后,就有人像我们回忆八十年代的港片一样来回忆这张《画皮》。
    
    不如把笑点抖一抖,顺便帮着大家扭曲一下逻辑。
    
    这个故事告诉我们生活中的许多大道理。
    
    故事的基本结构是这样的。
    
    
    
    陈坤和甄子丹本来是战友,两个人都喜欢赵薇。赵薇选择了嫁给陈坤,甄子丹愤而远走。
    画皮定律一:再好的朋友,抢一个心上人,也会翻脸。无论男女。
    
    陈坤救了一个女人周迅回家。周迅其实是妖怪。
    画皮定律二:如果一个有家的男人把一个单身女子带回家,这绝对是场冒险,不管这个姑娘会不会画皮。
    
    赵薇怀疑陈坤喜欢周迅,进而发觉周迅来了之后,城里开始死人。认准周迅就是妖怪,
    画皮定律三:如果一个女人发现自己的男人外面有了女人,那么到处跟人说那个女人是狐狸精,只能显得自己像个疯子,太小气。
    
    
    但是没有人相信她。她写信喊来了甄子丹。
    画皮定律四:还是去找自己的旧情人,是正路!(找旧情人来干什么,看你的兴趣)
    
    
    周迅想嫁给陈坤,不是做妾,而是做夫人。
    画皮定律五:如果一个小三,喜欢上了一个有妇之夫,又不像只是玩一玩就吃掉他,而是想要个名分,会搞得三个人都很凄惨。
    
    甄子丹来了,降魔者孙丽也来了,孙丽看着甄子丹很有感觉,甄子丹对孙丽也有点感觉。
    画皮定律六:男人终究是要变心的,不管他当初多么爱你,只不过是动手没动手的差别,而且,总是有更年轻的姑娘出现的!!
    
    还有个蜥蜴精追随周迅而来,蜥蜴精爱着狐狸精周迅,周迅不喜欢他。
    画皮定律七:讨厌长得不帅的男人,女人讨厌"长舌头"的男人,讨厌知道自己当年底细的男人,讨厌,吃的东西,跟自己口味不同的男人……之后数条,都是第一条的借口。
    
    
    甄子丹表示自己相信赵薇,赵薇说甄子丹是个好人。
    画皮定律八:如果一个人给你发了"好人卡",基本来说,这个人打算送死你去,吃定你一辈子了。不知道逃的,是傻瓜。
    
    
    周迅想色诱陈坤,蜥蜴精吃醋,进攻陈坤,大闹府里。
    画皮定律九:在两个女人之间摇摆的男人,比较吃香。在两个男人之间摇摆的女人,其实比较危险。女人斗心计,男人斗体力。
    
    
    蜥蜴精又进攻赵薇,关键时刻,陈坤选择去保护赵薇。
    画皮定律十:所有的男人,都会先考虑自己的老婆的,小三们的悲哀…… 其实,不是因为他更看重老婆,而是他的身份促使他必须先救自己的老婆,否则,会被人说,没有人味。
    
    周迅终于明白,陈坤更在乎身为老婆的赵薇。
    画皮定律十一:情人早晚会发现真相的,这个时候,怎么选择,能比较出一个人的智商。
    
    于是周迅直接胁迫赵薇离开,逼赵薇服毒。
    画皮定律十二:偷情的乐趣,就在于偷偷摸摸,有人争抢的感觉比较刺激,直接逼宫……注定是悲剧
    
    …………正邪开始大决战!!
    
    
    
    所谓,凡事,不能十三点。那就到此为止吧。
    
    爱情这种事情,都不能仔细推敲,一推敲,就千疮百孔。

-- 爆音爆食 发布于:2008-09-23 22:37

Saturday, October 04, 2008

js简单继承的实现, 改进篇

前文表述: js简单继承的实现

前文问题:
alert(child instanceof base); 打印false, 此处并没有实现真正的继承

改进:
function base() {
this.member = "dnnsun_Member";
this.test=function(){
window.alert('in base');
}
}

base.prototype.test= function() {
window.alert("base member "+this.member);
}

function extend(child, b) {
b.call(child);
child.prototype=new b;
}
var childclass=function(){
this.test=function(){
window.alert("in child");
}
};


extend(childclass, base);

child = new childclass;

window.alert(child.member);
window.alert(child.test);
child.test();
window.alert(child instanceof base);

不能没有doctype

* 有他的好处, 我这里放下不表, 今天就说说没有他时, 在开发中遇到的问题
   * 在不同的浏览器下网页莫名其妙的布局问题
   * document.body与document.documentElement谁的属性是准的?
      * scrollLeft
* Right
* Top
* Bottom