2015-12-15 36 views
8

如果有人能爲此考慮更好的標題,請不要猶豫改變它。如果已經在Jquery中過濾,請保持過濾

我對jQuery相當陌生,並遇到過濾元素的問題。

我使用change函數通過checkbox過濾DIVS的data-屬性。

我的問題是,如果我過濾一個data屬性(colour),然後我過濾另一個屬性(brand)元素都是隱藏的。但是如果我取消了其中一個過濾器,即使它們仍被另一個屬性過濾,元素仍會彈出。

無論如何我可以阻止這種情況發生?

這是代碼。

<div data-brand="Nike" data-price="31" data-colour="Blue">Blue</div> 
<div data-brand="Nike" data-price="31" data-colour="Red"> Red </div> 
Colours: 
Blue<input type="checkbox" id="BlueCB" checked> 
Red<input type="checkbox" id="RedCB" checked> 

Brand: Nike <input type="checkbox" id="NikeCB" checked> 

<script> 
    var BlueSelector = $('#BlueCB'); 

    BlueSelector.on("change", function(){ 
     if($(this).is(":checked")) 
     { 
      var divs = $("div[data-colour=Blue]"); 
      divs.css("display", "block"); 
     } else 
     { 
      var divs = $("div[data-colour=Blue]"); 
      divs.css("display", "none"); 
     } 
    }); 

    var RedSelector = $('#RedCB'); 

    RedSelector.on("change", function(){ 
     if($(this).is(":checked")) 
     { 
      var divs = $("div[data-colour=Red]"); 
      divs.css("display", "block"); 
     } else 
     { 
      var divs = $("div[data-colour=Red]"); 
      divs.css("display", "none"); 
     } 
    }); 

    var NikeSelector = $('#NikeCB'); 

    NikeSelector.on("change", function(){ 
     if($(this).is(":checked")) 
     { 
      var divs = $("div[data-colour=Nike]"); 
      divs.css("display", "block"); 
     } else 
     { 
      var divs = $("div[data-brand=Nike]"); 
      divs.css("display", "none"); 
     } 
    }); 
</script> 

要複製問題,請勾選nike複選框,然後取消選中藍色複選框並再次打勾。該元素將彈出,這是問題。

這裏是JSFIDDLE

這可能聽起來並不像最好的解釋,但我是最好的,我可以..你用小提琴演奏後,你就會明白了。

+0

所以,你只希望如果NikeSelector被選中顏色複選框工作? – xkcd149

回答

1

非常晚此外,但有一個暫時忘記小提琴在後臺打開。在被遺忘的小提琴行動小組的一封信後,我決定發佈它。

既然目標似乎是隱藏與選中箱數據,而不是顯示的任何數據屬性被選中的任何數據,你可以創建數據元素應該被隱藏黑名單。 正如在其他的答案中提到還有我的偏好將是把所有的元數據(數據)標籤都有效,如<input type="checkbox" data-type="colour" data-value="Blue" checked>,但不是單獨保存的過濾器,創建一個應該被隱藏的元素的組合過濾器。由於jquery可以輕鬆地選擇元素屬性,因此可以使用jquery功能爲您進行過濾。

的想法是,通過確定這樣的過濾器,任何新的數據的屬性可以被添加(如大小,其餘參加了小提琴加入的自由太)。

var $boxes = $('input[data-type]'), //all input boxes with data-type attribute 
    $dataObjects =$(); //will be filled with all bound data elements 
$boxes.each(function(ind, inp){  //create filter information 
    var type = inp.dataset.type, value = inp.dataset.value; //for older browsers, use $(inp).data('type') 
    var filter = 'div[data-' + type +'="' + value +'"]';  
    inp.dataset.filter = filter; 
    $.merge($dataObjects,$(filter)); 
}); 

$boxes.change(function(){ 
    var blacklist = $boxes.filter(function(i,b){return !b.checked}) 
    .map(function(i,b){return b.dataset.filter}).toArray().join(); 
    $dataObjects.hide().not(blacklist).show(); 
}); 

Fiddle

+0

哇..這是相當真棒!太完美的作品 – SK2017

+0

我怎麼能扭轉這一點,以便所有的元素顯示,即使首先所有複選框都未選中。當你開始滴答滴答時,只顯示勾選的元素? - 我試圖自己編輯它,但當我僅選擇了「藍色」並且沒有其他內容顯示時,它就成爲了一個問題,因爲「耐克」和「中型」也未被選中。 – SK2017

+0

取決於選中的多個複選框應該表現爲「和」還是「或」。對於'或'方法,您可以通過選中複選框來反轉選擇,並使用'filter'而不是'not'來顯示所有符合任何過濾條件的項目:https://jsfiddle.net/z9qbecLx/7 /(在'show ||'中的||''重置過濾器以在沒有框被選中時顯示所有內容)。對於'And',可以使用相同的方法,但是jquery選擇器應該沒有','的連接:https://jsfiddle.net/z9qbecLx/8/ –

0

