同位素:组合过滤+多重选择

对于那里的所有jQuery heros,我需要帮助! (再次)

我在互联网上发现了类似的问题,但到目前为止还没有答案: – /

我想用jquery同位素过滤一堆物品。 我从插件主页调整了组合filter示例,它工作正常,看起来像这样:

$(function () { var $container = $('#container'), filters = {}; $container.isotope({ itemSelector: '.item', filter: '', }); // filter links $('.filter a').click(function () { var $this = $(this); // don't proceed if already selected if ($this.hasClass('selected')) { return; } var $optionSet = $this.parents('.option-set'); // change selected class $optionSet.find('.selected').removeClass('selected'); $this.addClass('selected'); // store filter value in object // ie filters.color = 'red' var group = $optionSet.attr('data-filter-group'); filters[group] = $this.attr('data-filter-value'); // convert object into array var isoFilters = []; for (var prop in filters) { isoFilters.push(filters[prop]) } var selector = isoFilters.join(''); $container.isotope({ filter: selector }); return false; }); }); 

和一些过滤菜单的HTML:

  

我设置了一个小提琴演示,其中有3个滤镜类别可以合并: jsFiddle

现在我想让从每个类别中选择多个标签:

第1类: OR b c

分类2: OR b OR c

分类3: OR b OR c

desandro有一个复选框示例 ,但这不是我正在寻找的东西,因为我想在类别之间保持AND条件。 基本上我想要3个filter类别,每个filter类别都有一些复选框(或链接,但我想复选框更实用)。 我认为两个示例中使用的方法完全不同,我不知道如何组合它们的function。

我希望你明白我的观点,任何人都可以帮我找到解决方案。

提前致谢!

使用具有metafizzy同位素过滤的多种filter类型需要多维数组来保存每种filter类型的数组。

我在这里有一个实例

这个例子的js就在这里

有关完整的代码说明,请参阅我对此问题的回答

看看这里

http://codepen.io/desandro/pen/btFfG

这是DrewT的答案,但来自同位素团队。

为了过滤所需要做的就是将每个组放在同一个对象下

  var filters = {};//sould be outside the scope of the filtering function $a.click(function()//filtering function var group = $optionSet.attr('data-filter-group'); var filterGroup = filters[group]; if (!filterGroup) { filterGroup = filters[group] = []; } filters[ group ].push($this.attr('data-filter-value')); 

现在您所要做的就是调用getComboFilter函数(您不必理解getComboFilter中的代码,将其视为同位素的一部分)

  var comboFilter = getComboFilter( filters ); $container.isotope({ filter: comboFilter}); });//end filtering function function getComboFilter( filters ) { var i = 0; var comboFilters = []; var message = []; for ( var prop in filters ) { message.push( filters[ prop ].join(' ') ); var filterGroup = filters[ prop ]; // skip to next filter group if it doesn't have any values if ( !filterGroup.length ) { continue; } if ( i === 0 ) { // copy to new array comboFilters = filterGroup.slice(0); } else { var filterSelectors = []; // copy to fresh array var groupCombo = comboFilters.slice(0); // [ A, B ] // merge filter Groups for (var k=0, len3 = filterGroup.length; k < len3; k++) { for (var j=0, len2 = groupCombo.length; j < len2; j++) { filterSelectors.push( groupCombo[j] + filterGroup[k] ); // [ 1, 2 ] } } // apply filter selectors to combo filters for next group comboFilters = filterSelectors; } i++; } var comboFilter = comboFilters.join(', '); return comboFilter; } 

以下是您可以使用多个选择下拉菜单的同位素组合filter的JS小提琴代码

 $(document).ready(function(){ // init Isotope var $grid = $('.grid').isotope({ itemSelector: '.item' }); // store filter for each group var filters = {}; $('.filters').on('change', '.filters-select', function(){ var $this = $(this); var filterGroup = $this.attr('data-filter-group'); filters[ filterGroup ] = $this.val(); var filterValue = concatValues( filters ); $grid.isotope({ filter: filterValue }); }); // flatten object by concatting values function concatValues( obj ) { var value = ''; for ( var prop in obj ) { value += obj[ prop ]; } return value; } }); 

https://jsfiddle.net/srikanthLavudia/vhrbqn6p/

我可以使它工作,但它并不像我在第一个实例中所想的那样简单。 我想你需要记住几件事:

  1. 如果您想使用限制性条件,那么我建议不要使用“data-filter-value”选项。 相反,将filter变量作为类 。 然后,您需要在onclick事件中自己激发同位素function。 这是因为否则当用户单击按钮并且您将无法实现限制性AND时,您将触发“默认”同位素function。

  2. 在同一方向上,您将需要为要使用的嵌套filter选项的每个组合使用新的变量名称(因此为新类) 。 否则,我没有看到其他方式(目前)获得限制性条件。

关于限制性和非限制性AND子句的这个概念就像外部和内部连接之间的区别 。 如果你想处理两个filter,一个是另一个filter的子filter,那么你应该使用这个概念。
一个例子就是可以按品牌过滤的电子书列表,另一个基于它们所属的不同范围价格的子filter。

我向您展示了一个代码示例,我实现了这个想法,它可以给你一个我的意思:

HTML:

    

JavaScript的:

 $(function(){ $("a[id^='filter1']").on('click', function() { // alert($(this).attr('class')); // alert($('#optionSet2 .selected').attr('class')); var myclass = $('#optionSet2 .selected').attr('class'); myclass = myclass.replace(' selected',''); myclass = myclass.replace('selected',''); var myclass2 = $(this).attr('class'); myclass2 = myclass2.replace(' selected',''); myclass2 = myclass2.replace('selected',''); if($(myclass=='' && myclass2==''){ $('#portfolio-wrapper').isotope({ filter: '*'}); }else if(myclass==''){ $('#portfolio-wrapper').isotope({ filter: '.'+ myclass2+'' }); }else if(myclass2==''){ $('#portfolio-wrapper').isotope({ filter: '.'+myclass+'' }); }else{ $('#portfolio-wrapper').isotope({ filter: '.'+myclass2+myclass+''}); } }); $("a[id^='filter2']").on('click', function() { // alert($(this).attr('class')); // alert($('#optionSet1 .selected').attr('class')); var myclass = $('#optionSet1 .selected').attr('class'); myclass = myclass.replace(' selected',''); myclass = myclass.replace('selected',''); var myclass2 = $(this).attr('class'); myclass2 = myclass2.replace(' selected',''); myclass2 = myclass2.replace('selected',''); if(myclass=='' && myclass2==''){ $('#portfolio-wrapper').isotope({ filter: '*'}); }else if(myclass==''){ $('#portfolio-wrapper').isotope({ filter: '.'+ myclass2+'' }); }else if(myclass2==''){ $('#portfolio-wrapper').isotope({ filter: '.'+myclass+'' }); }else{ $('#portfolio-wrapper').isotope({ filter: '.'+myclass+myclass2+''}); } }); }); 

很抱歉疏通这个问题,但我最近遇到了同样的问题,并且(imho)浪费了很多时间用组合选择器来解决这个问题。 (将数组A中的每个类与数组B中的每个类组合起来,等等)

使用过滤function。 它允许任意复杂性,并且可能是所有非平凡案例的正确选择。

最重要的是,使用选择器没有性能优势(如果将选择器直接送入querySelector或jQuery调用,您可能会期望这样做)。 Isotope遍历每个项目并将选择器作为函数应用,无论如何:

 return function( item ) { return matchesSelector( item.element, filter ); }; 

因此,您可以将过滤逻辑放入函数中,而不是尝试生成选择器字符串。