官網介紹 zTree 是一個依靠 jQuery 實現的多功能 “樹插件”。優異的性能、靈活的配置、多種功能的組合是 zTree 最大優點。
1、zTree 是利用 JQuery 的核心代碼,實現一套能完成大部分常用功能的 Tree 插件
2、zTree v3.0 將核心代碼按照功能進行了分割,不需要的代碼可以不用加載
3、采用了 延遲加載 技術,上萬節點輕松加載,即使在 IE6 下也能基本做到秒殺
4、兼容 IE、FireFox、Chrome、Opera、Safari 等瀏覽器
5、支持 JSON 數據
6、支持靜態 和 Ajax 異步加載節點數據
7、支持任意更換皮膚 / 自定義圖標(依靠css)
8、支持極其靈活的 checkbox 或 radio 選擇功能
9、提供多種事件響應回調
10、靈活的編輯(增/刪/改/查)功能,可隨意拖拽節點,還可以多節點拖拽喲
11、在一個頁面內可同時生成多個 Tree 實例
12、簡單的參數配置實現 靈活多變的功能
ztree是一個很好的樹形結構組件,依賴Jquery,以其優異和完備的api可以自定義樹形的多種實現,做到靈活配置,最近看了淘寶的圖片空間,用的也恰好是ztree,所已就打算copy下來...
先看下效果圖:
繼續貼代碼:
首先引入相關的配置依賴文件
1 <link href="$!webPath/resources/js/zTree/css/zTreeStyle/zTreeStyle.css" type="text/css" rel="stylesheet"/> 2 <script type="text/javascript" charset="utf-8" src="$!webPath/resources/js/zTree/js/jquery.ztree.core-3.5.js"></script> 3 <script type="text/javascript" charset="utf-8" src="$!webPath/resources/js/zTree/js/jquery.ztree.excheck-3.5.js"></script> 4 <script type="text/javascript" charset="utf-8" src="$!webPath/resources/js/zTree/js/jquery.ztree.exedit-3.5.js"></script>
相關json數據
1 [ 2 { 3 "id": "1", 4 "name": "我的圖片", 5 "isParent": true, 6 "checked": false, 7 "nocheck": false, 8 "open": true, 9 "click": "photo_manage.accessory_list('1','common')", 10 "children": [ 11 { 12 "id": "1753", 13 "name": "測試_123kl", 14 "isParent": true, 15 "checked": false, 16 "nocheck": false, 17 "open": false, 18 "click": "photo_manage.accessory_list('1753','common')" 19 }, 20 { 21 "id": "1478", 22 "name": "日化家居", 23 "isParent": true, 24 "checked": false, 25 "nocheck": false, 26 "open": false, 27 "click": "photo_manage.accessory_list('1478','common')" 28 }, 29 { 30 "id": "1477", 31 "name": "美容彩妝", 32 "isParent": true, 33 "checked": false, 34 "nocheck": false, 35 "open": false, 36 "click": "photo_manage.accessory_list('1477','common')" 37 }, 38 { 39 "id": "1476", 40 "name": "母嬰用品", 41 "isParent": true, 42 "checked": false, 43 "nocheck": false, 44 "open": false, 45 "click": "photo_manage.accessory_list('1476','common')" 46 }, 47 { 48 "id": "1475", 49 "name": "營養保健", 50 "isParent": true, 51 "checked": false, 52 "nocheck": false, 53 "open": false, 54 "click": "photo_manage.accessory_list('1475','common')" 55 }, 56 { 57 "id": "1474", 58 "name": "進口食品", 59 "isParent": true, 60 "checked": false, 61 "nocheck": false, 62 "open": false, 63 "click": "photo_manage.accessory_list('1474','common')" 64 } 65 ] 66 } 67 ]
在script腳本中定義setting和zTreeNodes
1 var curStatus = "init", curAsyncCount = 0, asyncForAll = false, goAsync = false; 2 var setting = { 3 async: { 4 enable: true, 5 autoParam: ["id=ids"],//, "name=n", "level=lv" 6 url: "$!webPath/xxx/xxxTreeData.htm", 7 dataFilter: filter, 8 type: "post" 9 }, 10 view: { 11 fontCss: getFont, 12 showLine: true, 13 expandSpeed: "", 14 addHoverDom: addHoverDom, 15 //removeHoverDom: removeHoverDom, 16 selectedMulti: false 17 }, 18 edit: { 19 drag: { 20 isCopy: true, 21 isMove: true, 22 prev:true, 23 next:true 24 }, 25 enable: true, 26 showRemoveBtn: false, 27 //removeTitle: "刪除菜單", 28 renameTitle: "編輯菜單名稱" 29 }, 30 data: { 31 keep: { 32 parent: true 33 }, 34 simpleData: { 35 enable: false 36 } 37 }, 38 callback: { 39 onRightClick: onRightClick, 40 //beforeRemove: beforeRemove, //節點被刪除之前的事件,並且根據返回值確定是否允許刪除操作 41 beforeRename: beforeRename, //用於捕獲節點編輯名稱結束 42 43 beforeAsync: beforeAsync, //用於捕獲異步加載之前的事件回調函數,zTree 根據返回值確定是否允許進行異步加載 44 onAsyncSuccess: onAsyncSuccess, //用於捕獲異步加載出現異常錯誤的事件回調函數 45 onAsyncError: onAsyncError, //用於捕獲異步加載正常結束的事件回調函數 46 47 beforeDrag: beforeDrag, //用於捕獲節點被拖拽之前的事件回調函數,並且根據返回值確定是否允許開啟拖拽操作 48 beforeDrop: beforeDrop, //用於捕獲節點拖拽操作結束之前的事件回調函數,並且根據返回值確定是否允許此拖拽操作 49 beforeDragOpen: beforeDragOpen, //用於捕獲拖拽節點移動到折疊狀態的父節點后,即將自動展開該父節點之前的事件回調函數,並且根據返回值確定是否允許自動展開操作 50 onDrag: onDrag, //用於捕獲節點被拖拽的事件回調函數 51 onDrop: onDrop, //用於捕獲節點拖拽操作結束的事件回調函數 52 onExpand: onExpand //用於捕獲節點被展開的事件回調函數 53 } 54 };
相關的html和css
1 <div > 2 <div class="zTreeDemoBackground left" > 3 <!--<ul id="treeDemo" class="ztree"></ul>--> 4 <ul id="zTreeMenuContent" class="ztree" style="height: 790px;"></ul> 5 </div> 6 </div> 7 <style type="text/css"> 8 div#rMenu{ 9 position: fixed; 10 visibility:hidden; 11 top:0; 12 background-color: #fff; 13 text-align: left; 14 border: 1px solid #c9caca; 15 box-shadow: 0 0 2px #c9caca; 16 padding: 2px 0; 17 z-index: 999; 18 } 19 20 div#rMenu ul li{ 21 margin: 1px 0; 22 padding: 0 5px; 23 cursor: pointer; 24 list-style: none; 25 height: 30px; 26 background-color: #fff; 27 28 } 29 div#rMenu ul li:hover{ 30 background: #ddd; 31 } 32 </style> 33 34 <div id="rMenu" style="width: 120px;height: 110px;font-size: 12px;" > 35 <ul> 36 <li id="m_add" > 37 <i class="fa fa-plus fa-lg" aria-hidden="true"></i> 38 <span style="color:#1681ff;"> 39 添加相冊 40 </span> 41 42 </li> 43 <li id="m_rename" onclick="editAlbumName();"> 44 <i class="fa fa-edit fa-lg" aria-hidden="true"></i> 45 <span style="color:#1681ff;"> 46 重新命名 47 </span> 48 </li> 49 <li id="m_del" > 50 <i class="fa fa-close fa-lg" aria-hidden="true"></i> 51 <span style="color:#1681ff;"> 52  刪除相冊 53 </span> 54 </li> 55 </ul> 56 </div>
基本增刪改和右鍵功能
1 //節點數據過濾 2 function filter(treeId, parentNode, childNodes) { 3 if (!childNodes) { 4 return null; 5 } 6 for (var i = 0, l = childNodes.length; i < l; i++) { 7 childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.'); 8 } 9 return childNodes; 10 } 11 12 function expandNodes(nodes) { 13 if (!nodes) { 14 return; 15 } 16 17 curStatus = "expand"; 18 var zTree = jQuery.fn.zTree.getZTreeObj("zTreeMenuContent"); 19 if (zTree != null) { 20 for (var i = 0, l = nodes.length; i < l; i++) { 21 zTree.expandNode(nodes[i], true, false, false); 22 if (nodes[i].isParent && nodes[i].zAsync) { 23 expandNodes(nodes[i].children); 24 } else { 25 goAsync = true; 26 } 27 } 28 } 29 } 30 31 //字體設置 32 function getFont(treeId, node) { 33 return node.font ? node.font : {}; 34 } 35 36 ////////////////////下面是處理增刪改節點////////////////// 37 38 //節點被刪除之前的事件,並且根據返回值確定是否允許刪除操作 39 function beforeRemove(treeId, treeNode) { 40 41 } 42 43 //用於捕獲節點編輯名稱 44 function beforeRename(treeId, treeNode, newName, isCancel) { 45 46 if (treeNode.id === "1") { 47 layer.msg('根目錄不能編輯!', {icon: 3}); 48 return true; 49 } else { 50 if (treeNode.name == newName) { 51 return true; 52 } else if (newName.length == 0) { 53 layer.msg('菜單名稱不能為空!', {icon: 3}); 54 treeNode.name = treeNode.name; 55 return false; 56 } else { 57 58 var cn_pattern= /[\u4e00-\u9fa5]/g; 59 var g = newName.match(cn_pattern); 60 var cn_length = newName.length; 61 if(g!=null){ 62 var cn_numbers = g.length; 63 cn_length = cn_numbers*2+(cn_length-cn_numbers); 64 } 65 66 if(cn_length>99){ 67 layer.msg('名稱不能超過99個字符(1個漢字為2個字符)', {icon: 7}); 68 return false; 69 }else{ 70 var param_data = {"album_id": treeNode.id, "album_name": newName}; 71 var reData = ''; 72 jQuery.ajax({ 73 type: "post", 74 async: false, 75 url: "$!webPath/xxx/xxx_ajax_update.htm", 76 data: param_data, 77 success: function (save_id) { 78 reData = save_id; 79 } 80 }); 81 if (reData == treeNode.id) { 82 return true; 83 } else { 84 layer.msg("修改<" + treeNode.name + ">菜單名稱失敗!", {icon: 3}); 85 return false; 86 } 87 } 88 89 } 90 } 91 } 92 93 //添加菜單 94 var newCount = 1; 95 function addHoverDom(treeId, treeNode) { 96 var sObj = $("#" + treeNode.tId + "_span"); 97 if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) { 98 return; 99 } 100 }; 101 102 103 function dropNext(treeId, nodes, targetNode) { 104 var pNode = targetNode.getParentNode(); 105 if (pNode && pNode.dropInner === false) { 106 return false; 107 } else { 108 for (var i = 0, l = curDragNodes.length; i < l; i++) { 109 var curPNode = curDragNodes[i].getParentNode(); 110 if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) { 111 return false; 112 } 113 } 114 } 115 return true; 116 } 117 118 function dropPrev(treeId, nodes, targetNode) { 119 var pNode = targetNode.getParentNode(); 120 if (pNode && pNode.dropInner === false) { 121 return false; 122 } else { 123 for (var i = 0, l = curDragNodes.length; i < l; i++) { 124 var curPNode = curDragNodes[i].getParentNode(); 125 if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) { 126 return false; 127 } 128 } 129 } 130 return true; 131 } 132 133 function dropInner(treeId, nodes, targetNode) { 134 if (targetNode && targetNode.dropInner === false) { 135 return false; 136 } else { 137 for (var i = 0, l = curDragNodes.length; i < l; i++) { 138 if (!targetNode && curDragNodes[i].dropRoot === false) { 139 return false; 140 } else if (curDragNodes[i].parentTId && curDragNodes[i].getParentNode() !== targetNode && curDragNodes[i].getParentNode().childOuter === false) { 141 return false; 142 } 143 } 144 } 145 return true; 146 } 147 148 //className = "dark", 149 //用於捕獲節點被拖拽之前的事件回調函數,並且根據返回值確定是否允許開啟拖拽操作 150 var log, curDragNodes, autoExpandNode; 151 function beforeDrag(treeId, treeNodes) { 152 //className = (className === "dark" ? "" : "dark"); 153 for (var i = 0, l = treeNodes.length; i < l; i++) { 154 if (treeNodes[i].drag === false) { 155 curDragNodes = null; 156 return false; 157 } else if (treeNodes[i].parentTId && treeNodes[i].getParentNode().childDrag === false) { 158 curDragNodes = null; 159 return false; 160 } 161 } 162 curDragNodes = treeNodes; 163 return true; 164 } 165 166 167 //用於捕獲節點被拖拽的事件回調函數 168 function onDrag(event, treeId, treeNodes) { 169 //className = (className === "dark" ? "" : "dark"); 170 } 171 172 //用於捕獲節點拖拽操作結束的事件回調函數 173 function onDrop(event, treeId, treeNodes, targetNode, moveType, isCopy) { 174 175 if (treeNodes.length > 0 && targetNode) { 176 var dragId = treeNodes[0].id;//被拖拽菜單 177 var targetId = targetNode.id;//拖拽到的目標菜單 178 179 //判斷是否同級拖動 180 var treeNodes_parentId = treeNodes[0].parentTId; 181 var targetNode_parentId = targetNode.parentTId; 182 var is_child_move = false; 183 if(treeNodes_parentId==targetNode_parentId && moveType!="inner"){ 184 is_child_move = true; 185 } 186 var data = { "album_id" : dragId, "target_id" : targetId ,"moveType":moveType , "is_child_move" : is_child_move}; 187 jQuery.ajax({ 188 type: "post", 189 async: false, 190 url: "$!webPath/xxx/xxx_ajax_drag_update.htm", 191 data: data, 192 success: function(save_id){ 193 layer.msg('移動成功!', {icon: 1}); 194 }, 195 error: function () { 196 layer.msg('服務器內部異常!', {icon: 1}); 197 } 198 }); 199 } 200 } 201 202 //用於捕獲節點拖拽操作結束之前的事件回調函數,並且根據返回值確定是否允許此拖拽操作 203 function beforeDrop(treeId, treeNodes, targetNode, moveType, isCopy) { 204 if(targetNode){ 205 var targetNode_parentId = targetNode.parentTId; 206 if(targetNode_parentId==null){ 207 return false; 208 }else{ 209 return true; 210 } 211 }else{ 212 return false; 213 } 214 } 215 216 //用於捕獲節點被展開的事件回調函數 217 function onExpand(event, treeId, treeNode) { 218 if (treeNode === autoExpandNode) { 219 //className = (className === "dark" ? "" : "dark"); 220 } 221 } 222 223 function beforeAsync() { 224 layer.msg('加載中', {time: 6000,icon: 16}); 225 curAsyncCount++; 226 } 227 228 function onAsyncSuccess(event, treeId, treeNode, msg) { 229 230 curAsyncCount--; 231 if (curStatus == "expand") { 232 expandNodes(treeNode.children); 233 } else if (curStatus == "async") { 234 asyncNodes(treeNode.children); 235 } 236 //console.info(curStatus); 237 if (curAsyncCount <= 0) { 238 if (curStatus != "init" && curStatus != "") { 239 asyncForAll = true; 240 } 241 curStatus = ""; 242 } 243 layer.closeAll(); 244 } 245 246 function asyncNodes(nodes) { 247 if (!nodes) { 248 return; 249 } 250 curStatus = "async"; 251 var zTree = jQuery.fn.zTree.getZTreeObj("zTreeMenuContent"); 252 for (var i = 0, l = nodes.length; i < l; i++) { 253 if (nodes[i].isParent && nodes[i].zAsync) { 254 asyncNodes(nodes[i].children); 255 } else { 256 goAsync = true; 257 zTree.reAsyncChildNodes(nodes[i], "refresh", true); 258 } 259 } 260 } 261 262 function asyncAll() { 263 if (!check()) { 264 return; 265 } 266 var zTree = jQuery.fn.zTree.getZTreeObj("zTreeMenuContent"); 267 if (asyncForAll) { 268 269 } else { 270 asyncNodes(zTree.getNodes()); 271 if (!goAsync) { 272 curStatus = ""; 273 } 274 } 275 } 276 277 //用於捕獲異步加載正常結束的事件回調函數 278 function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) { 279 curAsyncCount--; 280 if (curAsyncCount <= 0) { 281 curStatus = ""; 282 if (treeNode != null) asyncForAll = true; 283 } 284 } 285 286 //用於捕獲拖拽節點移動到折疊狀態的父節點后,即將自動展開該父節點之前的事件回調函數,並且根據返回值確定是否允許自動展開操作 287 function beforeDragOpen(treeId, treeNode) { 288 autoExpandNode = treeNode; 289 return true; 290 } 291 292 293 //字體設置 294 function getFont(treeId, node) { 295 return node.font ? node.font : {}; 296 } 297 298 //初始化 299 var rMenu,zTree; 300 $(document).ready(function () { 301 zTree = jQuery.fn.zTree.init($("#zTreeMenuContent"), setting); 302 $("#callbackTrigger").bind("change", {}, setTrigger); //拖拽節點時自動展開父節點是否觸發 303 rMenu = $("#rMenu"); 304 }); 305 306 function reset() { 307 if (!check()) { 308 return; 309 } 310 asyncForAll = false; 311 goAsync = false; 312 jQuery.fn.zTree.init($("#zTreeMenuContent"), setting); 313 } 314 315 function check() { 316 if (curAsyncCount > 0) { 317 //$("#demoMsg").text("正在進行異步加載,請等一會兒再點擊..."); 318 return false; 319 } 320 return true; 321 } 322 323 324 function expandAll() { 325 if (!check()) { 326 return; 327 } 328 var zTree = jQuery.fn.zTree.getZTreeObj("zTreeMenuContent"); 329 if (zTree == null) 330 return false; 331 332 if (asyncForAll) { 333 zTree.expandAll(true); 334 } else { 335 expandNodes(zTree.getNodes()); 336 if (!goAsync) { 337 curStatus = ""; 338 } 339 } 340 } 341 function setTrigger() { 342 var zTree = jQuery.fn.zTree.getZTreeObj("zTreeMenuContent"); 343 zTree.setting.edit.drag.autoExpandTrigger = $("#callbackTrigger").attr("checked"); 344 } 345 //默認打開所有子級 346 // setTimeout(function () { 347 // expandAll(); 348 // }, 500); 349 350 //初始化關閉所有子級 351 expandAll(); 352 353 354 355 //鼠標右鍵功能 356 function onRightClick(event, treeId, treeNode) { 357 358 //var x = event.clientX+48; 359 //var y = event.clientY-132; 360 var x = event.clientX; 361 var y = event.clientY; 362 if (!treeNode && event.target.tagName.toLowerCase() != "button" && $(event.target).parents("a").length == 0) { 363 zTree.cancelSelectedNode(); 364 showRMenu("root", x, y); 365 } else if (treeNode && !treeNode.noR) { 366 zTree.selectNode(treeNode); 367 showRMenu("node", x, y); 368 } 369 } 370 371 function editAlbumName(){ 372 hideRMenu(); 373 zTree = jQuery.fn.zTree.getZTreeObj("zTreeMenuContent"); 374 var nodes = zTree.getSelectedNodes(); 375 zTree.editName(nodes[0]); 376 return true; 377 } 378 379 380 381 function showRMenu(type, x, y) { 382 $("#rMenu ul").show(); 383 if (type=="root") { 384 $("#m_del").hide(); 385 $("#m_rename").hide(); 386 } else { 387 $("#m_del").show(); 388 $("#m_rename").show(); 389 $("#m_add").show(); 390 } 391 rMenu.css({"top":y+"px", "left":x+"px", "visibility":"visible"}); 392 $("body").bind("mousedown", onBodyMouseDown); 393 } 394 395 function hideRMenu() { 396 if (rMenu) rMenu.css({"visibility": "hidden"}); 397 jQuery("body").unbind("mousedown", onBodyMouseDown); 398 } 399 function onBodyMouseDown(event){ 400 if (!(event.target.id == "rMenu" || $(event.target).parents("#rMenu").length>0)) { 401 rMenu.css({"visibility" : "hidden"}); 402 } 403 }
1 photo_del:function(){ /*刪除相冊*/ 2 $("#syncBtndel,#m_del").unbind("click").click(function(){ 3 4 var treeObj = jQuery.fn.zTree.getZTreeObj("zTreeMenuContent"); 5 var nodes = treeObj.getSelectedNodes(true); 6 if(nodes.length<=0){ 7 layer.msg('請選擇一個相冊', {icon: 3}); 8 return false; 9 } 10 var node = nodes[0]; 11 if(node.id==1){ 12 layer.msg('根目錄不能刪除', {icon: 3}); 13 return false; 14 } 15 16 layer.confirm('確定要刪除('+node.name+')相冊嗎,該相冊下的圖片不會被刪除?', { 17 btn: ['確定','取消'] //按鈕 18 }, function(){ 19 20 var data = { "album_id" : node.id }; 21 var reData = ''; 22 jQuery.ajax({ 23 type: "post", 24 async: false, 25 url: web_Path+"/xxx/xxx_album_del.htm", 26 data: data, 27 success: function(delete_id){ 28 reData = delete_id; 29 //刷新樹節點 30 //treeObj.reAsyncChildNodes(null, "refresh"); 31 32 //移除刪除的節點 33 treeObj.removeNode(node); 34 35 //刷新相冊 36 photo_manage.accessory_list(null,"delce"); 37 38 } 39 }); 40 if(reData != node.id){ 41 layer.msg("刪除<" + node.name + ">菜單失敗!", {icon: 3}); 42 } 43 layer.closeAll(); 44 }, function(){ 45 layer.msg('已取消', {time: 2000, }); 46 }); 47 }); 48 },
1 photo_add:function(){ /*添加相冊*/ 2 3 var photo_name = $("#groupTitle").val(); 4 if(isEmpty(photo_name)){ 5 layer.msg('相冊名稱不能為空', {icon: 7}); 6 return false; 7 } 8 9 //相冊名稱格式驗證 10 //var pattern = new RegExp("^[\u4E00-\u9FA5A-Za-z0-9]{1,20}$"); 11 //if(!pattern.test(photo_name)){ 12 // layer.msg('請輸入正確的格式(中文、英文、數字)', {icon: 7}); 13 // return false; 14 //} 15 16 //相冊名稱長度驗證{名稱不能超過20個字符(1個漢字為2個字符)} 17 var cn_pattern= /[\u4e00-\u9fa5]/g; 18 var g = photo_name.match(cn_pattern); 19 var cn_length = photo_name.length; 20 if(g!=null){ 21 var cn_numbers = g.length; 22 cn_length = cn_numbers*2+(cn_length-cn_numbers); 23 } 24 25 if(cn_length>99){ 26 layer.msg('名稱不能超過99個字符(1個漢字為2個字符)', {icon: 7}); 27 return false; 28 } 29 30 //獲取當前選中節點 31 var treeObj = jQuery.fn.zTree.getZTreeObj("zTreeMenuContent"); 32 var nodes = treeObj.getSelectedNodes(true); 33 var node = null; 34 var orderIds = null; 35 if(nodes.length>0){ 36 node = nodes[0]; 37 orderIds = (node.children == undefined ? 1 : (node.children.length + 1)); 38 }else{ 39 node = treeObj.getNodes()[0]; 40 orderIds = treeObj.getNodes()[0].children.length+1; 41 } 42 var addName = photo_name;//菜單初始化名稱 43 var param_data = {"parentid" : node.id, "album_name" : addName, "album_sequence" : orderIds }; 44 var reData = ''; 45 jQuery.ajax({ 46 type: "post", 47 async: false, 48 url: web_Path+"/xxx/xxx_ajax_save.htm", 49 data: param_data, 50 success: function(save_id){ 51 reData = save_id; 52 $('#syncBtn').popover('hide'); 53 $('#m_add').popover('hide'); 54 $(".popover").css("display","none"); 55 $("#groupTitle").val(''); 56 }, 57 error: function(){ 58 layer.msg('服務器內部異常', {icon: 3}); 59 } 60 }); 61 if(reData != ""){ 62 //強制刷新該節點下的子節點 63 if(node.id==1){ 64 //刷新整棵樹 65 treeObj.reAsyncChildNodes(null, "refresh"); 66 }else{ 67 //刷新選中節點下的子節點 68 treeObj.reAsyncChildNodes(nodes[0], "refresh"); 69 } 70 layer.closeAll(); 71 } 72 //隱藏樹結構右鍵菜單 73 hideRMenu(); 74 },
到這里就差不多了,服務器代碼就不貼了,就節點之間的移動和排序稍微復雜些,其他的實現起來不難。