欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-08-27 12:09:58
 唠叨一哈   前两天朋友跟我说要一个ztree的搜索功能,我劈头就是一巴掌:这种方法难道无数前辈还做少了?自己去找,我很忙~然后我默默地蹲着写ztree的搜索...

 唠叨一哈

  前两天朋友跟我说要一个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搜索-关键字查询 递归无限层功能实现代码,希望对大家有所帮助