TRSWCM65二次开发004树形组件.docx
- 文档编号:5466698
- 上传时间:2022-12-16
- 格式:DOCX
- 页数:24
- 大小:167.38KB
TRSWCM65二次开发004树形组件.docx
《TRSWCM65二次开发004树形组件.docx》由会员分享,可在线阅读,更多相关《TRSWCM65二次开发004树形组件.docx(24页珍藏版)》请在冰豆网上搜索。
TRSWCM65二次开发004树形组件
1树形组件
1.1概述
树形结构在普通的Web设计中不常用到,但是在一些B/S结构的系统(如OA系统)中是不可缺少的一种UI组件。
树状结构不仅是一种有效的信息组织方式,它同时建立了一种索引方式,帮助人类更快地在查找机器中的信息。
现代操作系统基本上都使用树状结构来管理磁盘文件,所以大多数人对树状菜单的逻辑模型和操作方式都非常熟悉,对于UI设计师来说就成了一种很好的选择。
1.2基本功能点
Ø有缩进的层次
Ø使用不同的图标区别出来树根、树枝、树叶
Ø图标可以标示出树枝是打开还是关闭
Ø每一个节点都有提示(ToolTip和状态栏)
Ø支持分隔符
1.3扩展功能点
Ø支持全展开和全关闭
Ø支持定位到指定节点
Ø支持动态载入指定树枝的节点
Ø不预先加载树中所有节点,只是在点击的时候自动加载,对于大数据量的树形结构特别有效;
Ø支持拖动
Ø支持给LI上填写扩展属性
Ø支持选择框
2关键技术
设计原则:
按照WEB标准建议,HTML代码只是表达内容的结构,由样式表和JavaScript结合控制表现。
wcm系统中树形组件定义在文件app\js\source\wcmlib\com.trs.tree\TreeNav.js。
这个JS文件里定义了树形组件的对象com.trs.tree.TreeNav的属性、方法和事件。
2.1HTML表达式
采用UL和DIV元素标示:
DIV表示单个节点;UL表示一组平级的节点,其中DIV中的A元素上定义Title属性。
2.2CSS的作用
Ø定义不同类型节点的图标(树根、树枝、树叶、分隔符);
Ø定义各种状态的标示(展开、关闭、鼠标移上、鼠标一种、选中);
Ø控制节点是否展开;
2.3不同类型节点的样式如何定义
按照设计原则,HTML内容只是复杂表达数据的结构,表现由样式+JavaScript来控制.所以在UL和DIV中是不包含任何样式,由JavaScript读取DOM树,动态设置样式。
2.4支持动态装载
动态载入的原理:
通过定义一个空的UL元素,让树形组件向JSP发出一个XMLHttp请求,获取到内容,填充UL。
其中JSP地址由覆写的树形组件函数决定。
例如,在wcm\app\nav_tree\nav_tree_select.jsp页面中调用该方法来重写原来的动态载入功能。
代码如下:
//重写com.trs.tree.TreeNav的动态载入方法
com.trs.tree.TreeNav.makeGetChildrenHTMLAction=function(_elElementLi){
…
//获取父节点的类型
varsParentType=_elElementLi.id.substring(0,nPos);
//获取父节点的id
varsParentId=_elElementLi.id.substring(nPos+1);
//返回tree_html_creator.jsp请求页面的结果,返回的结果为子节点的代码
return"tree_html_creator.jsp"+(location.search||'?
1=1')+"&Type=0&FromSelect=1&ParentType="+sParentType+"&ParentId="+sParentId;
}
由上可知动态载入主要是从请求tree_html_creator.jsp页面的返回值中获取子节点的代码。
tree_html_creator.jsp中各参数如下:
参数名
取值范围
描述
Type
0,1,2
参数值0:
表示输出当前节点的一级子节点,调用方法TreeCreator.writeTopChildrenHTML()
参数值1:
表示输出当前节点路径的HTML,调用方法TreeCreator.writeHTMLOfAPath()
参数值2:
表示产生包含指定栏目的HTML,调用方法TreeCreator.writeHTMLContainsChannels()
FromSelect
0或1
控制点击节点文字是否可以定位到节点前的选择框
ParentType
字符串
父节点的类型
ParentId
整型值
父节点的ID
2.5刷新树
在树组件中有两种刷新树的方法updateNodeChildrenHTML和reloadChildren。
这两个方法都可以只传入一个父节点或者父节点的ID来动态刷新该节点的所有子节点。
函数中各参数的意义见附录8.2的表。
以下举例说明:
1.需求:
点击树节点的时候触发刷新子节点的操作;
2.实现如下:
//树节点的点击事件
TreeNav.doActionOnClickA=function(event,oSrcElement){
//由于点击事件是发生在A元素上,我们需要找到该节点对应的DIV
//元素,该元素上记录了节点类型、ID等信息
varsrcElementDiv=oSrcElement.parentNode;
//更新子节点,将DIV元素传递给刷新函数
//TreeNav.reloadChildren(srcElementDiv)
TreeNav.updateNodeChildrenHTML(srcElementDiv);
}
2.6对节点事件的处理
有时我们想要在点击树节点时触发一些事件,这个事件的处理主要就包含在com.trs.tree.TreeNav.onClickNode函数中。
首先我们分析下默认的onClickNode函数是如何处理事件的,其代码如下:
onClickNode:
function(_event){
varevent=window.event||_event;
//获取点击的元素
varoSrcElement=Event.element(event);
varsOnclick=null;
//获取该元素上的onclick属性
if((sOnclick=oSrcElement.getAttribute('onclick',2))!
=null&&(sOnclick!
='')){
try{
//执行该元素上定义的onclick函数,然后返回
eval(sOnclick);
returnfalse;
}catch(err){
//justskipover
}
}
//获取点击的元素标签名
switch(oSrcElement.tagName){
//如果为div,即树节点上的图标
case"DIV":
//调用默认的_onClickFolder函数,默认为展开或收缩节点
com.trs.tree.TreeNav._onClickFolder(oSrcElement);
break;
//如果为a元素,即树节点上的文字
case"A":
//如果oPreSrcElementA元素不为空,即之前点击过其它节点
if(com.trs.tree.TreeNav.oPreSrcElementA!
=null){
//将之前节点的设置成不选中状态
Element.removeClassName(com.trs.tree.TreeNav.oPreSrcElementA,"Selected");
}
//将当前节点设置成选中状态
Element.addClassName(oSrcElement,"Selected");
//将之前的节点设置成倒数第二个元素
com.trs.tree.TreeNav.lastSecondSrcElementA=com.trs.tree.TreeNav.oPreSrcElementA;//modifiedbyhxj
//将当前节点设置成现在的元素
com.trs.tree.TreeNav.oPreSrcElementA=oSrcElement;
//执行doActionOnClickA函数
varbReturn=com.trs.tree.TreeNav.doActionOnClickA(event,oSrcElement);
if(bReturn==false)returnfalse;
break;
default:
break;
}
returntrue;
}
由上述代码中的注释分析可知,若想触发指定的事件有如下方法:
在节点上添加onclick属性;在onClickNode函数中执行需要的操作;在_onClickFolder和doActionOnClickA方法中添加需要的操作。
若只添加onclick属性,树节点并不会执行树的展开和收缩动作,因此一般不采用第一种方法。
下面我们将举个例子来说明,由于我们需要使用a元素,因此生成的子节点中不能包含有label元素。
我们修改动态生成子节点函数中传递给tree_html_creator.jsp页面的参数,如下所示,将FromSelect设置为0,则生成的子节点中不包含label元素(若想保留label元素,可将onClickNode函数中的case‘A’设置成case‘label’):
首先我们在app/_test目录下创建一个文件tree_test.html
引入相关的JS及CSS文件
在HTML页面中我们定义初始节点
100%;height: 100%;border: 0;">
重写动态载入子节点的方法
//重写com.trs.tree.TreeNav的动态载入方法
com.trs.tree.TreeNav.makeGetChildrenHTMLAction=function(_elElementLi){
varnPos=_elElementLi.id.indexOf("_");
//获取父节点的类型
varsParentType=_elElementLi.id.substring(0,nPos);
//获取父节点的id
varsParentId=_elElementLi.id.substring(nPos+1);
//返回tree_html_creator.jsp请求页面的结果,返回的结果为子节点的代码
return"../nav_tree/tree_html_creator.jsp"+(location.search||'?
1=1')+"&Type=0&FromSelect=0&ParentType="+sParentType+"&ParentId="+sParentId;
}
我们采用修改doActionOnClickA方法来实现点击节点后弹出节点名字的事件。
在页面中我们重写com.trs.tree.TreeNav.doActionOnClickA函数,代码如下:
com.trs.tree.TreeNav.doActionOnClickA=function(event,oSrcElement){
varsrcElementDiv=oSrcElement.parentNode;
com.trs.tree.TreeNav.updateNodeChildrenHTML(srcElementDiv);
alert(oSrcElement.innerHTML);
}
效果如下图所示:
2.7默认展开到指定的节点
有时我们需要在树初始化时就展开到指定的相关的节点。
这功能主要是在updateNodeChildrenHTML函数中实现。
如下所示:
//树载入完成后执行的操作expendTree
TreeNav.observe("onload",expendTree);
functionexpendTree(){
//通过updateNodeChildrenHTML函数更新在站点类型节点ID为r_0,展开到栏目ID
//为10的栏目
TreeNav.updateNodeChildrenHTML("r_0",makeURLofGetHTMLContainsChannelIds("10"))
}
functionmakeURLofGetHTMLContainsChannelIds(_sNodePath){
//给页面tree_html_creator.html传递参数,将Type设置成2,同时传入
//channelIds参数,表示获取到channelIds的树结构
varsAction="../nav_tree/tree_html_creator.jsp"+(location.search||'?
1=1')+"&Type=2&FromSelect=1&ChannelIds="+_sNodePath;
returnsAction;
}
其中主要是从tree_html_creator.jsp页面中返回默认展开的树结构。
我们将参数Type设置成2,并传入需要展开的栏目ID信息ChannelIds该页面就会将构造好的HTML代码返回。
这样树就已经展开到目标栏目了。
不过这个展开的树默认是从站点类型开始展开的,如果我们不想从站点类型开始展开,想从当前的根节点展开到某个栏目,该怎么办呢?
分析tree_html_creator.jsp页面我们会发现,在该页面中可以调用另一个方法:
writeHTMLOfAPath()。
该方法功能是按照一个节点路径依次展开。
因此我们只需要获取到当前根节点到目标栏目父节点的路径即可(注:
路径的获取可以通过jsp来实现,不里详细描述。
路径中应该包含该对象的类型信息,例如s_1,c_10,c_41表示为一个路径,表示站点ID为1的站点展开到栏目ID为10的栏目,再到栏目ID为41的栏目)。
获取到路径后,我今天将这个路径信息以参数NodeIds传递给tree_html_creator.jsp页面,如下图所示:
//树载入完成后执行的操作expendTree
functionexpendTree(){
//这里需要构造路径信息,可以通过jsp不断找父节点的方法来获取
//varpath=getPath(rootType,rootId,channelId)获取从需要展开的channelId到parentId的路径,在该路径中如果是站点就构造成s_加站点ID的形式,如果是站点类型就构造成r_加类型ID的形式,如果是栏目就构造成c_加栏目ID的形式。
varpath='s_1,c_10,c_41';
//这里的path表示从站点ID为1开始,展开到栏目ID为10的子栏目中,会显示ID为10的栏目的子栏目。
TreeNav.updateNodeChildrenHTML("s_1",makeURLofGetChildrenHTML2(path));
}
functionmakeURLofGetChildrenHTML2(_sNodePath){
varsAction="../nav_tree/tree_html_creator.jsp"+(location.search||'?
1=1')+"&Type=1&FromSelect=0&NodeIds="+_sNodePath;
returnsAction;
}
这样就可以获取到从指定的根节点到目标栏目的展开树了
2.8如何选中某个节点
WCM的树中每个节点都会有一个ID。
这个ID的构造规则如下,假设该节点对应对象在数据库的唯一标识id=1:
如果是站点类型:
树节点ID=‘r_1’;
如果是站点:
树节点ID=’s_1’;
如果是栏目:
树节点ID=’c_1’;
从上可知,节点的ID即为该节点类型的对应的前缀与其数据库id的组合。
我们要选中某个节点可以通过如下步骤:
1.获取该节点对应对象的id
2.构造该节点的ID(直接从HTML代码中获取也可以)
3.让树结构展开到对应的节点(见前一节:
展开到指定的节点)
4.调用js语句:
com.trs.tree.TreeNav.focus(ID),将节点以字符串的形式传递给该方法即可
示例:
//假设需要选中栏目id=10的栏目
//1.获取id
varid=10;
//2.构造节点ID
varID='c_10';
//3.让树展开到该节点
...
//4.选中该树
com.trs.tree.TreeNav.focus(ID);
3怎么控制树节点样式
一个树节点的的表现主要有图片,打开和收缩状态。
这些状态是如何控制的呢?
首先,我们需要了解节点的class属性是如何构造的。
WCM系统中的树节点class属性由两部分组成:
前缀和后缀。
前缀一般用来控制节点上显示的图片,而后缀则用来控制是显示打开状态还是收缩状态。
在每个节点中都会有一个classPre属性,该属性是用来构造节点class属性前缀用的。
使用这个属性可以控制这个节点需要显示的图片,就像WCM系统中站点类型、站点、栏目节点的显示图片是不一样的,因为他们classPre不同。
在展开的树节点前面会出现
,而在收缩的节点上会显示
图片,这些状态标识图片都是通过class的后缀来控制的。
节点后缀主要有两种Folder和FolderOpened。
综上所述,我们生成后的树节点class属性为XXXFolder和XXXFolderOpened这两种,它们分别对应于收缩和关闭状态。
其中XXX为节点的classPre属性,所以只要控制这两个class值就可以随心所欲地设置自己的树样式和图标了。
4实战示例-构造指定站点类型开始的树
4.1需求
在页面中生成一个多选类型的树结构,根节点为“文字库“,点击该根节点可以显示出该节点下的站点。
当树载入时自动展开到栏目ID为10的那一级栏目。
4.2引入相关文件
以上引入的为树的样式文件,控制树的图标等显示效果。
以下为引入的js文件。
4.3指定页面元素
若想在指定的位置上显示树结构,需要在该位置上放置元素并将class属性设置成TreeView如class=”TreeView”,com.trs.tree.TreeNav在初始化时会自动寻找该到元素。
在HTML页面元素中我们还需要一个空的
- 元素,用来存放动态加载的内容。
如下所示,id=”r_0”,其中r表示该节点为站点类型,数字0表示站点类型的编号。
classPre为设置该节点的class属性前缀,用来控制显示的图标。
(注意:
不要在
- 元素上下位置加注释等信息,这有可能导致树结构不可用)。
--使用UL+class定义树结构开始-->
--节点元素HTML代码-->
1">
--使用UL+class定义树结构结束-->
4.4定义树结构对象和属性
在生成树时首先需要定义一个com.trs.tree.TreeNav类型对象,如下所示:
//定义com.trs.tree.TreeNav对象
varTreeNav=com.trs.tree.TreeNav;
4.5重写动态载入方法
动态载入子结点可以通过com.trs.tree.TreeNav.makeGetChildrenHTMLAction()来控制。
代码如