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实现tab选项卡切换效果(悬停、下方横线动画位移)
May 05 jQuery
jQuery+PHP+Mysql实现抽奖程序
Apr 12 jQuery
jQuery菜单实例(全选,反选,取消)
Aug 28 jQuery
jQuery实现倒计时功能 jQuery实现计时器功能
Sep 19 jQuery
认识jQuery的Promise的具体使用方法
Oct 10 jQuery
手写简单的jQuery雪花飘落效果实例
Apr 22 jQuery
jquery分页插件pagination使用教程
Oct 23 jQuery
jQuery pager.js 插件动态分页功能实例分析
Aug 02 jQuery
jQuery/JS监听input输入框值变化实例
Oct 17 jQuery
Javascript和jquery在selenium的使用过程
Oct 31 jQuery
jQuery使用ajax传递json对象到服务端及contentType的用法示例
Mar 12 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
详解WordPress开发中的get_post与get_posts函数使用
2016/01/04 PHP
解决Laravel5.x的php artisan migrate数据库迁移创建操作报错SQLSTATE[42000]
2020/04/06 PHP
Javascript 作用域使用说明
2009/08/13 Javascript
JS去除字符串的空格增强版(可以去除中间的空格)
2009/08/26 Javascript
读jQuery之一(对象的组成)
2011/06/11 Javascript
获取客户端网卡MAC地址和IP地址实现JS代码
2013/03/17 Javascript
基于JavaScript创建动态Dom
2015/12/08 Javascript
JS Canvas定时器模拟动态加载动画
2016/09/17 Javascript
KnockoutJS 3.X API 第四章之表单value绑定
2016/10/10 Javascript
Mui使用jquery并且使用点击跳转新窗口的实例
2017/08/19 jQuery
Layui数据表格之获取表格中所有的数据方法
2018/08/20 Javascript
js中位运算的运用实例分析
2018/12/11 Javascript
vue tab切换,解决echartst图表宽度只有100px的问题
2020/07/19 Javascript
Vue Render函数原理及代码实例解析
2020/07/30 Javascript
JavaScript数组排序的六种常见算法总结
2020/08/18 Javascript
[00:09]DOTA2全国高校联赛 精彩活动引爆全场
2018/05/30 DOTA
[38:54]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第一场 11.28
2020/12/01 DOTA
Python图片裁剪实例代码(如头像裁剪)
2017/06/21 Python
微信跳一跳小游戏python脚本
2018/01/05 Python
对Python字符串中的换行符和制表符介绍
2018/05/03 Python
Python可迭代对象操作示例
2019/05/07 Python
python判断无向图环是否存在的示例
2019/11/22 Python
python误差棒图errorbar()函数实例解析
2020/02/11 Python
django执行原始查询sql,并返回Dict字典例子
2020/04/01 Python
在TensorFlow中实现矩阵维度扩展
2020/05/22 Python
欧铁通票官方在线销售网站:Eurail.com
2017/10/14 全球购物
网络工程与软件技术毕业生自荐信
2013/09/24 职场文书
人事主管岗位职责范本
2013/12/04 职场文书
关于毕业的广播稿
2014/01/10 职场文书
物流专业大学的自我评价
2014/01/11 职场文书
优秀员工评优方案
2014/06/13 职场文书
党员群众路线对照检查材料思想汇报
2014/09/17 职场文书
2014年大学生职业规划书:未来不是梦,只要勇敢冲!
2014/09/22 职场文书
小学班主任评语
2014/12/29 职场文书
安全教育培训心得体会
2016/01/15 职场文书
分析设计模式之模板方法Java实现
2021/06/23 Java/Android