标签:定义 :hover 点击 padding ram 回调函数 return thrown hidden
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 },
标签:定义 :hover 点击 padding ram 回调函数 return thrown hidden
原文地址:https://www.cnblogs.com/jiapengsongweb/p/9055100.html