js 树菜单
?
<!doctype html>
<title>樹 by 司徒正美</title>
<meta charset="utf-8"/>
<meta name="keywords" content="樹 by 司徒正美" />
<meta name="description" content="樹 by 司徒正美" />
<h2>樹 by 司徒正美</h2>
<script type="text/javascript">
? Tree = function(){
??? this.path = "http://images.cnblogs.com/cnblogs_com/rubylouvre/205314/o_";
??? this.name = "tree";
??? this.id = + new Date + parseInt(Math.random()*100000);
??? this.initialize.apply(this, arguments);
? }
? Tree.prototype = {
??? constructor : Tree,
??? initialize : function(config){
????? var me = this, renderTo = config.renderTo;
????? me.tree = config.data;
????? me.container = ((typeof renderTo === "string") ?
??????? document.getElementById(renderTo) : renderTo) || document.body;
????? me.panel = document.createElement("div");
????? me.panel.setAttribute("id","tree" + me.id)
????? me.container.insertBefore(me.panel,null);
????? var id = "#"+me.panel.id;
????? var sheet = document.createElement('style');
????? sheet.type = 'text/css';
????? document.getElementsByTagName('head')[0].appendChild(sheet);
????? var bg = "background:transparent url("+me.path;
????? var cssCode = id +" {font-size:12px;}\n" +
??????? id+" img {border:0;vertical-align: middle;}\n" +
??????? id+" span {vertical-align: bottom;}\n"+
??????? id+" .line {padding-left:18px;"+bg+"line.gif) repeat-y 0 0;}\n"+
??????? id+" .blank {margin-left:18px;}\n"+
??????? id+" img.collapse {padding-right:18px;"+bg+"folder.gif) no-repeat right center;}\n"+//控制枝節(jié)點的裝飾圖標(閉合)
????? id+" img.unfold {padding-right:18px;"+bg+"folderopen.gif) no-repeat right center;}\n"+//控制枝節(jié)點的裝飾圖標(展開)
????? id+" img.root {padding-right:18px;"+bg+"root.gif) no-repeat right center;}\n"+ //控制根節(jié)點的裝飾圖標
????? id+" img.leaf {padding-right:18px;"+bg+"leaf.gif) no-repeat right center;}\n" //控制葉節(jié)點的裝飾圖標
????? if(!+"\v1"){
??????? sheet.styleSheet.cssText = cssCode
????? }else if(/a/[-1]=='a'){
??????? sheet.innerHTML = cssCode
????? }else{
??????? sheet.appendChild(document.createTextNode(cssCode));
????? }
????? //添加根節(jié)點
????? var icon = me.makeImage("nolines_plus","collapse root")
????? var checkbox0 = me.makeImage("checkbox_0","checkbox_0");
????? me.panel.innerHTML = me.makeTree(me.tree[0][0],"b",0,icon+checkbox0, me.tree[0][2]);
????? me.childs = [];
????? me.checks = [];//由來裝載點擊數(shù)
????? me.panel.onclick = function(e){
??????? e = e || window.event;
??????? var node = e.srcElement ? e.srcElement : e.target;
??????? var current = node.parentNode;
??????? var currentIndex = current.getAttribute("index");
??????? var currentPrefix = current.getAttribute("prefix");
??????? var currentLevel = current.getAttribute("level");
??????? var subtree = me.getSubtree(currentIndex);
??????? var children = current.children[3];
??????? //添加子樹集合
??????? //存在子樹并且沒有添加時才添加
??????? if(subtree && !children){
????????? children = document.createElement("div");
????????? var childs = [];
????????? for(var i=0,length = subtree.length;i<length;i++){
??????????? var isLimb = me.hasSubtree(subtree[i][0]);
??????????? var isLast = (i == subtree.length - 1);
??????????? var prefix = isLast ? "blank" : "line";
??????????? icon = isLast ? "plusbottom" : "plus";
??????????? if(isLimb){
????????????? icon = me.makeImage(icon,"collapse limb");//枝節(jié)點前面的裝飾圖標
??????????? }else{
????????????? icon = icon.replace(/plus/, "join");//葉子節(jié)點前面的連線圖標
????????????? icon = me.makeImage(icon,"leaf");//葉子節(jié)點前面的裝飾圖標
??????????? }
??????????? childs.push(subtree[i][0])
??????????? children.innerHTML += me.makeTree(subtree[i][0],prefix,+currentLevel+1,icon+checkbox0,subtree[i][2])
????????? }
????????? me.childs[currentIndex] = childs;
????????? children.className = (currentPrefix == "line") ? "line": "blank";
????????? current.insertBefore(children,null);
??????? }
??????? if(/collapse/.test(node.className)){//如果點擊是加號或減號圖標
????????? node.src = node.src.replace(/plus/,"minus");//改變連線圖標
????????? node.className = node.className.replace("collapse","unfold");//改變裝飾圖標
????????? children &&(children.style.display = "block");
??????? }else if(/unfold/.test(node.className)){
????????? node.src = node.src.replace(/minus/,"plus");//改變連線圖標
????????? node.className = node.className.replace("unfold","collapse");//改變裝飾圖標
????????? children &&(children.style.display = "none");
??????? }
??????? if(/checkbox/.test(node.className)){//如果單擊的是checkbox圖標
????????? var checked = me.isChecked(node);//如果是true則--,如果是false則++
????????? me.setPriorCheckbox(current,checked);//一開始肯定是checkbox,返回false
????????? me.setJuniorCheckbox(current,checked)
??????? }
????? }
??? },
??? setJuniorCheckbox : function(node,/*Boolean*/checked){
????? var checkbox = node.children[1];
????? var replaceCheckbox = checked ? "checkbox_0" :"checkbox_1";
????? checkbox.src = checkbox.src.replace(/checkbox_\d/,replaceCheckbox);
????? checkbox.className? = replaceCheckbox;
????? var index = node.getAttribute("index");
????? if(!!this.childs[index]){
??????? var length = this.childs[index].length;
??????? this.checks[index] = checked ? length : 0;
??????? if(length > 0){
????????? var children = node.children[3].children;
????????? while(--length >= 0){
??????????? this.setJuniorCheckbox(children[length],checked)
????????? }
??????? }
????? }
??? },
??? setPriorCheckbox :function(node,/*Boolean*/checked){//設(shè)置上一級樹的checkbox
????? var index = node.getAttribute("index");
????? var prior = node.parentNode.parentNode;
????? var priorIndex = this.tree[index][1];
????? var priorCheckbox = prior.children[1];
????? var priorLevel = prior.getAttribute("level");
????? var priorCount = this.checks[priorIndex] || 0;
????? checked ? priorCount-- : priorCount++;
????? (priorCount < 0) && (priorCount = 0)
????? this.checks[priorIndex] = priorCount;
????? if(!!priorCheckbox){
??????? //當priorIndex等于-1時,
??????? //priorCheckbox不存在
??????? //me.childs[priorIndex]為undefined,不存在長度
??????? checked = (priorCount == this.childs[priorIndex].length);
??????? var replaceCheckbox = checked ? "checkbox_1" : "checkbox_2";
??????? //checkbox_1為全選,checkbox_2為非全選
??????? //全選,則讓上級++,即讓checked為false
??????? priorCheckbox.src =? priorCheckbox.src.replace(/checkbox_\d/,replaceCheckbox);//????????
??????? priorCheckbox.className? = replaceCheckbox;
????? }
????? if(priorLevel > 0){ //根節(jié)點沒有priorCheckbox,且priorLevel等于-1
??????? this.setPriorCheckbox(prior,checked);
????? }
??? },
??? isChecked : function(node){//如果是checkbox_0返回false,checkbox_1與checkbox_2返回true
????? return node.src.slice(-5,-4) > 0;
??? },
??? makeImage : function(image){
????? var status ="";
????? if(arguments[1] != null){
??????? status = "class='" + arguments[1] +"'";
????? }
????? return "<img src='"+this.path+image+".gif' "+status+" />"
??? },
??? makeTree : function(index,prefix,level,images,text){
????? var builder = [];
????? builder.push("<div index='");
????? builder.push(index);
????? builder.push("' prefix='")
????? builder.push(prefix);
????? builder.push("' level='")
????? builder.push(level);
????? builder.push("'>");
????? builder.push(images);
????? builder.push("<span>");
????? builder.push(text);
????? builder.push("</span></div>")
????? return builder.join('');
??? },
??? hasSubtree : function (p){
????? var tree = this.tree;
????? for(var i = 0,length = tree.length;i < length; i++){
??????? if(this.tree[i][1] == p){
????????? return true;
??????? };
????? };
????? return false;
??? },
??? getSubtree : function (p){
????? var subtree = [],tree = this.tree;
????? for(var i = 0,length = tree.length;i < length; i++){
??????? if(tree[i][1] == p){
????????? subtree.push(tree[i]);
??????? };
????? };
????? return subtree
??? }
? }
? var data = [
??? [0,-1,"前臺技術(shù)"],
??? [1,0,"表現(xiàn)層"],
??? [2,1,"CSS"],
??? [3,2,"CSS資源"],
??? [4,2,"CSS3前瞻"],
??? [5,1,"web標準知識"],
??? [6,1,"圖形"],
??? [7,6,"SVG"],
??? [8,6,"VML"],
??? [9,6,"canvas"],
??? [10,0,"結(jié)構(gòu)層"],
??? [11,10,"HTML"],
??? [12,10,"微格式"],
??? [13,10,"XML"],
??? [14,13,"XPath"],
??? [15,0,"行為層"],
??? [16,15,"core"],
??? [17,16,"變量與參數(shù)"],
??? [18,16,"對象與繼承"],
??? [19,16,"函數(shù)與閉包"],
??? [20,16,"算法"],
??? [21,16,"高級技術(shù)"],
??? [22,21,"跨域請求"],
??? [23,21,"提速技術(shù)"],
??? [24,21,"本地存儲"],
??? [25,21,"函數(shù)劫持"],
??? [26,16,"框架設(shè)計"],
??? [27,26,"Ext"],
??? [28,26,"dojo"],
??? [29,26,"mootools"],
??? [30,15,"Ajax"],
??? [31,15,"DOM"],
??? [32,15,"BOM"]
? ]
? window.onload = function(){
??? var tree = new Tree({renderTo:"test",data:data});
? }
</script>
<div id="test"></div>
轉(zhuǎn)載于:https://www.cnblogs.com/hsapphire/archive/2009/10/27/1590398.html
總結(jié)
- 上一篇: 忆
- 下一篇: 真不知写什么了,也就是很久没有做什么了