为什么非要源代码?
思路:
1、每个树枝关心它的parent和item集合,找到层次关系
2、找你喜欢的方法来构建实体,如<li>,<div>,<table>都可以不过最好不要用table,它比较麻烦
3、使用js生成代码,这样可以保证你的树随时添枝加叶,当让也就能根据数据库变化了。
这是我的风格,最重要的是找到逻辑关系,逻辑关系定了,如很生成html代码就非常简单了。
思路:
1、每个树枝关心它的parent和item集合,找到层次关系
2、找你喜欢的方法来构建实体,如<li>,<div>,<table>都可以不过最好不要用table,它比较麻烦
3、使用js生成代码,这样可以保证你的树随时添枝加叶,当让也就能根据数据库变化了。
这是我的风格,最重要的是找到逻辑关系,逻辑关系定了,如很生成html代码就非常简单了。
<html>
<head>
<title>Left</title>
<link rel="stylesheet" href="css/css.css" type="text/css">
<style>
<!--
#foldheader{cursor:hand ;font-size: 10pt;
list-style-image:url(plus1.gif)}
#foldinglist{font-size: 10pt;list-style-image:url(min1.gif); margin-left: 11 px}
//-->
</style>
<script language="JavaScript1.2">
function change(){
if(!document.all)
return
if (event.srcElement.id=="foldheader") {
var srcIndex = event.srcElement.sourceIndex
var nested = document.all[srcIndex+1]
if (nested.style.display=="none") {
nested.style.display=''
event.srcElement.style.listStyleImage="url(min1.gif)"
}
else {
nested.style.display="none"
event.srcElement.style.listStyleImage="url(plus1.gif)"
}
}
}
document.onclick=change
//-->
</script>
</head>
<body bgcolor="#69e90a" text="#000000" leftmargin="30" topmargin="0">
<nobr>
<ul id="foldinglist">
<li id="foldheader">公共信息</li>
<ul id="foldinglist" style="display:none" >
<li><a href="send.jsp?groupid=100" target="_top">公共信息</a></li>
<li id="foldheader">kdk</li>
<ul id="foldinglist" style="display:none" >
<li><a href="send.jsp?groupid=101" target="_top">公共信息</a></li>
</ul>
</ul>
<li id="foldheader">商学院</li>
<ul id="foldinglist" style="display:none" >
<li><a href="send.jsp?groupid=100" target="_top">公共信息</a></li>
<li id="foldheader">kdk</li>
<ul id="foldinglist" style="display:none" >
<li><a href="send.jsp?groupid=101" target="_top">公共信息</a></li>
</ul>
</ul>
</ul>
</nobr>
</body>
</html>
------------------------------------------------
难道layer是先静态设计好,然后根据权限显示或隐藏?-----------------------------------------------
2.菜单有几层?是outlook风格的两层菜单式还是无穷的树型菜单?问题不描述清楚,急有什么用^_^
更改各个frame的宽度。
试试吧,很简单的。
根据数据库变化了。
级数不确定了,你有好办法吗?最好结构清楚,便于再利用。
---------------------------------------------------
to Muzhu(思考在DHTML) :
用frameset。
更改各个frame的宽度。
试试吧,很简单的。
---------------------
具体怎么做?
------------------
各位帮帮忙吧?
星期一交差呀。救命呀!
但是我不知道怎样用代码从数据库取回?
即怎样用JSP输出生成相应的菜单项,好象层之间的位置也很难定位呀(相对?绝对?)?
而且头儿要求用DIV。你能告诉我吗?谢谢了!
这个过程我一点也不会呀!
星期一交差呀!可怜可怜吧!
别人现成的代码不可能拿来就能用的,没有一模一样的需求啊,权限系统、数据库表结构也不一样,访问方式也不一样,怎么能抄呢?
今天晚上结帐!
今天晚上结帐!
下面是我写的一个程序,因为觉得比较好,值得借鉴,
所以放了上来,
如果转载,请注明出自(不死鸟 QQ33054474)
谢谢 < !-- #include virtual='Include/database.asp' -->
< %
set rs=Server.CreateObject("ADODB.RecordSet") sql="SELECT menu_name, menu_link, menu_bgcolor, menu_color,id FROM enter_individual WHERE (parent_id = (SELECT id FROM enter_individual WHERE menu_flag = 'root' )) " '查询得到根节点
rs.Open sql,conn,1,1
Response.Write "< table width=100% border=0 cellspacing=1 cellpadding=0 align=center>< tr bgcolor=#3399CC valign=bottom align=center>"
sumnum=rs.RecordCount
myArray=rs.GetRows()
rs.Close ()
widd=780/sumnum '从一级子菜单数目判断弹出菜单x坐标的递增像素
dim i
i=0
defaultbgcolor="#3399cc" '指定默认底色
defaultcolor="#ffffff" '指定默认字体颜色
defaultlink="#" '指定默认链接
posit_x=0 'x位置
flag=1 '标志,作为菜单弹出方向 1表示向右,0表示向左
'Response.Write myArray(4,6)
while i Response.Write "< td height=20 bgcolor="&myArray(2,i)&" width="&widd&">< a href="&myArray(1,i)&" onmouseover=java script:a"&myArray(4,i)&".style.display='block' onmouseout=java script:a"&myArray(4,i)&".style.display='none' >< font color="&myArray(3,i)&" >"&myArray(0,i)&"< /a>< /td>"
'----------------------------------------------- i=i+1
Wend
Response.Write "< /tr>< /table>" i=0
while i posit_y=100 'y位置回到原位
If i>=(sumnum/2) Then '如果菜单进入右半部分,则弹出转向
flag=0
End If '调用GetSubMenu 函数 设置该项一级菜单的下级菜单,以myArray(4,i) 即菜单id作为下级菜单所在div 的id GetSubMenu myArray(4,i),posit_x,posit_y
posit_x=posit_x+widd '下一个一级菜单的子菜单的 x坐标值增加一个单位
i=i+1 Wend '使用递规算法的到下级菜单的函数
'parent_id 父 id; posit_x 弹出层的左边位置; posit_y 弹出层的离上面位置; Function GetSubMenu(parent_id,posit_x,posit_y)
dim myArray
dim sumnum
dim i '查询子菜单的下级菜单
sql="SELECT menu_name, menu_link, menu_bgcolor, menu_color,id FROM enter_individual WHERE parent_id = "&parent_id&" AND user_id = '"&userid&"'"
rs.Open sql,conn,1,1 '如果下级菜单不存在,则层数减一 ,关闭数据库链接,建立一个以父id为div id的空层,然后返回
If rs.EOF=true Then
level=level-1
rs.Close ()
'Response.Write parent_id
Response.Write "< div id='a"&parent_id&"' style='position: absolute; top: 4; left: -1; display: none; width: 0; height: 0'>< /div>"
Else '如果存在取到数据库数据,并调用SetSubMenu显示菜单
sumnum=rs.RecordCount
myArray=rs.GetRows()
rs.Close ()
SetSubMenu myArray,sumnum,parent_id,posit_x,posit_y '对数据进行循环,递规调用GetSubMenu
i=0
while i< sumnum
posit_y=posit_y*1+20 '递规一次posit_y 加一个单位,
if level=0 Then '如果级数减到0 则回到1
level=1
End If
'If flag=1 Then
'GetSubMenu myArray(4,i),posit_x+level*widd,posit_y-level*20 '递规调用GetSubMenu x,y坐标延伸 level 个单位
'End If
If flag=0 Then
GetSubMenu myArray(4,i),posit_x-level*widd,posit_y-level*20 '递规调用GetSubMenu x,y坐标延伸 level 个单位
Else
GetSubMenu myArray(4,i),posit_x+level*widd,posit_y-level*20 '递规调用GetSubMenu x,y坐标延伸 level 个单位
End If i=i+1
Wend
End If End Function '设置子菜单函数
'myArray 菜单数据 ,sumnum 数组大小 ,parent_id 层的id ;
'posit_x 弹出层的左边位置; posit_y 弹出层的离上面位置; Function SetSubMenu (myArray,sumnum,parent_id,posit_x,posit_y)
dim i
parent_id="a"&parent_id '父菜单id前面加上a 作为层的id
hh=sumnum*20 '数组大小乘以20作为层的高度
Response.Write "< DIV onmouseover=java script:"&parent_id&".style.display='block' onmouseout=java script:"&parent_id&".style.display='none' ID='"&parent_id&"' STYLE='position: absolute; top:"&posit_y&"; left:"&posit_x&"; height:"&hh*1&"; width: "&widd&"; display:none;vertical-align: top'>< table width=100% border=0 cellspacing=1 cellpadding=0 >"
i=0
While i myArray(0,i)=Trim(myArray(0,i))
myArray(1,i)=Trim(myArray(1,i))
myArray(2,i)=Trim(myArray(2,i))
myArray(3,i)=Trim(myArray(3,i))
If myArray(2,i)="" Then
myArray(2,i)=defaultbgcolor
End If If myArray(3,i)="" Then
myArray(3,i)=defaultcolor
End If If myArray(1,i)="" Then
myArray(1,i)=defaultlink
End If
Response.Write "< tr align=center >< td width=100% height=20 bgcolor="&myArray(2,i)&" onmouseover=java script:"&parent_id&".style.display='block';a"&myArray(4,i)&".style.display='block' onmouseout=java script:a"&myArray(4,i)&".style.display='none'>< a href='"&myArray(1,i)&"'>< font color="&myArray(3,i)&" >"&myArray(0,i)&"< /font>< /a>< /td>< /tr>" i=i+1
Wend Response.Write " < /table> < /DIV>"
End Function Set rs=nothing
conn.Close ()
Set conn=nothing
% >
我请大家贴上代码的目的是想参考对比一下各种解决方法的优劣,以便选择。只是想参考参考如果大家都把自己的代码贴上来互相讨论并借鉴提高不是很好的事吗?等到代码烂在脑子里吧?
在前台写一个用xml数据岛绑定的菜单组件(可以用htc)
菜单的内容由xml数据决定
这个你可以写一个java类通过权限来生成这段xml数据
可以根据不同用户分别设置
这种方案是可行的,我现在使用的就是这种方案
效果很好
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> tree view </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style>
<!--
.header{cursor:hand ;font-size: 10pt;
list-style-image:url(plus1.gif)}
.list{font-size: 10pt;list-style-image:url(min1.gif); margin-left: 11 px;}
.yellowSmallCLF { font-size: 11px; color: #000000;}
.yellowSmallCLF a:link { color: #000000; text-decoration: none;}
.yellowSmallCLF a:visited { color: #000000; text-decoration: none;}
.yellowSmallCLF a:active { color: #000000; text-decoration: none;}
.yellowSmallCLF a:hover { color: #FF9900; text-decoration: underline;}
//-->
</style>
<SCRIPT LANGUAGE="JavaScript">
<!--
/*------------------------ Class... -----------------------------*/
function TTreeView(name){
this.name=name;
this.database='';//extent...
this.items=new Array();//TTreeNodes(this);
this.items[this.items.length]=new TTreeNode(this,'topNode','','Top TreeNode');//
this.items['topNode']=this.items[this.items.length-1];
//method...
this.create=create;
this.add=add;
this.trimData=trimData;
this.showChild=showChild;
}
function TTreeNode(owner,name,parent,caption,action,img){
this.owner=owner;
this.name=name;
this.parentName=parent;
this.childs=new Array();
this.caption=(!action?'':('<span class="yellowSmallCLF" ><a href="#" onclick="'+action+'">'))+caption+(!action?'':'</a></span>');
this.action=action;
this.img=img;
this.index=owner.items.length;
//method...
this.addChild=addChild;
}
/*------------------------ Methods... -----------------------------*/
function add(name,parent,caption,action,img){
this.items[this.items.length]=new TTreeNode(this,name,parent,caption,action,img);//
this.items[name]=this.items[this.items.length-1];
}
function create(){
this.trimData();
document.write(this.items[0].htmlcode);
}
function trimData(){
for(i=0;i<this.items.length;i++){
var obj=this.items[i]
var pn=obj.parentName;
if(pn!=''){
this.items[pn].childs[this.items[pn].childs.length]=obj;
obj.htmlcode='<li id="'+this.name+'_'+obj.name+'" class="header">'+obj.caption+'</li><ul class="list" id="'+this.name+'_'+obj.name+'_child" style="display:none"></ul>';
}else{
obj.htmlcode='<ul class="list">\n<li id="'+this.name+'_topNode" class="header">'+obj.caption+'</li><ul class="list" id="'+this.name+'_'+obj.name+'_child" style="display:none"></ul></ul>';
}
}
}
function showChild(name){
/* var str='';
for(i=0;i<this.items[name].childs.length;i++){
str+=this.items[name].childs[i].htmlcode;
}
document.all['node_'+name+'_child'].innerHTML=str;
alert(str)//document.all.node_topNode.innerHTML
return false;*/
}
function getNameByIdstr(idstr){
var beginnum=idstr.indexOf("_")+1;//异常处理!!!!!
var name=idstr.slice(beginnum);
return name;
}
function getOwnerByIdstr(idstr){
var beginnum=idstr.indexOf("_");//异常处理!!!!!
var name=idstr.substring(0,beginnum);
return name;
}
function changeIt(){
var idstr=window.event.srcElement.id;
var n=getNameByIdstr(idstr);
var str='';
if(document.all[idstr+'_child'].innerHTML==''){
var tree=eval(getOwnerByIdstr(idstr));
for(i=0;i<tree.items[n].childs.length;i++)str+=tree.items[n].childs[i].htmlcode;
if(tree.items[n].childs.length!=0){
document.all[idstr+'_child'].innerHTML=str;
document.all[idstr+'_child'].style.display="block";
}
document.all[idstr].style.listStyleImage="url(min1.gif)"
}else{
document.all[idstr+'_child'].innerHTML='';
document.all[idstr+'_child'].style.display="none";
document.all[idstr].style.listStyleImage="url(plus1.gif)"
}
}
function addNode(){//这里可以动态的添加一个Node到指定的node上,这只是个演示,你应该把它扩展,并且符合面向对象的原则。
var idstr=window.event.srcElement.id;
var pn=getNameByIdstr(idstr);
var tree=eval(getOwnerByIdstr(idstr));
var name=pn+tree.items[pn].childs.length;
var caption=prompt('请输入名字',name);
var action=prompt('请输入动作','alert(3)');
if(confirm('你确定要在这里添加一个Node')){
tree.add(name,pn,caption,action)//,img)
tree.items[name].htmlcode='<li id="'+tree.name+'_'+name+'" class="header">'+caption+'</li><ul class="list" id="'+tree.name+'_'+name+'_child" style="display:none"></ul>';
tree.items[pn].childs[tree.items[pn].childs.length]=tree.items[name];
}}
function myClick(){
try{//必须
changeIt();
}
catch(x){}
}
function myDblClick(){
try{//必须
addNode();
}
catch(x){}
}
document.onclick=myClick;
document.ondblclick=myDblClick
/*----------------- 废弃的方法-----------------*/
function del(name){
}
function addChild(){//用来动态填加node到name中,这里只给你一个粗糙的添加方法,
/*var name=this.name+this.owner.items[this.name].childs.length;
var caption=prompt('请输入名字',name);
var action=prompt('请输入动作','alert(3)');
this.owner.add(name,this.name,caption,action)//,img)
this.owner.trimData();*/
}
//-->
</SCRIPT>
</HEAD><BODY>
<SCRIPT LANGUAGE="JavaScript">
<!--
ot=new TTreeView('ot');
ot.add('class','topNode','class');
ot.add('H971','class','环化971班');
ot.add('llrock','H971','llrock');
ot.add('nickname','llrock','百乐宝','alert(30)');
ot.add('bbrock','H971','bbrock');
ot.add('H972','class','H972');
ot.create();
//ot.items[0].addChild()//-->
</SCRIPT>
<br><b>单击展开,双击在此节点添加一个子节点;我没有时间把它扩展的更全面,这只是个例子</b>
</BODY>
</HTML>
你的方法好像不太适合我的要求哟!
---------------------------------to stellaxyq(汐):
我对你的方案很兴趣,请问htc是菜单组件吗?哪里可以下载?怎么用。
你的方案可以给个示例代码吗?或者应该看来哪些相关文章?