一月 22, 2006

最近正在构思一个服务,起名叫”SiteNote”,起作用是当用户处于任何一个页面的时候,都可以打开SiteNote这个服务,对当前页面进行”Note”,也就是”笔记”这种行为。日后当用户再次访问该页面的时候,也可以将以前的”Note”,Load到当前页面。同时,用户也可以将自己的”Note”置为”public”,以便其他用户也可以在当前页面察看到你公开的Note。

听起来比较好玩,同时也是一次创新的尝试,互联网上好像还没有同类的产品。

经过几天的研究,准备用bookmarklet来实现这种奇特的服务访问方式,说太多也没意思,主要看几个截图,好像会比较好一些。

  • 到Baidu.com的首页,启动bookmarklet

  • 之后点击”Add Note”,会出现一个小方块,就是一个Note

  • 之后选择好您需要放置Note的位置,之后点击”pin”将Note固定在这个位置,随后会出现文本框,让您输入相关信息

  • 输入完成相关信息后点击”save”保存结果。一个Note就这样完成了

  • 之后只要进入Baidu.com这个站点,启动bookmarklet之后,就能看到您以前所做过的Note,因为Note是存放在服务器的,所以用不会丢失

考虑到这个东西应该会有很多种玩法,比如Note可以不单单是一段文字,可以是图片,是用户绘画,可以是用户选中的网页上的文字,所以个人认为,如果把这个概念作出来的话,应该会有一片天地。接下来我会花一些时间在这个想法的产品化上面!

自己找了一台临时的服务器,可以放一个还处于构想阶段的模型,大家可以看看,具体使用方法是:

  1. 将以下链接加入您的收藏夹(具体链接地址附在下面的文本文件中,bookmarklet.txt)

bookmarklet.txt

   2. 在您需要进行Note的站点点击SiteNote的书签,启动SiteNote

一月 20, 2006

昨晚收到了Live.com的Beta mail邀请函.

登陆进入系统,期待了很久的界面出现在眼前,可是 3分钟后,有点失望!

概念是传统的概念,功能是传统的hotmail,我实在没有看出有什么非常吸引人的功能.

从技术层面来看,live mail用了FireAnt这个东西,估计是atlas里面的一些东西, live mail用了非常heavy的client framework atlas,这个东西包含在asp.net 2.0里面,用来完成javascript oo,ajax等最近抄的比较热的功能.前几天看到有关于atlas style oo & prototype.js style oo的一个benchmark,好像是atlas的效率要高一些,但是我觉得这个不会是选择某个框架的决定性因素.

live mail没有刷新,在首次加载的时候已经将所有需要的client script load完成.对于附带的calender等其他几个功能,并没有更换成所谓的calender.live.com等,仅仅是使用iframe来了个换汤不换药.很没有价值.live mail的拖拉功能很贴心,但是用了那么久的gmail,好像d&d在这种application里面并不是非常急需的feature,gmail使用比较常用的select:read,unread,starred,unstarred等选择功能来标记mail,之后进行删除移动等操作,用着也凑合.live mail则原封不动的实现了ctrl单选,shift多选的desktop application feature,这点非常不错.同时支持多个mail一起拖动等操作,可见技术上也费了不少功夫.

gmail.com也同样是所谓的ajax application,可是据我研究发现,每一个操作基本上都有页面刷新的操作.比如当你点击inbox的时候,实际进行的操作是,javascript 进行 mainframe.location.replace操作,估计这个操作里带有一定的cache机制,比如多长时间之内同一个url不进行replace操作.说道这里,就要解释一下,其实我们看到的gmail界面是一个MVC中的View,与Model的混合体,从HTML角度说是一个FrameSet中的Frame,name=main.参看gmail.com首页中的这一句:

document.write(’<frameset onload=lj() rows=”100%,*” border=0><frame name=main xsrc=”html/loading.html” mce_src=”html/loading.html” frameborder=0 noresize scrolling=no><frame name=js xsrc=”html/loading.html” mce_src=”html/loading.html” frameborder=0 noresize></frameset>’);

我们看到的和操作的,都是在name=main的frame中进行的.为什么这么做,我估计原因是,很多UI logic layer的controller code如果都放在一个页面里,页面会很肥,加载会很慢.所以在name=js的frame里面,所有javascript code都放在那里,在页面不刷新的情况下,只刷新name=main的frame里面的东西.其实我们的每个操作都是带刷新的(不包含一些小操作),这些带刷新的操作,基本都是一些令页面布局发生很大变化的操作,比如inbox切换到spam…..根据我的分析,每一个这样的操作实际包含一下过程:js替换main frame的url,在server side render main frame html 的时候,包含有这样的script段:

