亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 3 層菜單過濾結果列表

使用 3 層菜單過濾結果列表

慕田峪7331174 2022-01-13 16:30:10
我有 3 個單獨的菜單。如果從該特定菜單中未選擇任何內容,則它們都默認為“全部”。菜單項是過濾器,您可以從每個菜單中選擇任意數量的過濾器。當點擊過濾器時,這將構建 3 個包含所選項目的數組(請參見下文)。每個菜單中的過濾器都鏈接或包含到其他菜單,因此結果必須滿足所有選定的過濾器,否則它會被禁用類。我已經成功編寫了 JS 來處理每個菜單的行為,因此使用 css 類突出顯示選定的菜單項/過濾器。所以這一切都很好。我遇到的問題是當我嘗試過濾結果時。當它們被單擊時,它們會填充來自菜單過濾器的值,如果單擊過濾器兩次,則該項目將從數組中刪除。隨著這些數組的變化,我正在調用一個函數來更新結果。所以上面的更新函數只有在所有數組都有項目時才有效。所以我開始向上述條件添加進一步的邏輯,開始檢查每個數組是否有項目,如果他們沒有忽略它們,只是根據其他的過濾。顯然,這會導致有進一步的邏輯來檢查 3 個數組中的 2 個是否為空,等等。我覺得必須有更好的方法來做到這一點,而無需數十個嵌套的 if else 語句。也許我需要從完全不同的方式接近。非常感謝任何幫助。謝謝。
查看完整描述

1 回答

?
牧羊人nacy

TA貢獻1862條經驗 獲得超7個贊

在我添加我的解決方案之前,我必須感謝@ffriend和他的函數來找出兩個或多個數組中的所有組合(為此給他+1 ;)):Finding All Combinations (Cartesian product) of JavaScript array values


這個功能非常有用,我在我的解決方案中使用了。


這是針對您的問題的不同方法,因此我當然必須更改您的 HTML 和 jQuery。


首先是HTML。為了創建與您相同的過濾器系統,我決定只使用沒有任何特定屬性的類:


<div class="results">

   <div class="Series-1 Body-1 Style-1">Result 1</div>

   <div class="Series-1 Body-1 Style-1">Result 2</div>

   <div class="Series-2 Body-2 Style-2">Result 3</div>

   <div class="Series-2 Body-1 Style-2">Result 4</div>

   <div class="Series-3 Body-1 Style-1">Result 5</div>

   <div class="Series-3 Body-1 Style-1">Result 6</div>

   <div class="Series-3 Body-2 Style-2">Result 7</div>

   <div class="Series-2 Body-1 Style-3">Result 8</div>

</div>

...我創建了與所有導航列表的關系(也使用dot)


<ul class="nav" data-obj="series">

  <li data-el="*" class="selected">All</li>

  <li data-el=".Series-1">Series 1</li>

  <li data-el=".Series-2">Series 2</li>

  <li data-el=".Series-3">Series 3</li>

</ul>


<ul class="nav" data-obj="body">

  <li data-el="*" class="selected">All</li>

  <li data-el=".Body-1">Body 1</li>

  <li data-el=".Body-2">Body 2</li>

  <li data-el=".Body-3">Body 3</li>

</ul>


<ul class="nav" data-obj="style">

  <li data-el="*" class="selected">All</li>

  <li data-el=".Style-1">Style 1</li>

  <li data-el=".Style-2">Style 2</li>

  <li data-el=".Style-3">Style 3</li>

</ul>

在您的 CSS 中,我只刪除了.disabled該類,因為我使用 jQuery 來做到這一點。


現在是javascript。我已經評論了我認為重要的部分,以試圖澄清所有步驟:


/* I created one js object instead of 3 arrays, 'cause it is more simple to handle after in one general function */

var results = {

  series:[],

  body:[],

  style:[]

};


/* put the results containet in a variable */

var container=$(".results");


$(".nav li").on('click', function(){

  /*this is the general function that works for all your clicks */  


  /*set a few of variables */

  var $this=$(this);

  var parent=$this.parent();

  var parentObj=$this.parent().data("obj");

  var myClass=$this.data("el");

  var control=[]; /*this is an empty array that will set with your different classes*/


  if(myClass==="*") {

    /*click on first li*/

    if (!$this.hasClass("selected")) {

        /*do something if it didin't have the selected class*/

      $("li", parent).removeClass("selected"); /*remove selected classes from all li in my parent ul*/

      $this.addClass("selected");

      results[parentObj]=[];/* empty my associative object: series, body or style */

    }

  } else {

    /*click on the others li*/

    $("li[data-el='*']", parent).removeClass("selected"); 


    if ($this.hasClass("selected")) {

        /*click on li with selected class */

      $this.removeClass("selected");


      results[parentObj]=$.grep(results[parentObj], function(value) {

        return value != myClass; /* I used $.grep() to filter the contents of my object. This function remove a class that I previous added (remember that <li> was selected so this class is still in this obj) */

      });

    } else {

      $this.addClass("selected");

      results[parentObj].push(myClass) /* add a class on associative object */

    }

  }

 /* Here I use a EC6 technique to loop through my object => https://zellwk.com/blog/looping-through-js-objects/*/

  var entries = Object.entries(results);


  for (const [key, value] of entries) {

    if (value.length>0)

        /* add ONLY array with classes in it */

      control.push(value);

    else

    /* Here I know that if the array is empty all my child li have no selected class, so I can add "selected" class to the first li (i.e. <li> with data-el='*' as attribute)*/

      $(".nav[data-obj='"+key+"'] li[data-el='*']").addClass("selected");

  }



  /* Set all div in results to opacity:.5*/

  $(".results > div").css({"opacity":".5"});


  if(control.length>0){

    var c=allPossibleCases(control).toString(); /* use that function to find all combinations in control (that it is an array without empty associative objects. I transform it in string to use it as group classes to remove the opacity rule */

    $(c, container).removeAttr("style"); /* remove the opacity:.5 to all group class that I found in control array*/

  } else {

    $(".results > div").removeAttr("style"); /*if control is empty I set the initial state removing the opacity */

  }

});


