单纯从webim的ui层次(即layout)来看,整个webim是被一层一层的div“包裹起来”的。根据我们平常由表及里,由外到内地学习习惯,我们可以从最外层的div开始,进行一次“ui穿梭”。在这里,我只介绍我关心的并且也是重要的部分。
webim最外层皮是一个id为webim的div,里面主要有:layout,这个是构成了webim的主要轮廓。:layout下最重要的部分::shortcut和
:panels,apps
shortcut相对简单,就包括工具栏和各个快捷方式按钮。
在panesl中,包括了聊天窗口和聊天表情等,当然,这些窗口都是动态添加到panels中的,另外panels还包括展开和收缩工具条按钮。panels位于快捷方式和webim程序ui之间。
apps是webim最重要部分,包括聊天人员列表,热帖,通知和设置。
以上说的三个div和最外层的webim都定义在ui.layout.js中。现在剖析一下我最关心的apps部分,这一部分在ui.layout.js中的定义非常简单:
<div id=":apps" class="webim-apps"></div>
如上所示,apps在初始的静态html中只有简单的一个div定义,所有的app都是通过动态添加的。
接下来,我们来分析app是如何添加到apps的div的。这个是非常关键的地方。
为了能更清楚更简单的了解这一原理,我们以hotpost为例来说明单个app是如何创建并添加到apps中的,当然这里只讨论ui的添加,对于事件处理,我们以后再解决。
首
先,我们来看看custom.js.php文件,这个文件可以简单地理解为整个webim的“主函数”入口,就如c语言程序中不可少的main函数一样。
在custom.js.php中,webimUI将通过new被创建,webimUI在创建时就会调用自身的_init函数,hotpost就是在这个方
法里被创建的:
self.hostpost = new webimUI.hotpost();
在这里我们可以看到hotpost是做为webimUI的属性被创建的,这归功于widget函数。
来看widget函数(在ui.js中定义),widget(name,defaults,prototype)
widget函数主要包括这么两个部分:
- 内部函数 m的定义
- 将m函数赋值给webimUI对象的hotpost属性
在函数m中,有一些要注意的:
- 函数对参数中的prototype定义的以下函数进行了调用:
- 函数中还包括对hotpost属性的赋值操作,hotpost的className属性将以"webim-"为前缀,加上name参数
- hotpost还会有一个id值,由_widgetId全局变量自增1构成
- 另外,prototype对象中还有_li_tpl(data),_fitUI(),add()方法
- 在m函数中还有对tpl(),_initEvents(),mapElement(element)的调用,
关于m的具体细节,还会在后面接着来讲,
我们这里只是想知道hotpost通过widget函数“注册”到webimUI的。很简单,通过以下方法:
webimUI[name]=m;
这样,在webimUI的_init()中就可以这样创建hotpost对象:
self.hotpost = new webimUI.hotpost();
接着,ui中最重要的部分来了,当然,这也是目前为止比较复杂的,现在需要调用layout对象的addApp函数将hotpost的ui(即html代码)添加到layout中。
layout.addApp(self.hotpost, {
title: i18n("hotpost"),
icon: "hotpost",
sticky: false,
onlyIcon: true,
isMinimize: true
});
每个app的html都是包裹在window对象中的。我们先来了解一下window对象。
在addApp中可以看到这个操作:
win = new webimUI.window(null,options);
这里的window就是一个窗口对象了,app一般都有各自相应的window。window对象提供了html方法,通过此方法就可以将hotpost的html代码添加进window中,接下来,就是将包裹了hotpost的window添加到apps容器中了,
self.$[container ? container : "apps"].insertBefore(win.element, before && self.apps[before] ?self.apps[before].window.element : null);
接着,将window对象交给hotpost管理
app.window = win;
最后是绑定displayStatusChange事件并给apps添加hotpost
self.apps[app.name] = app;
在webimUI的初始化函数最后会调用_initEvents()函数,该函数会将事件绑定到im组件中。