dtree的使用和扩展
相信用過dtree的童靴的不在少數,網絡上流傳的JS樹有很多,例如雪花樹MzTreeView,EXT、Struts2出來之后,也有自己的樹控件,但是這么多風姿卓約的倩影中,我獨愛,獨愛dtree那一棵。原因有二:1.簡單易用,能滿足基本需要 2.代碼簡單,擴展起來也很容易。 這就像找MM一樣,簡單單純傻傻的MM好,那些復雜要猜心的就讓她靠邊吧,不能把握的再美再好咋都不要,哈哈,扯遠了。
言歸正傳,先介紹dtree的基本使用。第一步,引用dtree的資源,在你的頁面文件head標簽中引用dtree的js文件和css樣式文件。例如我的代碼如下,路徑視你存放dtree資源的具體情況而定:
第二步,定義和展示樹。dtree通常可放在一個div中,在你的頁面文件中要顯示樹的地方,添加下列代碼:
<div class="dtree" > <script type="text/javascript">/* 1. 定義一個樹對象 */ var d = new dTree('d'); // 隱含創建一個根節點,id等于-1,不可見/* 2. 添加一級節點 */ d.add("0","-1","所有類別"); //這里-1是前面根節點的id,說明是新增的節點是d的直接子節點/* 循環添加其他節點 */ /* 3. 參數說明:1.ID 2.父ID 3.名稱 4.URL 5.熱點提示 6.URL顯示目標target 7.節點關閉時圖標 8.節點打開時圖標 9.判斷節點是否打開 */ <c:forEach items="${userLogSortList}" var="treeNode">d.add( "${treeNode.sortId}","${treeNode.parentId}","${treeNode.sortName}", "${treeNode.url}","${treeNode.sortName}","logList");</c:forEach> /* 4.寫的div中展示 */ document.write(d);</script> </div>對前面代碼,簡單說明:其中注釋里1到3步是對樹各節點的定義,注釋4是把樹最終展示到頁面,其中1到3步的代碼中用到EL循環和表達式,EL是什么就不要我解釋了吧?!如果你不想使用dtree默認的節點關閉和打開的圖標,你也可以在add函數的第7個和第8個參數中填上你自己中意的圖標路徑。
怎么樣,很簡單吧,當然,樹的數據需要你在后臺準備好,這對那種樹控件都是逃避不了的工作。 但在實際使用中,dtree會有不足,在有些應用場景不能滿足我們的需求,所以有必要對dtree進行擴展,這就好比為了愛,我們會不斷使自己進步,讓自己變得更優秀,盡力把最美好的一面展示給對方,我想dtree如果有靈性,她也希望如此的,呵呵。但是在向完美靠近的過程中,需要根據自身實際情況采取合適的方法,否則適得其反,所以我們有必要先了解dtree,打開你的dtree.js文件吧,讓我們感受感受dtree的內心,就像感受和情人之間的心靈默契,有些東西語言是多余的。
dtree.js中最主要有下面幾個函數:
1.節點定義函數:function Node(id, pid, name, url, title, target, icon, iconOpen, open)
其中函數中_is屬性表示是否被選擇,_ls屬性表示是否為最后一個兄弟節點,_hc表示是否有子節點,_p指向父節點.
2.樹對象定義函數:function dTree(objName) :
該函數完成后述功能:a.定義樹全局配置信息 b.定義樹默認圖標 c.創建樹對象和根節點,創建根節點時會調用函數1.
3.節點添加函數:dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) 實際是調用函數1定義節點屬性,同時把節點增加到樹對象的aNodes節點數組中
4.dTree.prototype.node = function(node, nodeId)?
根據定義構建節點的圖標、url(關聯展開和關閉函數到非末節點)以及顯示文本。
5.dTree.prototype.addNode = function(pNode)?
根據定義構建樹首次展示的結構模型,會調用函數4
6.dTree.prototype.toString = function()?
調用函數4、5,串化dtree展示到頁面div中。
以上函數1到3在前面代碼中定義的步驟時會調用,函數4到5在前面代碼中展示樹的步驟會調用,這是最重要的幾個函數了,
是dtree的思想精華所在了,呵呵,其他的是事件觸發函數。學習prototype的童靴也可以用dtree.js作為學習的入門課本,不錯的。
了解了dtree的內心,我們再來說說擴展,我這里的第一個需求是為dtree增加checkbox按鈕,我想這個是很多童靴都想要的吧,網上已經有很多這樣的例子,我也就借花獻佛了、拋金引玉了。
步驟1,把函數1頭修改為function Node(id, pid, name, url, title, target, icon, iconOpen, open,checked,isBottom) ,在函數體增加下列代碼:
?
步驟2,在函數2的函數體的config信息中增加下列代碼:
check: false , useAllData: false?
其中useAllData這個屬性及相關代碼可能不是你想要的,但這里我一起給列出來了。
步驟3,函數3的函數體修改后如下:
var node = new Node(id, pid, name, url, title, target, icon, iconOpen, open, checked,isBottom);this.aNodes[this.aNodes.length] = node; var n; var len = this.aNodes.length; if ( node.checked ){ var pid = node.pid; var bSearch; do{ bSearch = false; for( n = 0; n < len; n++){ if ( this.aNodes[n].id == pid){ if (this.aNodes[n].checked == false){ this.aNodes[n].checked=true; pid = this.aNodes[n].pid; bSearch= true; break; } } } }while(bSearch==true); }?
后面兩重循環的作用是,當一個節點被勾選時候,改變其父輩祖宗節點的選擇狀態定義。
步驟4,在函數4中創建圖標的代碼段中增加下列代碼,該代碼的作用是用來構建節點checkbox的圖標以及為節點關聯checkbox勾選觸發函數:
if(this.config.check == true){ if(node.checked ==true){ str+= '<input type="checkbox" id="c'+ this.obj + nodeId + '" value="'+ node.id +'" '; if (this.config.useAllData) { str+= ' name="dataId" '; } if (!this.config.useAllData) { str+= node.isBottom ? ' name="dataId" ':' name="nodeId"'; } str+= ' οnclick="javascript:'+this.obj+'.cc('+nodeId+')" checked />'; }else{ str+= '<input type="checkbox" id="c'+ this.obj + nodeId + '" value="'+ node.id +'" '; if (this.config.useAllData) { str+= ' name="dataId" '; } if (!this.config.useAllData) { str+= node.isBottom ? ' name="dataId" ':' name="nodeId"'; } str+= ' οnclick="javascript:'+this.obj+'.cc('+nodeId+')" />'; } }?
步驟5,增加一個新的函數,就是步驟4的cc函數,作用是單節點checkbox勾選狀態改變時,改變相應祖宗節點和子孫節點checkbox的狀態,如下:
dTree.prototype.cc=function(nodeId){ var cs = document.getElementById("c"+this.obj+nodeId).checked; var n,node = this.aNodes[nodeId]; var len =this.aNodes.length;for (n=0; n<len; n++) {if (this.aNodes[n].pid == node.id) { document.getElementById("c"+this.obj+n).checked=cs; this.cc(n); } } if (cs ==f alse){ var clicknode=node do{ for( j=0; j<l en; j++){ if(this.aNodes[j].pid==clicknode.pid&&document.getElementById ("c"+this.obj+j).checked==true){ return; } } if ( j == len) { for(k=0;k<len;k++){ if (this.aNodes[k].id == clicknode.pid ){ document.getElementById("c"+this.obj+k).checked=false; clicknode=this.aNodes[k]; break; } } }}while(clicknode.pid!=-1);} if(cs==true){ var pid=node.pid; var bSearch; do{ bSearch=false; for(n=0;n<len;n++){ if (this.aNodes[n].id == pid ){ document.getElementById("c"+this.obj+n).checked = true; pid = this.aNodes[n].pid; bSearch = true; break; } } }while(bSearch==true); }}?
稍微麻煩點,但是看到checkbox出來時,我想你會有成就感,就象歷盡艱辛情路追到你心儀女孩后時內心的雀躍。
最后講講擴展的第二個需求,為末級節點增加外部js函數調用,外部js函數是留給童靴們在使用時去實現的,這樣子,童靴們可以在這個外包js函數去定制和樹有關的其他業務動作,甚至是異步調用,實現ajax的無刷新效果。具體擴展方法是,在函數4中判斷url的代碼中再增加一個分支,代碼如下:
else if ((!this.config.folderLinks || !node.url) && !node._hc && node.pid != this.root.id){ str += '<a href="javascript: ' + this.obj + 'treeNodeClick(' + node.id + ');" class="node">'; }?
轉載于:https://www.cnblogs.com/iteakey/p/4052167.html
總結
以上是生活随笔為你收集整理的dtree的使用和扩展的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: text-overflow
- 下一篇: ida提取hashab算法记录