function allPossibleCases(arr) {

  if (arr.length == 1) {

    return arr[0];

  } else {

    var result = [];

    var allCasesOfRest = allPossibleCases(arr.slice(1));

    for (var i = 0; i < allCasesOfRest.length; i++) {

      for (var j = 0; j < arr[0].length; j++) {

        result.push(arr[0][j] + allCasesOfRest[i]);

      }

    }

    return result;

  }

}

而已。工作中的所有代碼:

var results = {

  series:[],

  body:[],

  style:[]

};


var container=$(".results");


$(".nav li").on('click', function(){

  var $this=$(this);

  var parent=$this.parent();

  var parentObj=$this.parent().data("obj");

  var myClass=$this.data("el");

  var control=[];


  if(myClass==="*") {

    if (!$this.hasClass("selected")) {

      $("li", parent).removeClass("selected");

      $this.addClass("selected");

      results[parentObj]=[];

    }

  } else {

    $("li[data-el='*']", parent).removeClass("selected");


    if ($this.hasClass("selected")) {

      $this.removeClass("selected");


      results[parentObj]=$.grep(results[parentObj], function(value) {

        return value != myClass;

      });

    } else {

      $this.addClass("selected");

      results[parentObj].push(myClass)

    }

  }


  var entries = Object.entries(results);


  for (const [key, value] of entries) {

    if (value.length>0)

      control.push(value);

    else

      $(".nav[data-obj='"+key+"'] li[data-el='*']").addClass("selected");

  }


  $(".results > div").css({"opacity":".5"});


  if(control.length>0){

    var c=allPossibleCases(control).toString();

    $(c, container).removeAttr("style");

  } else {

    $(".results > div").removeAttr("style");

  }

});


function allPossibleCases(arr) {

  if (arr.length == 1) {

    return arr[0];

  } else {

    var result = [];

    var allCasesOfRest = allPossibleCases(arr.slice(1));

    for (var i = 0; i < allCasesOfRest.length; i++) {

      for (var j = 0; j < arr[0].length; j++) {

        result.push(arr[0][j] + allCasesOfRest[i]);

      }

    }

    return result;

  }

}

ul {

  border-bottom: 1px solid black;

  padding-bottom: 10px;

}


li {

  display: inline-block;

}


.selected {

  background-color: red;

}


.results {

  display: flex;

}


.results > div {

  width: 100px;

  height: 100px;

  background: black;

  color: white;

  display: flex;

  justify-content: center;

  align-items: center;

  margin: 10px;

}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<ul class="nav" data-obj="series">

  <li data-el="*" class="selected">All</li>

  <li data-el=".Series-1">Series 1</li>

  <li data-el=".Series-2">Series 2</li>

  <li data-el=".Series-3">Series 3</li>

</ul>


<ul class="nav" data-obj="body">

  <li data-el="*" class="selected">All</li>

  <li data-el=".Body-1">Body 1</li>

  <li data-el=".Body-2">Body 2</li>

  <li data-el=".Body-3">Body 3</li>

</ul>


<ul class="nav" data-obj="style">

  <li data-el="*" class="selected">All</li>

  <li data-el=".Style-1">Style 1</li>

  <li data-el=".Style-2">Style 2</li>

  <li data-el=".Style-3">Style 3</li>

</ul>


<div class="results">

   <div class="Series-1 Body-1 Style-1">Result 1</div>

   <div class="Series-1 Body-1 Style-1">Result 2</div>

   <div class="Series-2 Body-2 Style-2">Result 3</div>

   <div class="Series-2 Body-1 Style-2">Result 4</div>

   <div class="Series-3 Body-1 Style-1">Result 5</div>

   <div class="Series-3 Body-1 Style-1">Result 6</div>

   <div class="Series-3 Body-2 Style-2">Result 7</div>

   <div class="Series-2 Body-1 Style-3">Result 8</div>

</div>


查看完整回答
反對 回復 2022-01-13
  • 1 回答
  • 0 關注
  • 156 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號