Home > Article > Web Front-end > jQuery implements recursive infinite layer function
This article mainly introduces the zTree search function - keyword query - related information on recursive infinite layers. It is very good and has reference value. Friends in need can refer to it
Nagging Yiha
Two days ago, a friend told me that he wanted a ztree search function, and I was slapped in the face: Is this method not done enough by countless predecessors? I went to find it myself, I was very busy~ Then I squatted silently and wrote the zTree search method. why? Because I said, "It's impossible to find it. Many people must have done it countless times. If you can't find it, I'll write it to you and ask you to have lunch." However, I searched for a long time and couldn't find it ( Tears, my plan, my lunch~). Most of them use getNodesByParamFuzzy() or highlighting in the API. However, friends said that the requirements are not met: 1. If the matching fails, the parent node is also hidden; 2. The matching rules can be customized, that is, it can match names and attributes... (Anyway, what I want is not spicy, Xiaosheng With a smile on my face, but in my heart...then I will write it for you~), enter the text below:
Mind Map
The general search function only matches keywords within the "established range (convenient name)". The "established range" means that we already know the search range: for example, a text library, a drop-down box , in other words, the size of our matching object set has been determined. However, this is not feasible on ztree. Why? When I thought about the implementation logic of the ztree search function, I asked: So, is the level of this tree fixed? Or are you not sure how many layers there are? The old man looked at me and smiled knowingly: You write in infinite layers~ Xiaosheng’s calf twitched. . Because the level of the tree is uncertain, the search range is uncertain. For example: the target node is matched successfully. If this node is a child node, then its parent node should also be displayed, and then the parent node of its parent node should also be Displayed, and then the parent node of its parent node's parent node... Orz... It seems that it will never end... There is no other way but to: recurse to find all the parent nodes and child nodes of the target node.
Key points of logic
In the above mind map, I roughly listed the logic, under what circumstances the target node is displayed, and what This is a key point that we must be clear about. Let’s take a closer look at the existence of the target node: The development of the search function has been clearly understood in the mind. The only thing left is the implementation method. However, this is not a problem at all~ (Xiaosheng secretly thinks that what is really worrying is that the process of the function is not clear. As for the implementation method, you all know it. Right? 0.0..)
About tree nodes To complete the various methods in the above process, we need to know a series of tree nodes Attributes, we all know that there is an artifact like API. However, one of the characteristics of API is that it is complete (so complete that when we want to accurately find a certain attribute or method, we may have a hard time searching). What we want here is how to quickly get ourselves For the desired attributes or methods, we print out the tree node set on the console:
var treeObj=$.fn.zTree.getZTreeObj("homeTree"); // 设置根节点
var node = treeObj.getNodes(); // 获取根节点
var nodes = treeObj.transformToArray(node); // 获取所有节点
console.log(nodes);
Looking at the picture: we can see all the nodes, including id, name and other attributes
Look at the picture again: we can see various attributes of any node, including the child node set we want, the parent node attribute isParent, the node id tId, the parent node id parentTid...
Everything is ready, get started
Let’s take a look at the relevant methods. Many small details need to be discovered during the actual coding process. For the convenience of display, they are listed here. method.
Declare the backup array:// 地区搜索 var parentArray = []; var childArray = [];Recursively obtain the set of parent nodes of the target node:
// 递归获取目标节点所有父节点 function getParentsNode(treeNode){ var thisParentNode = treeNode.getParentNode(); //得到该节点的父节点 if( thisParentNode != null ){ // 父节点存在 parentArray.push(thisParentNode); // 储存至数组 getParentsNode(thisParentNode); // 重调 }else{ return false; } }Recursively obtain the set of child nodes of the target node:
// 递归获取目标节点所有子节点 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; } }It is recommended here to Extract the matching node part and write a separate method to facilitate the expansion of matching rules. Here we assume that in addition to matching the name, we also need to match the entity_code attribute of the node:
//匹配节点 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; }Successful node matching method:
// 节点匹配成功 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(); } }Node Matching failure method:
// 节点匹配失败 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(); } }Target node matching failure The target node has both a parent node and a child node:
// 目标节点匹配失败 目标节点即有父节点又有子节点 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(); // 有一种匹配成功或都匹配成功 } }Define the search method:
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]); } } } }Call the search method:
// 调用搜索方法 $(".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); } });Look at the effect (there is a problem with the computer PS, so I used beautiful pictures to show off the pictures~囧...):
Conclusion
Theoretically speaking, it should be able to support unlimited layers. I tried up to four layers and there was no problem. , no more tests have been done, interested viewers can try it, and those who need a demo can leave a message, learn from each other, and make progress together
The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.
Related articles:
How to fix the header and first column in Vue
How to use the image annotation component in jquery.picsign
How to package the koa2 framework app through webpack? What should I do?
The above is the detailed content of jQuery implements recursive infinite layer function. For more information, please follow other related articles on the PHP Chinese website!