视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
jQuery zTree搜索-关键字查询 递归无限层功能实现代码
2020-11-27 22:21:12 责编:小采
文档

 唠叨一哈

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

思维导图

  

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

逻辑关键点

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

  

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

关于树节点

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

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

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

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

万事俱备,动手

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

  声明备用数组:

// 地区搜索
 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出问题了,用美图秀秀拼的图~囧...):

结语

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

总结

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

下载本文
显示全文
专题