D([”cfs”,[[”lei liu”,”digitalghost.ebook@gmail.com”,0,”"]],[]]);

D其实是一个js frame中的函数,D的arguments是JSON代码,这个函数的具体功能估计是向js frame传递当前model的信息,页面脚本的最后一句

try{top.js.L(window,1029,’37e5d0cb35′);}catch(e){}

功能就是调用js frame中的代码将model的状态转换到view,期间可能使用了google-ajaxslt这个框架,对于是否真使用这个框架,我也是道听途说的….在这一系列的操作中有一个sercurity risk,就是观察发现:

D=(top.js&&top.js.init)?function(d){top.js.P(window,d)}:function(){};

还有刚才的top.js.L()都将当前frame的window对象传递给了top,原因是:如果在top中直接操作frame的document对象,会出现sercurity denied的exception,而如果将window对象传入top的一个function之后,再使用这个function操作frame的window对象就不会出现问题.这个具体的原因我也不知道,但是实际测试以后果然是存在这个问题.gmail刷新main frame,将数据从server side返回,但是并不返回html的最大的好处,就是不用在browser中放一些暂时不用的html代码,因为单纯的让很多html element进行Style.display =’none’的操作不管对于程序性能,还是程序结构都是一种恶梦.同时,使用这样的frame机制,令gmail天然的支持了broswer 的 back , forword,bookmark等操作.实现了history的功能.这恰巧是现在很多ajax application欠缺的.比如live mail,就缺少history的功能.

可见,其实两中产品都没有偏激的完全使用xmlhttprequest去服务器拿到净数据,之后使用javascript进行render的工作.其间肯定是有这样那样的原因,权衡之后才使用这样的替代方案.gmail尤其明显,一开始大家都以为gmail是一个完全的client side application,经过发现之后才发现,其实gmail是一个彻头彻尾的half blood web application,并没有极端的使用全xmlhttprequest 进行 client server communication.
其实,我们看到两种同类产品不同的技术选择,这种不同的选择不但表现出各家对技术的了解程度,同时渗透着对产品的理解.两种实现都非常wonderful,可是不是两种产品都很popular,因为用户只需要一个email address,因为用户固有一种用户习惯.live用传统的windows习惯拉拢着使用IE的用户,gmail在创新的概念与功能下,为用户建立一种自己的gmail使用习惯.最后究竟谁能胜出,可能真的很难预料,因为live.com还没有出现,同样google Web OS也还在酝酿之中….

一月 19, 2006

长时间的苦于对于开发一个javascript应用时,很难分离logic layer与presentation layer,因为html与操作html的javascript很难分离.
也看过一些framework,他们不是用id,就是用css class.受到启发,发现css 确实是一种标记的好办法,于是就开始写了这个东西.

web上面很多server side framework 是tag based,比如jsp,asp.net等,这个client side framework,采用html element的class作为标记的基础.模仿开发出一套client side的widgets(in asp.net also “control”)

具体的使用方法为:

1.完成页面的布局设计

2.使用特殊的CSS class 标记需要CSSWidget Engine process 的tag

caution:the tag need to be processed by engine must be the html tag, else the engine will ignore the tag
3.invoke the CSSWidget.Engine.parseChildNodes(document.body) , that the Engine will process the entire document body element

4.optional : if you want to get all reference that about CSS Widget in the document.body,you could do like below code:

var csswBody = new CSSW.Container(document.body);// csswBody.widgets is an array that contains all CSSWidgets object reference

the original html code:

<div class=”CSSW.Label” text=’test label’>div label</div>
<div class=”CSSW.Container” style=”BACKGROUND-COLOR: aqua”>
<div class=”CSSW.Label” text=’test label 2′>div label</div>
</div>
<div class=”CSSW.Repeater” dataJSON=”[{name:’digitalghost’,age:’20′,sex:’male’},{name:’yzx’,age:’21′,sex:’male’}]”>
<div class=”CSSW.Repeater.RenderContainer”>
</div>
<div class=”CSSW.Repeater.ItemTemplate”>
<div class=”CSSW.Label” text=”label:${name}”>test</div>
<a xhref=”/” mce_href=”/” >${name}</a>
<div>${age}</div>
<div>${sex}</div>
<hr>
</div>
</div>

after CSSWidget.Engine process:

<div class=”CSSW.Label” text=”test label”>test label</div>
<div class=”CSSW.Container” style=”background-color: aqua;”>
<div class=”CSSW.Label” text=”test label 2″>test label 2</div>

</div>
<div class=”CSSW.Repeater”
datajson=”[{name:’digitalghost’,age:’20′,sex:’male’},{name:’yzx’,age:’21′,sex:’male’}]”>
<div class=”CSSW.Repeater.RenderContainer”>
<div class=”CSSW.Label” text=”label:digitalghost”>label:digitalghost</div>
<a xhref=”/” mce_href=”/” >digitalghost</a>
<div>20</div>
<div>male</div>
<hr>
<div class=”CSSW.Label” text=”label:yzx”>label:yzx</div>
<a xhref=”/” mce_href=”/” >yzx</a>
<div>21</div>
<div>male</div>
<hr>
</div>
<div style=”display: none;” class=”CSSW.Repeater.ItemTemplate”>
<div class=”CSSW.Label” text=”label:${name}”>test</div>
<a xhref=”/” mce_href=”/” >${name}</a>
<div>${age}</div>
<div>${sex}</div>
<hr>
</div>
</div>

sample page: test.htm
framework source (the CSSWidget framework depend on prototype.js,template.js,logger.js):

prototype.js
template.js
logger.js
CSSWidget.js