<? class Tree { var $data = array(); var $tpl = '<table cellpadding=0 cellspacing=0 border=0 style="font-size:9pt">$块</table>'; var $block = '<tr onClick="tree_onclick()" bs=$标识><td background="$连线">$主图标</td><td>$副图标 $文字</td></tr><tr style="display:$可见"><td background="$连线"></td><td value="$编号">$子树</td></tr>'; var $images = array( // 节点图片 array("images/tree_L.gif","images/tree_T.gif","images/icon-page.gif"), array("images/OpenFolder_L.gif","images/OpenFolder_T.gif","images/FolderClose.gif","images/FolderOpen.gif"), array("images/CloseFolder_L.gif","images/CloseFolder_T.gif","images/FolderClose.gif","images/FolderOpen.gif"), array("none","images/tree_I.gif"), ); var $bond = array("","数据加载中..."); var $all = false; // 是否产生一棵子树 /** * Tree 构造函数 */ function Tree() { } /** * table 方法 * 功能 产生以表格方式组织的数据 * 说明 主要用于调试 */ function table($format="",$head="") { if(count($this->data) <= 0) return $this->out = ""; $out = "<table $format><tr>"; if($head == "") { foreach($this->data as $v) break; $head = array_keys($v); } foreach($head as $v) $out .= "<th>$v</th>"; $out .= "</tr>"; foreach($this->data as $value) { $out .= "<tr>"; foreach($head as $k) $out .= "<td>$value[$k]</td>"; $out .= "</tr>"; } return $this->out = "$out</table>"; } /** * node_all 方法 * 功能 根据模板构造全部数据 */ function node_all($id, $key=array("id","pid","text","link")) { $this->all = true; return $this->node($id,$key); } /** * index 方法 * 功能 索引树 */ function index($start=0, $key=array("id","pid")) { $fun = create_function('$a,$b' ,"if($a[$key[1]] == $b[$key[1]]) return 0;" ."return $a[$key[1]] > $b[$key[1]]?1:-1;"); $out = array(); foreach($this->data as $k=>$v) { if($v[$key[1]] == $start) $out[] = $v; else $this->insert($v,&$out,$key); } return $this->data = $out; } /** * insert 方法 * 功能 插入节点 */ function insert($value,$array="",$key=array("id","pid")) { if($array == "") $array =& $this->data; if(count($array) <= 0) { $array[] = $value; return true; } $k = $m = $n = 0; $ar = array(); foreach($array as $t) { $k++; if($t[$key[0]] == $value[$key[1]]) $m = $k; if($t[$key[1]] == $value[$key[1]] || in_array($t[$key[1]],$ar)) { $n = $k; $ar[] = $t[$key[0]]; } } $k = max($m,$n); if($k == 0) return false; $array = array_merge(array_slice($array,0,$k),array($value),array_slice($array,$k)); return true; } /** * update 方法 * 功能 修改节点 */ function update() { } /** * delete 方法 * 功能 删除节点 */ function delete() { } /** * move 方法 * 功能 移动节点 */ function move() { } /** * display 方法 * 功能 显示 */ function display($type="node_all",$key=array("id","pid","text","link")) { switch($type) { case "table": $this->table(); break; case "node_all": $this->out = $this->node_all(0,$key); break; } echo $this->out; $this->javascript(); } function javascript() { static $key; if(! empty($key)) return; echo <<<JS <script> function tree_onclick() { el = event.srcElement; switch(event.srcElement.tagName) { case "A": case "IMG": while(el.tagName != "TR") el = el.parentElement; break; default: return; } if(el.bs == 0) return; // bs=0 表示是叶节点; =1 为L接; >1 为T接 var pos = el.rowIndex; var el1 = el.parentElement.rows[pos+1]; if(el1.style.display == "block") { el1.style.display = "none"; el.cells[0].children[0].src = (el.bs==1?images[0][0]:images[0][1]); if(el.cells[1].children[0]) el.cells[1].children[0].src = images[1][2]; }else { el1.style.display = "block"; el.cells[0].children[0].src = (el.bs==1?images[1][0]:images[1][1]); if(el.cells[1].children[0]) el.cells[1].children[0].src = images[1][3]; } el = el1.cells[1]; if(el.innerHTML == bond) Tree_load.src = "?node="+el.value; } myload = 0; function tree_load_end() { if(myload != 0) el.innerHTML = myload; } </script> <script id='Tree_load' src=' onreadystatechange='tree_load_end()'></script> JS; $js = "<script>n"; $js .= "images = new Array(nnew Array("; foreach($this->images[1] as $v) $js .= "'$v',"; $js = substr($js,0,-1)."),n"; $js .= "new Array("; foreach($this->images[2] as $v) $js .= "'$v',"; $js = substr($js,0,-1).")n);n"; $js .= "bond = '{$this->bond[1]}';"; $js .= "</script>"; echo $js; $key = 1; } function find($id,$key=array("id","pid")) { foreach($this->data as $v) if($v[$key[1]] == $id) return true; return false; } /** * filter方法 * 功能 返回$id的一级子集 */ function filter($id,$key=array("id","pid")) { $cmd = create_function('$var',"return($var[$key[1]]=='$id');"); return array_filter($this->data,$cmd); } /** * node 方法 * 功能 根据模板构造指定节点数据 */ function node($id,$key=array("id","pid","text","link")) { $ar = $this->filter($id,$key); if(($n = count($ar)) == 0) return ""; $块 = ""; foreach($ar as $value) { $n--; $p = sign($value[node_childs]); $可见 = "none";//"block"; $标识 = $p==0 ? $p : $p+$n; $主图标 = "<img src="{$this->images[$p][sign($n)]}">"; $副图标 = empty($this->images[$p][2]) ? "" : "<img src="{$this->images[$p][2]}">"; $文字 = empty($value[$key[3]]) ? $value[$key[2]] : "<a href="{$value[$key[3]]}">{$value[$key[2]]}</a>"; $连线 = $this->images[3][sign($n)]; $编号 = $value[id]; $子树 = $this->all ? $this->node($value[$key[0]],$key) : $this->bond[$p]; $块 .= eval("return "".AddSlashes($this->block)."";"); } return eval("return "n".AddSlashes($this->tpl)."";"); } /** * build方法 * 功能 计算各节点的一级子节点数,用附加的node_childs表示 */ function build($key=array("id","pid")) { foreach($this->data as $k=>$v) { $this->data[$k][node_childs] = count($this->filter($v[$key[0]])); } } } class exTree extends Tree { var $images = array( // 节点图片 array("images/icon-page.gif"), // 无子节点 array("images/OpenFolder.gif","images/OpenFolder.gif"), // 子节点关闭 array("images/CloseFolder.gif","images/CloseFolder.gif") ); // 子节点打开 } $t = new Tree; //$t = new exTree; // 去掉注释看看效果 $ar = array( array(id=>1,pid=>0,text=>"PHP",link=>"#"), array(id=>2,pid=>1,text=>"函数"), array(id=>5,pid=>1,text=>"类"), array(id=>3,pid=>0,text=>"ASP"), array(id=>4,pid=>2,text=>"d"), array(id=>6,pid=>3,text=>"66"), array(id=>7,pid=>0,text=>"JSP") ); //$t->data = $ar; foreach($ar as $v) $t->insert($v); $t->insert(array(id=>8,pid=>4,text=>"abc",link=>"aaaa")); $t->build(); if(! isset($_GET['node'])) { $t->display("table"); if(0) // 1 一次性加载 $t->display(); else { // 分步加载 $t->javascript(); echo $t->node(0); } }else { // 分步加载时返回指定节点 $s = $t->node($_GET['node']); $s = preg_replace("/r?n/","\n",$s); echo "myload = '$s'"; } ?> phpfans.net收集整理 |