zTree 是一款依靠 jQuery 實現的多功能 "樹插件",http://www.treejs.cn/v3/main.php#_zTreeInfo,功能強大,不多贅述.
下面我將介紹如何實現使用該插件生成HTML元素Dom樹,並對其進行多樣操作.
先貼上一個簡單的HTML頁面(直接拿的ztree的用的,畫面簡單實用,里面的文字內容不用在意)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title></title> 6 <meta charset="utf-8" /> 7 <script src="../Scripts/jquery-2.2.4.min.js"></script> 8 <link href="http://localhost:83/Library/zTree_v3/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" /> 9 <script src="http://localhost:83/Library/zTree_v3/js/jquery.ztree.all-3.5.min.js"></script> 10 <script src="../Scripts/tree.js"></script> 11 <style type="text/css"> 12 div#rMenu { 13 position: absolute; 14 visibility: hidden; 15 top: 0; 16 background-color: #555; 17 text-align: left; 18 padding: 2px; 19 } 20 21 div#rMenu ul { 22 margin: 0; 23 padding: 0; 24 border: 0; 25 outline: 0; 26 font-weight: inherit; 27 font-style: inherit; 28 font-size: 100%; 29 font-family: inherit; 30 vertical-align: baseline; 31 } 32 33 .ztree { 34 margin-top: 10px; 35 border: 1px solid #617775; 36 background: #f0f6e4; 37 width: 220px; 38 height: 360px; 39 overflow-y: scroll; 40 overflow-x: auto; 41 } 42 43 div#rMenu ul li { 44 margin: 1px 0; 45 padding: 0 5px; 46 cursor: pointer; 47 list-style: none outside none; 48 background-color: #DFDFDF; 49 } 50 </style> 51 </head> 52 <body> 53 <div class="content_wrap"> 54 <div class="zTreeDemoBackground left" id="tree"> 55 <ul id="treeDemo" class="ztree"></ul> 56 </div> 57 </div> 58 <div class="example"> 59 <ul myid="1"> 60 <li myid="2"> 61 <h2 myid="3">實現方法說明</h2> 62 <ul myid="4"> 63 <li myid="5">對於這種只有一個根節點,且不顯示 +/- 開關的需求,需要利用 css、setting 配合使用</li> 64 <li myid="6">zTree v3.x 可以針對指定的 level,進行樣式設定,請查看本頁面源碼,查看 css 設置</li> 65 <li myid="7">設置 setting.view.dblClickExpand 指向 Function,可以只針對根節點關閉雙擊展開的操作</li> 66 </ul> 67 </li> 68 </ul> 69 </div> 70 </body> 71 </html>
2JS文件(僅生成dom樹),需要用到遞歸
1 var zNodes = [], zTree, rMenu, $example; 2 function loopnodes(fathernode) { 3 var ret = []; 4 var children = $(fathernode).children(); 5 children.each(function (i, em) { 6 var node = { 7 myid: $(em).attr('myid'), 8 name: $(em)[0].tagName + '|' + $(em).attr("myid"), 9 children: [] 10 }; 11 if ($(em).children().length > 0) { 12 node.children = loopnodes(em); 13 } 14 ret.push(node); 15 }); 16 return ret; 17 } 18 $(document).ready(function () { 19 $example = $(".example"); 20 zNodes = loopnodes($example); 21 zTree = treeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes); 22 }); 23 var setting = { 24 edit: { 25 showRemoveBtn: false, 26 showRenameBtn: false, 27 } 28 };
這樣就可以把指定的區域的元素遍歷到dom樹上,再根據官方提供的Apl,可以對其進行一系列的操作.
例如(舉個簡單例子,對應API很容易實現),點擊dom樹上的節點,對應的頁面元素發生變化
1 var setting = { 2 edit: { 3 showRemoveBtn: false, 4 showRenameBtn: false, 5 } , 6 callback: { 7 onClick: zTreeOnClick, 8 } 9 }; 10 function zTreeOnClick(event, treeId, treeNode) { 11 var myid = treeNode.myid; 12 $example.find('[myid="' + myid + '"]').css('color', 'red'); 13};
那么如何進行拖拽實現頁面元素與dom樹節點的變化了,首先,我們要明白ztree與位置變化相關的參數
先貼一個簡單的拖拽代碼
1 var setting = { 2 edit: { 3 drag: { 4 prev: true, 5 inner: true, 6 next: true, 7 isMove: true, 8 isCopy: true 9 }, 10 enable: true, 11 showRemoveBtn: false, 12 showRenameBtn: false 13 }, 14 callback: { 15 beforeDrag: beforeDrag, 16 beforeDrop: beforeDrop 17 } 18 }; 19 function beforeDrag(treeId, treeNodes) { 20 return true; 21 } 22 function beforeDrop(treeId, treeNodes, targetNode, moveType) { 23 return true; 24 }
我們需要需要關注的是beforeDrop,在拖拽落下的時候會傳入的:
treeNodes:拖動的節點
targetNode:目標節點
moveType:拖動節點與目標節點的關系
我們確定拖動的節點所拖到的位置,就需要依靠moveType,它可能的值是
prev: 拖動節點在目標節點之前
inner: 拖動節點在目標節點之內
next: 拖動節點在目標節點之后
關於目標節點,可以參考下面內容:
當你要把 C 拖拽到 A 和 B 之間 的時候, 如果僅僅要鼠標移動到 A和B 之間的空間內操作起來實屬不易, 所以必然是在 B 的偏上位置 或 A 的偏下位置 即可認為是 A、B之間, 並且這里面也有一些細微的區別:
在 A 偏下的時候, 你得到的 drop 的參數 target 是 A,moveType 是 next
在 B 偏下的時候, 你的道德 drop 的參數 target 是 B,moveType 是 prev
有了這層關系,很容易就可以完成拖拽dom樹,頁面元素跟隨變化
1 var setting = { 2 edit: { 3 drag: { 4 prev: true, 5 inner: true, 6 next: true, 7 isMove: true, 8 isCopy: true 9 }, 10 enable: true, 11 showRemoveBtn: false, 12 showRenameBtn: false 13 }, 14 callback: { 15 beforeDrag: beforeDrag, 16 beforeDrop: beforeDrop 17 } 18 }; 19 function dropdrag(selectmyid, targetmyid, moveType) { 20 var currentelem = $example.find('[myid=' + selectmyid + ']'); 21 var parentelem = $example.find('[myid=' + targetmyid + ']'); 22 var content = currentelem.prop("outerHTML") 23 if (moveType == 'inner') { 24 parentelem.append(content); 25 currentelem.remove(); 26 } 27 else if (moveType == "prev") { 28 parentelem.before(currentelem) 29 } 30 else { 31 parentelem.after(currentelem) 32 } 33 } 34 function beforeDrag(treeId, treeNodes) { 35 return true; 36 } 37 function beforeDrop(treeId, treeNodes, targetNode, moveType) { 38 var selectmyid = treeNodes[0].myid, 39 targetmyid = targetNode.myid; 40 dropdrag(selectmyid, targetmyid, moveType); 41 return true; 42 }