1 回答

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>
添加回答
舉報