jQuery zTree搜索-关键字查询 递归无限层功能实现代码


Posted in jQuery onJanuary 25, 2018

 唠叨一哈

前两天朋友跟我说要一个ztree的搜索功能,我劈头就是一巴掌:这种方法难道无数前辈还做少了?自己去找,我很忙~然后我默默地蹲着写zTree的搜索方法去了。为什么呢?因为我说了句“找不到是不可能的啊,肯定有很多人早做了无数了,找不到我给你写还请你恰午饭”,然而我也去找了很久也没有找到(泪崩,我的计划,我的午饭~)。绝大多数都是用的API里面的getNodesByParamFuzzy()或者高亮之类的。然而朋友表示需求不符合:1. 匹配失败父节点也隐藏;2.能自定义匹配规则,即能匹配name还能匹配属性......(反正就是我想要的不是辣个,小生脸上笑嘻嘻,心里.......那我给你写呗~),下面进入正文:

思维导图

jQuery zTree搜索-关键字查询 递归无限层功能实现代码

一般搜索功能只是在“既定范围内(方便称呼)”匹配关键字,“既定范围”即我们已经知道搜索的范围:比如说一个文本库,一个下拉框,换而言之我们匹配的对象集大小已经确定了。然而这一点在ztree上不可行,为什么呢?在我考虑了一下ztree搜索功能实现逻辑的时候问了一句:那啥,这棵树的层级是固定的吗?还是说不确定有多少层?老哥看着我会心一笑:你按无限层来写~小生小腿肚子一抽。。因为树的层级不确定,所以搜索范围不确定,举个栗子:目标节点匹配成功,如果这个节点是子节点,那么它的父节点也应该是显示的,然后它父节点的父节点也应该是显示的,然后它父节点的父节点的父节点的...Orz...这仿佛永远写不到尽头了...没办法,只能:递归,找到目标节点的所有父节点和子节点。

逻辑关键点

在上面的思维导图中我大致列出了逻辑,目标节点在什么情况下显示,什么情况下隐藏,这是我们必须清楚的关键点,下面我们具体看下目标节点存在的情况:

jQuery zTree搜索-关键字查询 递归无限层功能实现代码

到了这里,相信对于如何实现满足我们需求的搜索功能开发,已经能做到了然于心了,剩下的只是实现的方法,然而这完全不是事~(小生窃以为真正让人忧心的理不清功能的流程,至于实现方法你们都懂的吧?0.0..)

关于树节点

要完成上述流程中各种方法,我们需要知道树节点的一系列属性,我们都知道有api这种神器,然而api有一个特点就是齐全(齐全得我们想精确的找到某一个属性或者方法时可能得一顿好找),这里我们想要的是如何快速得到自己想要的属性或者方法,我们在控制台打印出树节点集合: 

var treeObj=$.fn.zTree.getZTreeObj("homeTree"); // 设置根节点
  var node = treeObj.getNodes(); // 获取根节点
  var nodes = treeObj.transformToArray(node); // 获取所有节点
  console.log(nodes);

 

看图:我们能看到所有节点,其中有id,name等各种属性

jQuery zTree搜索-关键字查询 递归无限层功能实现代码

再看图:我们能看到任意节点的各种属性,有我们想要的子节点集合 childern,父节点属性 isParent ,节点id tId,父节点id parentTid...

jQuery zTree搜索-关键字查询 递归无限层功能实现代码

万事俱备,动手

下面看一下相关方法,很多小细节需要在真正编码过程中才能发现,这里为了方便展示就直接列举方法了。

声明备用数组:

// 地区搜索
 var parentArray = [];
 var childArray = [];

 

递归获取目标节点父节点集合:

// 递归获取目标节点所有父节点
 function getParentsNode(treeNode){
  var thisParentNode = treeNode.getParentNode(); //得到该节点的父节点
  if( thisParentNode != null ){ // 父节点存在
   parentArray.push(thisParentNode); // 储存至数组
   getParentsNode(thisParentNode); // 重调 
  }else{
   return false;
  }   
 }

 

递归获取目标节点子节点集合:

// 递归获取目标节点所有子节点
 function getChildrenNode(treeNode){
  var thisIsParent = treeNode.isParent; // 获取目标节点 isParent 属性,判断是否为父节点
  if( thisIsParent == true ){
   var thisChildrenNode = treeNode.children; // 得到该节点的子节点集合
   for(var i=0;i<thisChildrenNode.length;i++){
    childArray.push(thisChildrenNode[i]); // 将该子节点加入数组中
    getChildrenNode(thisChildrenNode[i]); // 重调  
   }
  }else{
   return false;
  }
 }

 

这里建议将匹配节点部分摘出来单独写一个方法,方便进行拓展匹配规则,这里我们假设除了匹配name还需要匹配节点的 entity_code 属性:

