jQuery zTree搜索-關鍵字查詢 遞歸無限層功能實現(xiàn)代碼
嘮叨一哈
前兩天朋友跟我說要一個ztree的搜索功能,我劈頭就是一巴掌:這種方法難道無數(shù)前輩還做少了?自己去找,我很忙~然后我默默地蹲著寫zTree的搜索方法去了。為什么呢?因為我說了句“找不到是不可能的啊,肯定有很多人早做了無數(shù)了,找不到我給你寫還請你恰午飯”,然而我也去找了很久也沒有找到(淚崩,我的計劃,我的午飯~)。絕大多數(shù)都是用的API里面的getNodesByParamFuzzy()或者高亮之類的。然而朋友表示需求不符合:1. 匹配失敗父節(jié)點也隱藏;2.能自定義匹配規(guī)則,即能匹配name還能匹配屬性......(反正就是我想要的不是辣個,小生臉上笑嘻嘻,心里.......那我給你寫唄~),下面進入正文:
思維導圖
一般搜索功能只是在“既定范圍內(nèi)(方便稱呼)”匹配關鍵字,“既定范圍”即我們已經(jīng)知道搜索的范圍:比如說一個文本庫,一個下拉框,換而言之我們匹配的對象集大小已經(jīng)確定了。然而這一點在ztree上不可行,為什么呢?在我考慮了一下ztree搜索功能實現(xiàn)邏輯的時候問了一句:那啥,這棵樹的層級是固定的嗎?還是說不確定有多少層?老哥看著我會心一笑:你按無限層來寫~小生小腿肚子一抽。。因為樹的層級不確定,所以搜索范圍不確定,舉個栗子:目標節(jié)點匹配成功,如果這個節(jié)點是子節(jié)點,那么它的父節(jié)點也應該是顯示的,然后它父節(jié)點的父節(jié)點也應該是顯示的,然后它父節(jié)點的父節(jié)點的父節(jié)點的...Orz...這仿佛永遠寫不到盡頭了...沒辦法,只能:遞歸,找到目標節(jié)點的所有父節(jié)點和子節(jié)點。
邏輯關鍵點
在上面的思維導圖中我大致列出了邏輯,目標節(jié)點在什么情況下顯示,什么情況下隱藏,這是我們必須清楚的關鍵點,下面我們具體看下目標節(jié)點存在的情況:
到了這里,相信對于如何實現(xiàn)滿足我們需求的搜索功能開發(fā),已經(jīng)能做到了然于心了,剩下的只是實現(xiàn)的方法,然而這完全不是事~(小生竊以為真正讓人憂心的理不清功能的流程,至于實現(xiàn)方法你們都懂的吧?0.0..)
關于樹節(jié)點
要完成上述流程中各種方法,我們需要知道樹節(jié)點的一系列屬性,我們都知道有api這種神器,然而api有一個特點就是齊全(齊全得我們想精確的找到某一個屬性或者方法時可能得一頓好找),這里我們想要的是如何快速得到自己想要的屬性或者方法,我們在控制臺打印出樹節(jié)點集合:
var treeObj=$.fn.zTree.getZTreeObj("homeTree"); // 設置根節(jié)點 var node = treeObj.getNodes(); // 獲取根節(jié)點 var nodes = treeObj.transformToArray(node); // 獲取所有節(jié)點 console.log(nodes);
看圖:我們能看到所有節(jié)點,其中有id,name等各種屬性
再看圖:我們能看到任意節(jié)點的各種屬性,有我們想要的子節(jié)點集合 childern,父節(jié)點屬性 isParent ,節(jié)點id tId,父節(jié)點id parentTid...
萬事俱備,動手
下面看一下相關方法,很多小細節(jié)需要在真正編碼過程中才能發(fā)現(xiàn),這里為了方便展示就直接列舉方法了。
聲明備用數(shù)組:
// 地區(qū)搜索 var parentArray = []; var childArray = [];
遞歸獲取目標節(jié)點父節(jié)點集合:
// 遞歸獲取目標節(jié)點所有父節(jié)點 function getParentsNode(treeNode){ var thisParentNode = treeNode.getParentNode(); //得到該節(jié)點的父節(jié)點 if( thisParentNode != null ){ // 父節(jié)點存在 parentArray.push(thisParentNode); // 儲存至數(shù)組 getParentsNode(thisParentNode); // 重調(diào) }else{ return false; } }
遞歸獲取目標節(jié)點子節(jié)點集合:
// 遞歸獲取目標節(jié)點所有子節(jié)點 function getChildrenNode(treeNode){ var thisIsParent = treeNode.isParent; // 獲取目標節(jié)點 isParent 屬性,判斷是否為父節(jié)點 if( thisIsParent == true ){ var thisChildrenNode = treeNode.children; // 得到該節(jié)點的子節(jié)點集合 for(var i=0;i<thisChildrenNode.length;i++){ childArray.push(thisChildrenNode[i]); // 將該子節(jié)點加入數(shù)組中 getChildrenNode(thisChildrenNode[i]); // 重調(diào) } }else{ return false; } }
這里建議將匹配節(jié)點部分摘出來單獨寫一個方法,方便進行拓展匹配規(guī)則,這里我們假設除了匹配name還需要匹配節(jié)點的 entity_code 屬性:
//匹配節(jié)點 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; }
節(jié)點匹配成功方法:
// 節(jié)點匹配成功 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(); } }
節(jié)點匹配失敗方法:
// 節(jié)點匹配失敗 function checkFalseArray(arr,treeNode){ var result = []; var result2 = []; var thisTid = treeNode.tId; var thisLi = $("#"+thisTid); var val = inputArea.val(); // 獲取檢索值 var thisParent = treeNode.getParentNode(); // 獲取目標節(jié)點父節(jié)點 if( thisParent != null ){ // 有父節(jié)點 var thisBrotherArr = treeNode.getParentNode().children; // 得到包含自身的兄弟數(shù)組 for(var m=0;m<arr.length;m++){ // 匹配父節(jié)點 var num = matchNode(arr[m]); if( num != -1 ){ result.push(arr[m]); } } var resultLength = result.length; for( var m=0;m<thisBrotherArr.length;m++ ){ // 匹配兄弟節(jié)點 var num = matchNode(thisBrotherArr[m]); if( num != -1 ){ result2.push(thisBrotherArr[m]); } } var resultLength2 = result2.length; // 對于自身匹配失敗的節(jié)點,要顯示必須滿足有父節(jié)點匹配成功,且兄弟級節(jié)點都匹配失敗 if( (resultLength == 0 && resultLength2 == 0) || resultLength2 != 0 ){ thisLi.hide(); } if( resultLength !=0 && resultLength2 == 0 ){ thisLi.show(); } }else{ thisLi.hide(); } }
目標節(jié)點匹配失敗 目標節(jié)點即有父節(jié)點又有子節(jié)點:
// 目標節(jié)點匹配失敗 目標節(jié)點即有父節(jié)點又有子節(jié)點 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++){ // 匹配子節(jié)點或父節(jié)點 var num = matchNode(arr[m]); if( num != -1 ){ result.push(arr[m]); // 匹配成功儲存至數(shù)組 } } var resultLength = result.length; // 獲取匹配成功后返回的數(shù)組長度 for(var m=0;m<arr2.length;m++){ // 匹配子節(jié)點或父節(jié)點 var num = matchNode(arr2[m]); if( num != -1 ){ result2.push(arr2[m]); // 匹配成功儲存至數(shù)組 } } var resultLength2 = result2.length; // 獲取匹配成功后返回的數(shù)組長度 if( resultLength == 0 && resultLength2 == 0 ){ // 子節(jié)點和父節(jié)點都匹配失敗 thisLi.hide(); }else{ thisLi.show(); // 有一種匹配成功或都匹配成功 } }
定義搜索方法:
function searchArea(treeId, treeNode){ // 定義搜索方法 var inputArea = $("input[name='searchArea']"); var val = inputArea.val(); // 獲取檢索值 var treeObj=$.fn.zTree.getZTreeObj("homeTree"); // 設置根節(jié)點 var node = treeObj.getNodes(); // 獲取根節(jié)點 var nodes = treeObj.transformToArray(node); // 獲取所有節(jié)點 console.log(nodes); for(var i=0;i<nodes.length;i++){ var thisNodePid = nodes[i].pId; var thisParentNode = parentArray = []; childArray = []; getParentsNode(nodes[i]); // 獲取目標節(jié)點所有父節(jié)點 返回數(shù)組 getChildrenNode(nodes[i]); // 獲取目標節(jié)點所有子節(jié)點 返回數(shù)組 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]); } } } }
調(diào)用搜索方法:
// 調(diào)用搜索方法 $(".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出問題了,用美圖秀秀拼的圖~囧...):
結(jié)語
理論上來說應該是能支持無限層的,最多試了四層,沒有問題,沒有做更多測試,有興趣的看官可以試試,需要demo的可以留言,互相學習,一起進步,么么噠~
總結(jié)
以上所述是小編給大家介紹的jQuery zTree搜索-關鍵字查詢 遞歸無限層功能實現(xiàn)代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
JS 遍歷 json 和 JQuery 遍歷json操作完整示例
這篇文章主要介紹了JS 遍歷 json 和 JQuery 遍歷json操作,結(jié)合完整實例形式詳細分析了JavaScript與jQuery遍歷json格式數(shù)據(jù)的簡單實現(xiàn)技巧,需要的朋友可以參考下2019-11-11淺談JSON和JSONP區(qū)別及jQuery的ajax jsonp的使用
文章從JSON和JSONP區(qū)別開始講起,用實例來對比他們之間的不同之處,然后詳細講解了jQuery中的ajax jsonp的使用并給出了示例及詳細參數(shù)說明。這里推薦給大家,希望對小伙伴能有所幫助2014-11-11淺析jQuery 遍歷函數(shù),javascript中的each遍歷
下面小編就為大家?guī)硪黄獪\析jQuery 遍歷函數(shù),javascript中的each遍歷。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05Jquery揭秘系列:ajax原生js實現(xiàn)詳解(推薦)
下面小編就為大家?guī)硪黄狫query揭秘系列:ajax原生js實現(xiàn)詳解(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06BootStrap中jQuery插件Carousel實現(xiàn)輪播廣告效果
輪播廣告在網(wǎng)站中的應用實在是太常見了,下面說一說怎樣使用bootstrap中的Carousel插件來實現(xiàn)輪播廣告效果,感興趣的朋友一起看看吧2017-03-03jQuery遍歷DOM節(jié)點操作之filter()方法詳解
這篇文章主要介紹了jQuery遍歷DOM節(jié)點操作之filter()方法,結(jié)合實例形式詳細分析了filter的功能及4種具體用法,需要的朋友可以參考下2016-04-04