ホームページ  >  記事  >  ウェブフロントエンド  >  jQueryは再帰的な無限層関数を実装します

jQueryは再帰的な無限層関数を実装します

亚连
亚连オリジナル
2018-06-09 14:51:371545ブラウズ

この記事は、zTree 検索機能 - キーワード クエリ - 再帰的無限レイヤーに関する情報を主に紹介します。非常に優れており、必要な友人は参考にすることができます

2 日間雑談します。以前、友人が ztree 検索機能が欲しいと私に言いました。私は即座に「この方法は無数の先人たちによって十分に行われていないのではないか?」とたたきつけられました。私は自分で探しに行きました、とても忙しかったです〜 それから私は黙ってしゃがんでzTreeの検索方法を書きました。なぜ?というのは、「見つけるのは不可能です。何度もやった人はたくさんいるはずです。もし見つからなかったら、手紙を書いて昼食に誘ってください。」と言いましたが、私は探しました。長い間探しても見つからなかった(涙、計画、ランチ~)。それらのほとんどは、API で getNodesByParamFuzzy() またはハイライトを使用します。しかし、友人たちは次の要件を満たしていないと言っていました。 1. マッチングが失敗した場合、親ノードも非表示になります。 2. マッチング ルールはカスタマイズ可能です。つまり、名前と属性を一致させることができます。私が欲しいのは辛くない、Xiaosheng 顔に笑顔を浮かべて、そして心の中で...それなら私があなたのためにそれを書きます~)、テキストを入力しましょう:

マインドマップ

一般検索機能は、キーワードと一致する「確立された範囲(便利な「名前」)」内のみであり、「確立された範囲」とは、検索の範囲がすでにわかっていることを意味します。たとえば、テキスト ライブラリ、ドロップダウン ボックス、言い換えれば、一致するオブジェクト セットのサイズが決定されました。しかし、これは ztree では実現できません。なぜでしょうか? ztree 検索機能の実装ロジックを考えたとき、「では、このツリーのレベルは固定されているのでしょうか?」と疑問に思いました。それとも何層あるのかわかりませんか?兄は私を見て、わざとらしく微笑んだ。「あなたは無限の層で書くんですね~」シャオシェンのふくらはぎがピクピクと動きました。 。ツリーのレベルが不定であるため、検索範囲も不定です。たとえば、このノードが子ノードの場合は、その親ノードも表示され、その親ノードの親ノードも表示されます。も表示され、その親ノードの親ノードも表示されます...orz... 永遠に終わらない気がします... 再帰ですべての親ノードと子ノードを探すしかありません。ターゲットノード。

ロジックの要点

上記のマインドマップでは、対象のノードがどのような状況で表示され、どのような状況で非表示になるのかというロジックを大まかに列挙しました。以下でターゲットノードの存在を見てみましょう:

この時点で、残りのニーズを満たす検索機能の開発を実装する方法を明確に理解できたと思います。は単なる実装方法ですが、これはまったく問題ありません。 ~ (Xiaosheng は、不明瞭な関数のプロセスが非常に心配だと密かに考えています。実装方法については、皆さん知っていますか? 0.0..)

ツリーノードについて

上記のプロセスでさまざまなメソッドを実行するには、API のようなアーティファクトがあることは誰もが知っています。 complete (非常に完全なので、特定の属性またはメソッドを正確に見つけたいときに、見つけるのが難しい場合があります) ここで必要なのは、必要な属性またはメソッドを迅速に取得する方法です。ツリー ノードを出力します。コンソールで設定します:

 var treeObj=$.fn.zTree.getZTreeObj("homeTree"); // 设置根节点
  var node = treeObj.getNodes(); // 获取根节点
  var nodes = treeObj.transformToArray(node); // 获取所有节点
  console.log(nodes);
画像を見る: ID、名前、その他の属性を含むすべてのノードが表示されます

もう一度画像を見てください: ノードのさまざまな属性を確認できます。必要な子ノード セット、親ノード属性 isParent、ノード ID tId、親ノード IDparentTid...

すべてが完了しました。準備を整えて、始めましょう

関連するメソッドを見てみましょう。細部については、実際のコーディング プロセス中に確認する必要があります。便宜上、その方法をここに示します。

予備配列を宣言する:

// 地区搜索
 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;
  }
 }

一致するノード部分を抽出して、マッチングルールの拡張を容易にするための別のメソッドを作成します。ここでは、名前のマッチングに加えて、ノードのentity_code属性もマッチングする必要があると仮定します:

 //匹配节点
 function matchNode(treeNode,num){
  var inputArea = $("input[name=&#39;searchArea&#39;]");
  var name = treeNode.name;
  var entityCode = treeNode.entity_code|| &#39;&#39;;
  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=&#39;searchArea&#39;]");
  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=&#39;searchArea&#39;]");
 inputArea.keyup(function(treeId, treeNode,e){
  var e = event || window.event;
  var val = inputArea.val();
  if( e.keyCode == 13 || val == "" ){
   searchArea(treeId, treeNode);
  }
 });

効果を見てください(コンピューターの問題です PS、写真をまとめるのに Meitu Xiu Xiu を使いました~囧...):

結論

理論的には、最大 4 つのレイヤーをサポートできるはずですが、これ以上のテストは行われませんでした。興味のある方は試してみてください。メッセージを残して、お互いに学び、一緒に進歩しましょう

上記は私がまとめたもので、将来的に皆さんのお役に立てれば幸いです。

関連記事:

Vue でテーブルのヘッダーと最初の列を修正する方法

jquery.picsign で画像注釈コンポーネントを使用する方法

webpack を介して koa2 フレームワーク アプリをパッケージ化する方法、何をすべきか私はします?

以上がjQueryは再帰的な無限層関数を実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。