//匹配节点
 function matchNode(treeNode,num){
  var inputArea = $("input[name='searchArea']");
  var name = treeNode.name;
  var entityCode = treeNode.entity_code|| '';
  var val = inputArea.val(); // 获取检索值
  var numName = name.indexOf(val);
  var numCode = entityCode.indexOf(val);
  var num = -1;
  if( numName != -1 || numCode !=-1 ){
   num = 1;
  }
  if( numName == -1 && numCode == -1 ){
   num = -1; 
  }
  return num;
 }

 

节点匹配成功方法:

// 节点匹配成功
 function checkTrueArray(arr,treeNode){
  var thisTid = treeNode.tId;
  var thisLi = $("#"+thisTid);
  for(var n=0;n<arr.length;n++){
   var thisNodeId = arr[n].tId;
   var thisNodeLi = $("#"+thisNodeId);
   thisLi.show();
   thisNodeLi.show();
  }
 }

 

节点匹配失败方法:

// 节点匹配失败
 function checkFalseArray(arr,treeNode){
  var result = [];
  var result2 = [];
  var thisTid = treeNode.tId;
  var thisLi = $("#"+thisTid);
  var val = inputArea.val(); // 获取检索值
  var thisParent = treeNode.getParentNode(); // 获取目标节点父节点
  if( thisParent != null ){ // 有父节点
   var thisBrotherArr = treeNode.getParentNode().children; // 得到包含自身的兄弟数组
   for(var m=0;m<arr.length;m++){ // 匹配父节点
    var num = matchNode(arr[m]);
    if( num != -1 ){
     result.push(arr[m]);
    }
   }
   var resultLength = result.length;
   for( var m=0;m<thisBrotherArr.length;m++ ){ // 匹配兄弟节点
    var num = matchNode(thisBrotherArr[m]);
    if( num != -1 ){
     result2.push(thisBrotherArr[m]);
    }
   }
   var resultLength2 = result2.length;
   // 对于自身匹配失败的节点,要显示必须满足有父节点匹配成功,且兄弟级节点都匹配失败
   if( (resultLength == 0 && resultLength2 == 0) || resultLength2 != 0 ){
    thisLi.hide();
   }
   if( resultLength !=0 && resultLength2 == 0 ){
    thisLi.show();
   }
  }else{
   thisLi.hide();
  } 
 }

 

目标节点匹配失败 目标节点即有父节点又有子节点:

// 目标节点匹配失败 目标节点即有父节点又有子节点
 function checkAllArray(arr,arr2,treeNode){
  var result = [];
  var result2 = [];
  var thisTid = treeNode.tId;
  var thisLi = $("#"+thisTid);
  var val = inputArea.val(); // 获取检索值
  for(var m=0;m<arr.length;m++){ // 匹配子节点或父节点
   var num = matchNode(arr[m]);
   if( num != -1 ){
    result.push(arr[m]); // 匹配成功储存至数组
   }
  }
  var resultLength = result.length; // 获取匹配成功后返回的数组长度
  for(var m=0;m<arr2.length;m++){ // 匹配子节点或父节点
   var num = matchNode(arr2[m]);
   if( num != -1 ){
    result2.push(arr2[m]); // 匹配成功储存至数组
   }
  }
  var resultLength2 = result2.length; // 获取匹配成功后返回的数组长度
  if( resultLength == 0 && resultLength2 == 0 ){ // 子节点和父节点都匹配失败
   thisLi.hide();
  }else{ 
   thisLi.show(); // 有一种匹配成功或都匹配成功
  }
 }

定义搜索方法:

function searchArea(treeId, treeNode){ // 定义搜索方法
  var inputArea = $("input[name='searchArea']");
  var val = inputArea.val(); // 获取检索值
  var treeObj=$.fn.zTree.getZTreeObj("homeTree"); // 设置根节点
  var node = treeObj.getNodes(); // 获取根节点
  var nodes = treeObj.transformToArray(node); // 获取所有节点
  console.log(nodes);
  for(var i=0;i<nodes.length;i++){
   var thisNodePid = nodes[i].pId;
   var thisParentNode = 
   parentArray = [];
   childArray = [];
   getParentsNode(nodes[i]); // 获取目标节点所有父节点 返回数组
   getChildrenNode(nodes[i]); // 获取目标节点所有子节点 返回数组
   var num = matchNode(nodes[i]);
   if( nodes[i].isParent == false ){ 
    if( num != -1 ){
     checkTrueArray(parentArray,nodes[i]);
    }else{
     checkFalseArray(parentArray,nodes[i]);
    }
   }
   if( nodes[i].isParent == true ){
    if( num != -1 ){
     checkTrueArray(parentArray,nodes[i]); 
     checkTrueArray(childArray,nodes[i]);     
    }else{
     checkAllArray(parentArray,childArray,nodes[i]);
    }
   }   
  }
  
 }

调用搜索方法:

