to xuzuning(唠叨) 老大的函数的确不错,对于顶级2-高级3这一分支,应当是点击顶级2可以打开高级3,4,点高级3,4可以展开其叶。然后点各自节点可以收拢其下的所有分支。 你所说的加入层次标志我还没有想到,所以没有提出,惭愧,如果要加,应当是如何来加,是否对每个数组都要加上这一标志。 另外要保存结构似乎办法也有很多,1是全展开之后用js隐显,2是逐个展开用session或是文件来存,3是用get或session来获取参数列表,我现在用的是最后的一种,不知道有无更好的办法。
to pwtitle(doodoo) 呵呵,js的树形菜单实在是太多了。我这里要的是不用js的,谢谢帮助。
建议使用
http://www.posi.de的class.tree比你做的好的多,而且要比csdn的好看,呵呵
其实如果用js的话是很容易实现的,只要控制一下表格的显隐即可,这里要求用php来实现是为了彻底的隐藏不想显示东西,我已解决了在二维上的树形展开,不过用的办法不是递归,用递归的实现可能有点难,因为没有明确的父子关系在里面,而且这是维数上的深入,并不是可以无限分下去的,bluemeteor(挂月||╭∩╮(︶_︶)╭∩╮)提出的用session来存放节点列表的办法还没有试过,可以一试。
请教一下唠叨,如果要实现的话还需要哪些条件?你所说的指示分支的方案是否是指标识该节点的方案呢?
我现在是用get两个参数的办法来解决的,一个是action它的open和close用来打开和关闭树,另一个是expand它的值用来指向所开节点,不知道还有无更好的办法。
其实要实现这个问题的主要目的是要解决在服务器端实现权限树,即有相应的权限才能看到相应的树,我很笨,还请大家指点。
$item1 = array( array('name' => 'A', 'url' => 'action.php?action=a'),array('name' => 'B', 'url' => 'action.php?action=b'));
$item2 = array( array('name' => 'C', 'url' => 'action.php?action=c'),array('name' => 'D', 'url' => 'action.php?action=d'));
$item3 = array( array('name' => 'E', 'url' => 'action.php?action=e'),array('name' => 'F', 'url' => 'action.php?action=r'));
$item4 = array( array('name' => 'G', 'url' => 'action.php?action=g'),array('name' => 'H', 'url' => 'action.php?action=h'));$menu1 = array( array('title' => '高级1', 'item' => $item1),array('title' => '高级2','item' => $item2));
$menu2 = array( array('title' => '高级3', 'item' => $item3),array('title' => '高级4','item' => $item4));$pmenu = array(array('class'=>'顶级1','menu'=>$menu1),array('class'=>'顶级2','menu'=>$menu2));
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>无标题文档</title>
<script language="JavaScript">
<!--
function clickmenu(thisid){
obj=eval(thisid);
if(obj.style.display=="")
obj.style.display='none';
else
obj.style.display='';
}
//-->
</script>
</head><body>
<?php
while(list($key,$class)=each($pmenu)){
?>
<table width="150" border="1" cellspacing="0" bordercolor="#0066FF">
<tr>
<td onclick="clickmenu('<?php echo "menu".$key;?>')"><?php echo $class["class"]; ?></td>
</tr>
<tr>
<td>
<div id="<?php echo "menu".$key;?>" style="display:none">
<?php
while(list($key1,$title)=each($class["menu"])){
?><table width="150" border="1" cellspacing="0" bordercolor="#0066FF">
<tr>
<td onclick="clickmenu('<?php echo "menu".$key."item".$key1;?>')"><?php echo $title["title"]; ?></td>
</tr>
<tr>
<td>
<div id="<?php echo "menu".$key."item".$key1;?>" style="display:none"><table width="150" border="1" cellspacing="0" bordercolor="#0066FF">
<?php
while(list($key2,$name)=each($title["item"])){
?>
<tr>
<td><?php echo $name["name"]; ?></td>
</tr>
<?php
}
?>
</table></div>
</td>
</tr>
</table>
<?php
}
?></div>
</td>
</tr>
</table>
<?php
}
?>
</body>
</html>
<pre>
<?php
$item1 = array( array('name' => 'A', 'url' => 'action.php?action=a'),array('name' => 'B', 'url' => 'action.php?action=b'));
$item2 = array( array('name' => 'C', 'url' => 'action.php?action=c'),array('name' => 'D', 'url' => 'action.php?action=d'));
$item3 = array( array('name' => 'E', 'url' => 'action.php?action=e'),array('name' => 'F', 'url' => 'action.php?action=r'));
$item4 = array( array('name' => 'G', 'url' => 'action.php?action=g'),array('name' => 'H', 'url' => 'action.php?action=h'));$menu1 = array( array('title' => '高级1', 'item' => $item1),array('title' => '高级2','item' => $item2));
$menu2 = array( array('title' => '高级3', 'item' => $item3),array('title' => '高级4','item' => $item4));$pmenu = array(array('class'=>'顶级1','menu'=>$menu1),array('class'=>'顶级2','menu'=>$menu2));function tree($menu,$open="",$deep=0) {
foreach($menu as $k=>$v) {
if(isset($v['class'])) { //顶级
echo $v['class']."\n";
if(empty($open)) tree($v['menu'],$open,$deep+1);
}
if(isset($v['title'])) { //高级
echo str_repeat("\t",$deep).$v['title']."\n";
if(empty($open)) tree($v['item'],$open,$deep+1);
}
if(isset($v['name'])) { //叶
echo str_repeat("\t",$deep).$v['name']."[".$v['url']."]\n";
}
}
}tree($pmenu);
?>
参数
$deep 表示树的深度
$open 表示是否展开 函数中暂以空表示全部展开如果现在不想展开“顶级2-高级3”的叶节点,你计划如何表述这个条件呢?
表述不同算法也不竟相同
表面上看,可以用节点文字链作为识别标志,但有可能出现不唯一的情况
若在的层次上加入标志所属层次的元素倒是一种解决方案,但你没有提出
所以我说“条件不足”
完全实现你的要求,要的话发信到[email protected]
老大的函数的确不错,对于顶级2-高级3这一分支,应当是点击顶级2可以打开高级3,4,点高级3,4可以展开其叶。然后点各自节点可以收拢其下的所有分支。
你所说的加入层次标志我还没有想到,所以没有提出,惭愧,如果要加,应当是如何来加,是否对每个数组都要加上这一标志。
另外要保存结构似乎办法也有很多,1是全展开之后用js隐显,2是逐个展开用session或是文件来存,3是用get或session来获取参数列表,我现在用的是最后的一种,不知道有无更好的办法。
呵呵,js的树形菜单实在是太多了。我这里要的是不用js的,谢谢帮助。
<pre>
<?php
$item1 = array( array('text' => 'A', 'url' => 'action.php?action=a'),array('text' => 'B', 'url' => 'action.php?action=b'));
$item2 = array( array('text' => 'C', 'url' => 'action.php?action=c'),array('text' => 'D', 'url' => 'action.php?action=d'));
$item3 = array( array('text' => 'E', 'url' => 'action.php?action=e'),array('text' => 'F', 'url' => 'action.php?action=r'));
$item4 = array( array('text' => 'G', 'url' => 'action.php?action=g'),array('text' => 'H', 'url' => 'action.php?action=h'));$menu1 = array( array('text' => '高级1', 'item' => $item1),array('text' => '高级2','item' => $item2));
$menu2 = array( array('text' => '高级3', 'item' => $item3),array('text' => '高级4','item' => $item4));$pmenu = array(array('text'=>'顶级1','item'=>$menu1),array('text'=>'顶级2','item'=>$menu2));function tree($menu,$open="",$deep=0) {
foreach($menu as $k=>$v) {
if(isset($v['text'])) {
echo str_repeat("\t",$deep).$v['text'];
if(isset($v['url'])) echo "[".$v['url']."]";
echo "\n";
if(is_array($v['item']))
if(empty($open)) tree($v['item'],$open,$deep+1);
else
if(in_array($open,$point)) tree($v['item'],$open,$deep+1);
}
}
}tree($pmenu);
?>
你用纯php生成不闲效率低吗?每次点hit都要重新生成页面。不划算啊。
不到不得已我也不会这么干,只是js不太好设置权限,所以才想在服务器端来直接实现权限控制,当然我可能会用php生成对应的权限树之后再用js来控制显隐。不仅仅js可以控制表格的显隐,php也是可以做到的,谢谢你的提醒!:)
session_start();
?>
<pre>
方案一
php版本4.3.2
设由session保存节点状态信息
初态:仅显示“顶级”节点
<?php
$item1 = array( array('text' => 'A', 'url' => 'action.php?action=a'),array('text' => 'B', 'url' => 'action.php?action=b'));
$item2 = array( array('text' => 'C', 'url' => 'action.php?action=c'),array('text' => 'D', 'url' => 'action.php?action=d'));
$item3 = array( array('text' => 'E', 'url' => 'action.php?action=e'),array('text' => 'F', 'url' => 'action.php?action=r'));
$item4 = array( array('text' => 'G', 'url' => 'action.php?action=g'),array('text' => 'H', 'url' => 'action.php?action=h'));$menu1 = array( array('text' => '高级1', 'item' => $item1),array('text' => '高级2','item' => $item2));
$menu2 = array( array('text' => '高级3', 'item' => $item3),array('text' => '高级4','item' => $item4));$pmenu = array(array('text'=>'顶级1','item'=>$menu1),array('text'=>'顶级2','item'=>$menu2));function tree($menu,$point=-1,$deep=0) {
//构造状态信息
static $info;
static $num;
if($deep == 0) {
$info = array();
$num = 0;
}
foreach($menu as $k=>$v) {
$tmp = $v;
unset($tmp['item']);
$info[] = array(item=>$tmp,deep=>$deep,child=>(is_array($v['item'])?count($v['item']):0));
if(is_array($v['item']))
tree($v['item'],"",$deep+1);
}
if($deep != 0) return; //至此已将数状的结构平面化了
//print_r($info); // 查看平面化结果
if(! isset($_SESSION['menu_info'])) { // 如果尚未定义菜单状态信息
$menu_info = str_repeat("0",count($info));
$_SESSION['menu_info'] = $menu_info;
}else $menu_info = $_SESSION['menu_info'];
echo "$menu_info\n"; //查看菜单状态信息 //调整菜单状态
if($point >= 0) {
$ch = $menu_info[$point]; //取得指定的节点的状态
$menu_info[$point] = $ch = $ch=="1"?"0":"1"; //置反节点状态 $deep = $info[$point]['deep']; //取得当前的深度
for($i=$point+1;$info[$i]['deep']>$deep;$i++) { //向深度方向
$menu_info[$i] = "0"; //不管三七二十一,先关了再说
}
if($ch == "1") { //如果不是关闭
for($i=$point+1;$info[$i]['deep']>$deep;$i++) { //向深度方向
if($info[$i]['deep'] == $deep+1) {
$menu_info[$i] = "1";
}
}
}
$_SESSION['menu_info'] = $menu_info; //保存修改
}
echo "$menu_info\n"; //再次查看菜单状态信息
//显示菜单
for($i=0;$i<strlen($menu_info);$i++)
if($menu_info[$i] == "1" || $info[$i]['deep'] == 0) {
echo str_repeat("\t",$info[$i]['deep']).$info[$i]['item']['text'];
if(isset($info[$i]['item']['url']))
echo "[".$info[$i]['item']['url']."]";
else echo "($i)";
echo "\n";
}
}tree($pmenu);
tree($pmenu,0); //展开第一分支
?>
不过这样写要被 mikespook(Mike大懒猫) 指责“不遵守软件工程的规范”了至于如何传递和接收参数就有你决定了
php版本4.3.2
设由session保存节点状态信息
初态:仅显示“顶级”节点
11001000000000
11001000000000
顶级1(0)
高级1(1)
高级2(4)
顶级2(7)
11001000000000
00000000000000
顶级1(0)
顶级2(7)这是我运行后的效果,是这样吗?