ztree插件的使用及列表项拖拽的实现(jQuery)+异步加载节点数据
为了实现如图所示的树状结构图,并使列表项可拖动到盒子里,研究了ztree这个插件的使用,并仔细研究了列表项的拖动事件。完成了预期需求,对jQuery的运用得到了提高。这个插件的功能非常强大,除了基本的简单树结构外,还支持自定义图标、自定义字体、单击节点控制、异步加载节点数据等多种扩展功能。本文只介绍一下基本树的实现,需要扩展功能的话,可以参考其API根据项目需求灵活展开工作。官网地址为:http://www.treejs.cn/v3/demo.php#_101
需求图
实现:首先我们先下载ztree这个插件,解压后会发现里面文件很多,那是因为这个插件涵盖了各种需求的实现文件。找到中文(CN)目录下的文件,根据页面demo来实现我们的需求,首先引入核心库jquery-1.9.1.min.js,jquery.ztree.core.js,zTreeStyle.css,别忘了img这个文件夹,如果缺失可能会导致树显示的不完整,文件夹也显示不出来。引入这些后,还需要在需要放置li列表的ul上面添加一个class="ztree"。使用这个的时候踩过两个坑,一个就是img文件夹未添加,一个就是ztree类名未添加,导致反复调试。下面上代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="zTreeStyle.css" type="text/css"> <script src="jquery-1.9.1.min.js"></script> <script src="jquery.ztree.core.js"></script> <style> .divT li{ list-style: none; } </style> </head> <body style="padding-left: 140px"> <div class="content_wrap"> <div class="zTreeDemoBackground left"> <ul id="ulDiv" class="ztree"></ul> </div> </div> <div class="divT" id="box1" style="width:200px;height:200px;border:1px solid red"> </div> <div class="divT" id="box2" style="width:200px;height:200px;border:1px solid red"> </div> <div class="divT" id="box3" style="width:200px;height:200px;border:1px solid red"> </div> <script> var setting = { }; var zNodes =[ {name:"条目列表", open:true, children: [ { name:"叶子节点1"}, { name:"叶子节点2"}, { name:"叶子节点3"}, { name:"叶子节点4"}, { name:"叶子节点5"}, { name:"叶子节点6"}, { name:"叶子节点7"}, { name:"叶子节点8"}, { name:"叶子节点9"} ]} ]; $(document).ready(function(){ $.fn.zTree.init($("#ulDiv"), setting, zNodes); var liDoms = $('#ulDiv_1_ul li'); //循环设置每个子项的draggable属性,以及时候拖动标记 liDoms.each(function (index) { this.draggable='true'; this.flag=false; this.ondragstart=(function (k) { return function () { this.flag=true; console.log('第'+(k+1)+'项开始移动') } })(index); this.ondragend=(function (k) { return function () { this.flag=false; } })(index); }); //投放区事件 var acceptDiv=$(".divT"); acceptDiv.each(function (index) { this.ondragenter=(function(k){ return function (e) { e.preventDefault(); } })(index); this.ondragover=(function(k){ return function (e) { e.preventDefault(); } })(index); this.ondragleave=(function(k){ return function (e) { e.preventDefault(); } })(index); this.ondrop = (function(k){ return function (e) { e.preventDefault(); liDoms.each(function () { if(this.flag){ $('.divT:eq('+k+')').append(this); console.log('落地在第'+(k+1)+'个盒子'); } }); } })(index); }); }); </script> </body> </html>
可以看到,ul下面的列表li是由zNodes这个数组渲染出来的,在渲染并填充好列表后我们才能对其进行绑定操作,因此要注意事件添加的先后顺序,否则会达不到预期效果。首先循环设置每个子项,下面对子项的拖拽事件做一个介绍。
①draggable属性:标签元素要设置draggable=true,否则不会有效果,例如上述代码中将每个li节点的属性设置为draggable='true';
②ondragstart事件:当拖拽元素开始被拖拽的时候触发的,此事件作用在被拖拽元素上。
③ondragover事件:拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上。
④ondragend事件:当拖拽完成后触发的事件,此事件作用在被拖拽元素上。
⑤ondrop事件:被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上。
⑥ondragenter事件:当拖拽元素进入目标元素的时候触发的事件,此事件作用在目标元素上。
在上述代码中,Event.preventDefault()方法用来阻止默认的事件方法等执行。在Ondragover中一定要执行preventDefault(),否则ondrop事件不会被触发。Event.effectAllowed属性,就是拖拽的效果。
实现了如下预期功能:
异步加载节点数据
setting设置如下所示,具体API可查看官网,此时url根据单击节点的不同而动态设置,根据层级的不同需要调整相应设置。
var setting = { data:{ simpleData:{ enable:true } }, view:{ showIcon:false,//设置是否显示图标 showLine:true//设置是否显示线条 }, async: { enable: true, type:"get", url:function (treeId,treeNode) { console.log(treeNode.ID); return '/api/group/'+treeNode.ID+'?param=&proxy=eyJQcm90b2NvbCI6IkNsb3NlbGkiLCJVc2VybmFtZSI6IjE4ODg4ODg4ODg4IiwiUGFzc3dvcmQiOiJBcmNzb2Z0MDEiLCJWZW5kb3IiOiJIZW11U21iIn0%3D'; }, autoParam:["id", "name=n", "level=lv"], otherParam:{"otherParam":"zTreeAsyncTest"}, dataFilter: filter } }; function filter(treeId, parentNode, data) { var childNodes=data.Result.Children; if (!childNodes) return null; console.log(childNodes); console.log(999); childNodes.map(function (x) { x.isParent=true; return x; }); var i,l=childNodes.length; for (i=0; i<l; i++) { childNodes[i].name = childNodes[i].Name.replace(/\.n/g, '.'); } return childNodes; } var zNodes =[ {Name:data.Result.Name, open:true,isParent:true, children: data.Result.Children.map(function (x) { x.isParent=true; return x; }) } ]; $.fn.zTree.init($("#dev-list"), setting, zNodes);