// 调用搜索方法
 $(".searchAreaBtn").click(function(treeId, treeNode){
  searchArea(treeId, treeNode);
 });
 var inputArea = $("input[name='searchArea']");
 inputArea.keyup(function(treeId, treeNode,e){
  var e = event || window.event;
  var val = inputArea.val();
  if( e.keyCode == 13 || val == "" ){
   searchArea(treeId, treeNode);
  }
 });

 

看效果(电脑ps出问题了,用美图秀秀拼的图~??..):

jQuery zTree搜索-关键字查询 递归无限层功能实现代码

结语

理论上来说应该是能支持无限层的,最多试了四层,没有问题,没有做更多测试,有兴趣的看官可以试试,需要demo的可以留言,互相学习,一起进步,么么哒~

总结

以上所述是小编给大家介绍的jQuery zTree搜索-关键字查询 递归无限层功能实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

jQuery 相关文章推荐
jquery 禁止鼠标右键并监听右键事件
Apr 27 jQuery
Jquery获取radio选中的值
May 05 jQuery
jquery实现简单实用的轮播器
May 23 jQuery
Angular2使用jQuery的方法教程
May 28 jQuery
bootstrap+jQuery 实现下拉菜单中复选框全选和全不选效果
Jun 12 jQuery
jQuery实现的简单动态添加、删除表格功能示例
Sep 21 jQuery
jQuery实现手机号正则验证输入及自动填充空格功能
Jan 02 jQuery
jQuery实现form表单序列化转换为json对象功能示例
May 23 jQuery
AJAX在JQuery中的应用详解
Jan 30 jQuery
jQuery内容选择器与表单选择器实例分析
Jun 28 jQuery
jQuery实现倒计时功能完整示例
Jun 01 jQuery
jquery实现拖拽小方块效果
Dec 10 jQuery
使用Ajax和Jquery配合数据库实现下拉框的二级联动的示例
Jan 25 #jQuery
解决Jquery下拉框数据动态获取的问题
Jan 25 #jQuery
jquery 获取索引值在一定范围的列表方法
Jan 25 #jQuery
jquery 输入框查找关键字并提亮颜色的实例代码
Jan 23 #jQuery
js和jQuery以及easyui实现对下拉框的指定赋值方法
Jan 23 #jQuery
jquery在启动页面时,自动加载数据的实例
Jan 22 #jQuery
浅谈ajax在jquery中的请求和servlet中的响应
Jan 22 #jQuery
You might like
DIY一个适配电脑声卡的动圈话筒放大器
2021/03/02 无线电
动态网站web开发 PHP、ASP还是ASP.NET
2006/10/09 PHP
配置php.ini实现PHP文件上传功能
2014/11/27 PHP
php创建多级目录的方法
2015/03/24 PHP
php计算整个目录大小的方法
2015/06/19 PHP
JavaScript中使用构造器创建对象无需new的情况说明
2012/03/01 Javascript
js限制文本框只能输入数字方法小结
2014/06/16 Javascript
百度UEditor编辑器如何关闭抓取远程图片功能
2015/03/03 Javascript
AngularJs入门教程之环境搭建+创建应用示例
2016/11/01 Javascript
javascript数组去重方法分析
2016/12/15 Javascript
jQuery的三种bind/One/Live/On事件绑定使用方法
2017/02/23 Javascript
vue子父组件通信的实现代码
2017/07/09 Javascript
element-ui中select组件绑定值改变,触发change事件方法
2018/08/24 Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
2020/08/10 Javascript
three.js着色器材质的内置变量示例详解
2020/08/16 Javascript
[03:02]2014DOTA2西雅图邀请赛 让队员自己告诉你DK NAVI备战情况
2014/07/08 DOTA
老生常谈进程线程协程那些事儿
2017/07/24 Python
tensorflow 获取变量&amp;打印权值的实例讲解
2018/06/14 Python
Django使用redis缓存服务器的实现代码示例
2019/04/28 Python
Python不支持 i ++ 语法的原因解析
2020/07/22 Python
python输出国际象棋棋盘的实例分享
2020/11/26 Python
详解移动端html5页面长按实现高亮全选文本内容的兼容解决方案
2016/12/03 HTML / CSS
HTML5 Canvas 实现K线图的示例代码
2019/12/23 HTML / CSS
军训的自我鉴定
2013/12/10 职场文书
建筑工程管理专业自荐信范文
2013/12/28 职场文书
优秀护士演讲稿
2014/04/30 职场文书
文员求职信
2014/07/15 职场文书
2014年“四风”问题个人整改措施
2014/09/17 职场文书
地震慰问信
2015/02/14 职场文书
2015年教师学期工作总结
2015/04/30 职场文书
2015年体育教师个人工作总结
2015/05/12 职场文书
一文帮你理解PReact10.5.13源码
2021/04/03 Javascript
MySQL REVOKE实现删除用户权限
2021/06/18 MySQL
详解 TypeScript 枚举类型
2021/11/02 Javascript
Python if else条件语句形式详解
2022/03/24 Python
使用Postman测试需要授权的接口问题
2022/06/21 Java/Android