ztree树形插件
在开发项目中需要用到树插件,近期研究了几款树插件,好记性不如烂笔头 ,写下来 以后好查
MzTreeView(梅花雪) 很经典的树形菜单脚本控件 菜单树展示加载速度快 支持1w条以上大数据
缺点--不能动态修改 刷新 兼容性不好 官网没有再继续维护
最近因开发需求在寻找开源树形插件 研究了一下ztree --jQuery 树插件,很不错的一款树形插件 关键是兼容性比较好
网址:http://www.ztree.me/v3/main.php#_zTreeInfo
- zTree v3.0 将核心代码按照功能进行了分割,不需要的代码可以不用加载
- 采用了 延迟加载 技术,上万节点轻松加载,即使在 IE6 下也能基本做到秒杀
- 兼容 IE、FireFox、Chrome、Opera、Safari 等浏览器
- 支持 JSON 数据
- 支持静态 和 Ajax 异步加载节点数据
- 支持任意更换皮肤 / 自定义图标(依靠css)
- 支持极其灵活的 checkbox 或 radio 选择功能
- 提供多种事件响应回调
- 灵活的编辑(增/删/改/查)功能,可随意拖拽节点,还可以多节点拖拽哟
- 在一个页面内可同时生成多个 Tree 实例
- 简单的参数配置实现 灵活多变的功能
后续继续更新自己研究的内容
由于官网的Demo 异步都是用php代码编写,于是自己动手了写了几个简单的Demo
1、只作树的展示(异步)使用的是简单树
脚本:需要引用JQuery、jquery.ztree.core-3.5.js 类库
1 function setting() { 2 var setting = { 3 data: { 4 view: { 5 dblClickExpand: false 6 }, 7 simpleData: { 8 enable: true 9 } 10 }, 11 async: { 12 enable: true, 13 url: "GetTreeData.aspx", 14 autoParam: ["id", "name", "level"], 15 otherParam: { "otherParam": "zTreeAsyncTest", "Method": "GetTreeData", "casetype": $("input:radio:checked").val() }, 16 dataFilter: filter 17 }, 18 callback: { 19 beforeClick: beforeClick 20 21 } 22 }; 23 return setting; 24 } 25 26 27 function filter(treeId, parentNode, childNodes) { 28 if (!childNodes) return null; 29 for (var i = 0, l = childNodes.length; i < l; i++) { 30 childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.'); 31 } 32 return childNodes; 33 } 34 35 //单击进行刷新 36 function beforeClick(treeId, treeNode) { 37 var check = (treeNode && !treeNode.isParent); 38 //如果是父节点单击打开子节点 39 40 if (!check) { 41 var zTree = $.fn.zTree.getZTreeObj("tree"); 42 //只展开本节点的第一级子节点 43 zTree.expandNode(treeNode, true, false, true); 44 45 //可通过单击进行刷新和展开 46 // if (treeNode.zAsync) { 47 // //已经异步加载过的强制重新加载(刷新) 48 // zTree.reAsyncChildNodes(treeNode, "refresh", null); 49 // } 50 // else { 51 //单击展开 52 // zTree.expandNode(treeNode, true, true, true); 53 // } 54 } 55 return true; 56 } 57 58 $(document).ready(function () { 59 $.fn.zTree.init($("#tree"), setting()); 60 61 $("input:radio").change(function () { 62 $.fn.zTree.init($("#tree"), setting()); 63 }); 64 65 //刷新 66 $("#btnrefresh").click(function () { 67 var zTree = $.fn.zTree.getZTreeObj("tree"); 68 var selectednotes = zTree.getSelectedNodes(); 69 //获取的是集合 70 //必须通过循环进行加载获取选中的子节点 71 for (var i = 0, l = selectednotes.length; i < l; i++) { 72 // alert(selectednotes[i].name); 73 zTree.reAsyncChildNodes(selectednotes[i], "refresh", null); 74 } 75 76 }); 77 78 });
前台页面:
做一个可以切换的树
<input type="radio" value="USECASE" name="ustype" id="usecase" checked="checked" />用例 <input type="radio" value="CR" name="ustype" id="CR" />CR <img src="../../../Images/reload.png" id="btnrefresh" style="cursor: pointer" /> <fieldset style="overflow: auto" style="height: 500px"> <div class="zTreeDemoBackground left"> <ul id="tree" class="ztree"> </ul> </div> </fieldset>
后台请求数据页面处理:
GetTreeData.aspx
//根据请求的数据拼接代码生成Json对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 if (!LTMS.BLL.PRM.UserInfo.CheckUserLogin(Page, out _LoginUser)) { return; } 4 5 if (Request.Params["id"] != null) 6 { 7 ID = Request.Params["id"].ToString(); 8 } 9 else 10 { 11 ID = "0"; 12 } 13 14 15 if (Request.Params["level"] != null) 16 { 17 Level = Request.Params["level"].ToString(); 18 } 19 else 20 { 21 Level = "-1"; 22 } 23 24 if (Request.Params["Method"] != null) 25 { 26 Method = Request.Params["Method"].ToString(); 27 } 28 29 if (Request.Params["casetype"] != null) 30 { 31 CaseType = Request.Params["casetype"].ToString(); 32 } 33 34 //映射 35 Type type = this.GetType(); 36 MethodInfo method = type.GetMethod(Method); 37 if (method != null) 38 { 39 method.Invoke(this, null); 40 } 41 } 42 43 44 /// <summary> 45 /// 获取用例库 46 /// </summary> 47 /// <returns></returns> 48 public void GetTreeData() 49 { 50 IList<SWT_UseCase_Module_Model> _infos; 51 StringBuilder jsonstr = new StringBuilder(); 52 53 if (Level == "-1") 54 { 55 //用例库顶级大节点,需要经权限筛选 56 _infos = UseCaseModule.GetListArray("UseCase", 1, _LoginUser, CaseType, ""); 57 //_infos = UseCaseModule.GetListArray("UseCase", _LoginUser); 58 } 59 else 60 { 61 //非用例库顶级大节点,无需权限筛选 62 //_infos = UseCaseModule.GetTreeData(Convert.ToInt64(ID)); 63 _infos = UseCaseModule.GetListArray(new string[] { "MODULE_FATHERID=" + ID }); 64 } 65 66 ///创建资讯树 67 string url = "ModuleContent.aspx?id="; 68 69 foreach (SWT_UseCase_Module_Model _mode in _infos) 70 { 71 //换行需要json转义 72 jsonstr.AppendFormat("{{\"id\":{0},\"name\":\"{1}\",\"pId\":{2},\"url\":\"{3}\",\"target\":\"{4}\"", _mode.Module_ID, _mode.Module_Name.Replace("\n", " ").Replace("\r", " "), _mode.Module_FatherID, url + _mode.Module_ID + "&Type="+CaseType, "mid_frame"); 73 if (UseCaseModule.ExistsBywhere("MODULE_FATHERID=" + _mode.Module_ID)) 74 { 75 jsonstr.Append(",isParent:true"); 76 } 77 jsonstr.Append("},"); 78 } 79 80 //移除最后一个, 81 if (jsonstr.ToString().EndsWith(",")) 82 { 83 jsonstr = jsonstr.Remove(jsonstr.Length-1, 1); 84 } 85 86 _infos = null; 87 Response.Write("["+jsonstr.ToString()+"]"); 88 89 }
2、用户搜索树控件
难点:ztree 在demo中的搜索只将搜索结果加粗显示 跟预期结果显示查询的结果不一致 解决这个问题,我采用的方式是将树清空 重新加载查询结果
主要是脚本页面
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function dblClickExpand(treeId, treeNode) { return treeNode.level > 0; } function filter(treeId, parentNode, childNodes) { if (!childNodes) return null; for (var i = 0, l = childNodes.length; i < l; i++) { childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.'); } return childNodes; } //查询 function search() { //搜索框为空时,重新绑定 if ($("#username").val() == "") { $.fn.zTree.init($("#tree"), setting()); return; } //异步加载 $.ajax({ url: "../Control/GetNodes.aspx", // url:"../Control/GetNodes.ashx", type: "post", dataType: "text", async: true, data: { "command": "GetSearchNodes", "group": $("input:radio:checked").val(), "username": $("#username").val() }, beforeSend: function () { $("#search").attr("disabled", "disabled").val("搜索中..."); }, success: function (data) { //eval将返回来的json字符串转换成json对象 var json = eval(data); $.fn.zTree.init($("#tree"), setting(), json); }, error: function (textStatus, errorThrown) { //请求出错处理 alert("错误:" + textStatus + errorThrown.toString()); }, complete: function () { $("#search").attr("disabled", "").val("搜索"); } }); } //动态添加的元素不会有加载原来的脚本的事件 需要手动添加onclick事件 function deleteNodes(btnDelete) { //parents过滤 $(btnDelete).parents("li").remove(); } function beforeClick(treeId, treeNode) { var check = (treeNode && !treeNode.isParent); //如果是父节点单击打开子节点 if (!check) { var zTree = $.fn.zTree.getZTreeObj("tree"); zTree.expandNode(treeNode, null, true, true); } // alert("只能选择人员..."); return check; } function onClick(e, treeId, treeNode) { var zTree = $.fn.zTree.getZTreeObj("tree"), nodes = zTree.getSelectedNodes(), v = ""; nodes.sort(function compare(a, b) { return a.id - b.id; }); for (var i = 0, l = nodes.length; i < l; i++) { //cursor:pointer; CSS 2.0 标准 google支持 v += "<li><span style='cursor:pointer;'><div class='selectednodes' onclick='deleteNodes(this)'>" + nodes[i].name + "<div></span></li>"; } if (v.length > 0) v = v.substring(0, v.length - 1); var SelectedObj = $("#selected"); SelectedObj.html(SelectedObj.html() + v); } //将设置转换成函数 --好处:设置参数里面有变量 ,可以定时获取最新的 function setting() { var setting = { data: { view: { dblClickExpand: false }, simpleData: { enable: true } }, async: { enable: true, // url:"../Control/GetNodes.ashx", url: "../Control/GetNodes.aspx", autoParam: ["id", "name", "level"], otherParam: { "otherParam": "zTreeAsyncTest", "command": "GetChildrenNodes", "group": $("input:radio:checked").val(), "username": $("#username").val() }, dataFilter: filter }, callback: { beforeClick: beforeClick, onClick: onClick } }; return setting; } $(document).ready(function () { //过滤掉其他没用的enter // document.onkeydown = function () { // if (event.srcElement.type != 'button' && // event.srcElement.type != 'image' && event.srcElement.type != 'submit' // && event.srcElement.type != 'textarea' && event.keyCode == 13) // { event.keyCode = 9; } // } $(document).keydown(function () { if (event.srcElement.type != 'button' && event.srcElement.type != 'image' && event.srcElement.type != 'submit' && event.srcElement.type != 'textarea' && event.keyCode == 13) { event.keyCode = 9; } }); //初始化 $.fn.zTree.init($("#tree"), setting()); //查询 $("#search").click(function () { search(); // if ($("#username").val() == "") { $.fn.zTree.init($("#tree"), setting()); return; } // $.fn.zTree.init($("#tree"), setting()); // var zTree = $.fn.zTree.getZTreeObj("tree"); //异步加载全部 }); $("#username").keydown(function () { if (event.keyCode == 13) { search(); } }); $("#btnOK").click(function () { $("#hidden").val($("#selected").text().replace(/\.n/g, '').replace(" ", ',')); alert($("#selected").text().replace(/\.n/g, '').replace(" ", ',')); }); $("input:radio").change(function () { //重置成空 $("#username").val(""); $("#selected").html(""); //重新加载 $.fn.zTree.init($("#tree"), setting()); }); });
Html页面
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<fieldset style="width: 700px"> <div> <input id="MIDH" type="radio" name="group" value="1" />类别1 <input id="SYS" type="radio" name="group" value="2" checked="checked" />类别2 </div> <div> <input type="text" style="float: left" id="username" /> <input type="button" value="搜索" id="search" /> <ul id="tree" class="ztree" style="float: left"> </ul> <ul id="selected" class="ztree" style="float: left"> </ul> </div> </fieldset> <br /> <input type="button" id="btnOK" value="确定" /> <input type="hidden" id="hidden" />
以上是我个人研究的一些东西写出来跟大家分享一下,有不合理的地方还望指正
作者:雨的点滴
出处:http://www.cnblogs.com/yudeyinji/articles/3488269.html
欢迎转载,但须保留版权