您可以使用jQuery將data-selected屬性添加到已檢查的項目。我假設這些項目沒有被默認選中。通過在選定的div上使用attr屬性,可以添加這樣一個屬性。爲確保在單擊Nike複選框時僅顯示過濾選擇器,您需要將數據屬性添加到該檢查事件的選擇器中,並將其轉換爲$("div[data-brand=Nike][data-select=true]")。此外,爲簡潔起見,您可以將attr屬性和css屬性鏈接在一起。

https://jsfiddle.net/tfr9zh0w/

var BlueSelector = $('#BlueCB'); 
 

 
BlueSelector.on("change", function(){ 
 
if($(this).is(":checked")) 
 
{ 
 
var divs = $("div[data-colour=Blue]"); 
 
divs.attr('data-select', true).css("display", "block"); 
 
} else 
 
{ 
 
var divs = $("div[data-colour=Blue]"); 
 
divs.removeAttr('data-select').css("display", "none"); 
 
} 
 
}); 
 

 
var RedSelector = $('#RedCB'); 
 

 
RedSelector.on("change", function(){ 
 
if($(this).is(":checked")) 
 
{ 
 
var divs = $("div[data-colour=Red]"); 
 
divs.attr('data-select', true).css("display", "block"); 
 
} else 
 
{ 
 
var divs = $("div[data-colour=Red]"); 
 
divs.removeAttr('data-select').css("display", "none"); 
 
} 
 
}); 
 

 
var NikeSelector = $('#NikeCB'); 
 

 
NikeSelector.on("change", function(){ 
 
if($(this).is(":checked")) 
 
{ 
 
var divs = $("div[data-brand=Nike][data-select=true]"); 
 
divs.css("display", "block"); 
 
} else 
 
{ 
 
var divs = $("div[data-brand=Nike]"); 
 
divs.css("display", "none"); 
 
} 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
 
<div data-brand="Nike" data-price="31" data-colour="Blue"> 
 
Blue </div> 
 
<div data-brand="Nike" data-price="31" data-colour="Red"> 
 
Red </div> 
 
Colours: 
 
Blue<input type="checkbox" id="BlueCB" checked> 
 
Red<input type="checkbox" id="RedCB" checked> 
 

 
Brand: Nike <input type="checkbox" id="NikeCB" checked>

3

以下的代碼的多品牌以及多的顏色,這是由具有分離過濾器陣列,用於品牌和色彩的工作,如果過濾器是檢查我們添加到相應的filters數組,然後最後我們檢查每個div並檢查它是否同時具有品牌和顏色關鍵字,如果兩者都符合我們顯示(*)它,否則我們隱藏(*)它:

JS Fiddle

var Divs = $('.divs'), 
 
    CheckBoxes = $('.chbx'), 
 
    BlueSelector = $('#BlueCB'), 
 
    RedSelector = $('#RedCB'), 
 
    NikeSelector = $('#NikeCB'), 
 
    Index, Colour, Brand; 
 

 

 
CheckBoxes.on("change", function() { 
 
    // Reset filters Arrays 
 
    var ColoursFilters = [], 
 
    BrandsFilters = []; 
 

 
    // If Blue checkbox is checked, add it to colours array - 
 
    // Otherwise it's unchecked, remove it from the colours array 
 
    if (BlueSelector.is(":checked")) { 
 
    ColoursFilters.push('Blue'); 
 
    } else if (BlueSelector.is(":checked") == false) { 
 
    Index = ColoursFilters.indexOf('Blue'); 
 
    ColoursFilters.splice(Index, 'Blue'); 
 
    } 
 

 
    // If Red checkbox is checked, add it to colours array - 
 
    // Otherwise it's unchecked, remove it from the colours array 
 
    if (RedSelector.is(":checked")) { 
 
    ColoursFilters.push('Red'); 
 
    } else if (RedSelector.is(":checked") == false) { 
 
    Index = ColoursFilters.indexOf('Red'); 
 
    ColoursFilters.splice(Index, 'Red'); 
 
    } 
 

 
    // If Nike checkbox is checked, add it to brands array - 
 
    // Otherwise it's unchecked, remove it from the brands array 
 
    if (NikeSelector.is(":checked")) { 
 
    BrandsFilters.push('Nike'); 
 
    } else if (NikeSelector.is(":checked") == false) { 
 
    Index = BrandsFilters.indexOf('Red'); 
 
    BrandsFilters.splice(Index, 'Blue'); 
 
    } 
 

 
    // Now we check for every colour and every brand - 
 
    // If both conditions met, show the div, else hide it. 
 
    Divs.each(function() { 
 
    Colour = $(this).attr('data-colour'); 
 
    Brand = $(this).attr('data-brand'); 
 
    if ($.inArray(Colour, ColoursFilters) > -1) { 
 
     if ($.inArray(Brand, BrandsFilters) > -1) { 
 
     $(this).show(); 
 
     } else { 
 
     $(this).hide(); 
 
     } 
 
    } else { 
 
     $(this).hide(); 
 
    } 
 
    }) 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
 
<div class="divs" data-brand="Nike" data-price="31" data-colour="Blue"> 
 
    Blue</div> 
 
<div class="divs" data-brand="Nike" data-price="31" data-colour="Red"> 
 
    Red</div> 
 
Colours: Blue 
 
<input class="chbx" type="checkbox" id="BlueCB" checked>Red 
 
<input class="chbx" type="checkbox" id="RedCB" checked> 
 
<br>Brand: Nike 
 
<input class="chbx" type="checkbox" id="NikeCB" checked>


編輯1:

如果你要設置的所有複選框默認狀態爲未選中,我們創建了一個功能checkFilters() havin g中的所有邏輯,我們稱之爲頁面首次加載以及每次複選框狀態發生更改時,如此JS Fiddle 2中所示。


編輯2:

的JavaScript代碼仍然有冗餘代碼,這僅僅是3個複選框,假設有10個品牌,你有5種顏色每個品牌則代碼會顯得凌亂並重復了更多錯誤機會,爲使代碼更健壯,更靈活並且更短,我們爲每個複選框添加了data-typedata-keyword屬性,並且根據data-type屬性的值,我們返回相應的數組,並將值的data-keyword屬性放入相應的數組中工作無論有多少顏色或品牌如何檢查框也有,只是想在這個JS Fiddle 3

輸入例

<input class="chbx" type="checkbox" id="BlueCB" data-type="Colours" data-keyword="Blue" checked> Red 

JS:

function checkFilters() { 
    // Reset filters Arrays 
    var ColoursFilters = [], 
    BrandsFilters = []; 

    CheckBoxes.each(function() { 
     var $th = $(this), ArrayType, keyword; 

     // Using ternary operator, we return the array that corresponds to the data-type 
     ArrayType = $th.attr('data-type') == 'Colours' ? ColoursFilters : BrandsFilters; 
     keyword = $th.attr('data-keyword'); 
     if ($th.is(':checked')) { 
      ArrayType.push(keyword); 
     } else if ($th.is(":checked") == false) { 
      Index = ArrayType.indexOf(keyword); 
      ArrayType.splice(Index, keyword); 
     } 
    }); 
    // ... 
} 

*請注意,jQuery .show()大致相當於調用.css("display", "block")「而.hide()大致相當於調用.css("display", "none")

+0

謝謝你一個絕妙的答案。 JSFiddle 3完全是我想要的。 - 我剛剛開始使用你的代碼,儘管我並沒有完全理解它編輯過它。我添加了另一個類型('大小')。你會快速查看我是否做得對嗎? https://jsfiddle.net/60L6pzs8/3/ - 再次感謝。 – SK2017

+0

@丹這是很好做,你需要的一切都是爲了一個「小」'input'添加到HTML,而且你不需要用三元操作線以來已與3階段做了'如果-else'報表,看看這個小提琴https://jsfiddle.net/Mi_Creativity/zhmopvgd/1/其中有評論三元運算符線和添加到HTML –

+0

「小」尺寸過濾此外我認爲你能理解代碼非常好除了「三元運算符」外,基本上這是一個* 2-stage * if-else語句的簡化版本,這個'Z =(conditionX> Y)? A:B'相當於'if(conditionX> Y){Z = A; } else {Z = B; }',有關三元運算符檢查的詳細信息如下:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator –

0

添加到您,如果以確定顏色選擇語句,如果耐克複選框被選中。

如果Nike箱未被選中,我個人將取消選中並禁用顏色複選框。

https://jsfiddle.net/z9qbecLx/4/

var BlueSelector = $('#BlueCB'); 
var RedSelector = $('#RedCB'); 
var NikeSelector = $('#NikeCB'); 

BlueSelector.on("change", function(){ 
    if($(this).is(":checked") && NikeSelector.is(":checked")) 
    { 
     var divs = $("div[data-colour=Blue]"); 
     divs.css("display", "block"); 
    } 
    else 
    { 
     var divs = $("div[data-colour=Blue]"); 
     divs.css("display", "none"); 
    } 
}); 

RedSelector.on("change", function(){ 
    if($(this).is(":checked") && NikeSelector.is(":checked")) 
    { 
     var divs = $("div[data-colour=Red]"); 
     divs.css("display", "block"); 
    } 
    else 
    { 
     var divs = $("div[data-colour=Red]"); 
     divs.css("display", "none"); 
    } 
}); 

NikeSelector.on("change", function(){ 
    if($(this).is(":checked")) 
    { 
    RedSelector.prop('disabled', false); 
    BlueSelector.prop('disabled', false); 
    var divs = $("div[data-colour=Nike]"); 
    divs.css("display", "block"); 
    } 
    else 
    { 
    RedSelector.prop('checked', false).prop('disabled', true); 
    BlueSelector.prop('checked', false).prop('disabled', true); 
    var divs = $("div[data-brand=Nike]"); 
    divs.css("display", "none"); 
    } 
});