对于那里的所有jQuery heros,我需要帮助! (再次)
我在互联网上发现了类似的问题,但到目前为止还没有答案: - /
我想用jquery同位素过滤一堆物品。我从插件主页调整了组合过滤器示例,它工作正常,看起来像这样:
$(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
// i.e. 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:
<div id="nav">
<ul class="filter option-set" data-filter-group="who">
<li><a href="#filter-who-any" data-filter-value="" class="selected">Any</a></li>
<li><a href="#filter-who-boys" data-filter-value=".boys">Boys</a></li>
<li><a href="#filter-who-girls" data-filter-value=".girls">Girls</a></li>
</ul>
</div>
我设置了一个小提琴演示,其中有3个滤镜类别可以合并:jsFiddle
现在我想让从每个类别中选择多个标签:
第1类:OR b或c
和
第2类:OR b或c
和
第3类:OR b或c
desandro有一个check-box-example,但这不是我正在寻找的东西,因为我想在类别之间保持AND条件。基本上我想要3个过滤器类别,每个过滤器类别都有一些复选框(或链接,但我想复选框更实用)。我认为两个示例中使用的方法完全不同,我不知道如何组合它们的功能。
我希望你明白我的观点,任何人都可以帮我找到解决方案。
提前致谢!
使用具有metafizzy同位素过滤的多种过滤器类型需要多维数组来保存每种过滤器类型的数组。
我有一个实例here
例子中的js是here
有关完整的代码说明,请参阅我对this question的回答
看看这里
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});
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;
}
以下是您可以使用多个选择下拉菜单的同位素组合过滤器的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;
}
});
我可以使它工作,但它并不像我在第一个实例中想象的那么简单。我想你需要记住几件事:
关于限制性和非限制性AND子句的这个概念就像外部和内部连接之间的区别。如果你想处理两个过滤器,一个是另一个过滤器的子过滤器,那么你应该使用这个概念。 一个例子就是可以按品牌过滤的电子书列表,另一个基于它们所属的不同范围价格的子过滤器。
我在下面给出了一个代码示例,我实现了这个想法,它可以给你一个我的意思:
HTML:
<!--Filters section -->
<div id="filters">
<ul id="optionSet1" class="option-set" data-option-key="filter">
<li><a id="filter10" href="#filter" class="selected">Everything</a></li>
<c:forEach var="brand" items="${brands}" varStatus="status" >
<li><a id="filter1${status.count}" href="#filter" class='${brand}'>${brand}</a></li>
</c:forEach>
</ul>
<ul id="optionSet2" class="option-set" data-option-key="filter">
<li><a id="filter20" href="#filter" class="selected">Any Price</a> </li>
<c:forEach var="brandPrice" items="${brandPrices}" varStatus="status" >
<li><a id="filter2${status.count}" href="#filter" class='${brandPrice}'>${brandPrice}</a></li>
</c:forEach>
</ul>
</div>
<!--Elements to filter -->
<div id="portfolio-wrapper" class="row">
<c:forEach var="publication" items="${publications}" varStatus="status" >
<div class='span4 portfolio-item ${publication.filterOption1} ${publication.filterOption2} ${publication.filterOption3}...'>
<!-- filterOption3 would be the combination of filterOption1 and filterOption2, you can make this building a string as the addition of filterOption1 and filterOption2 strings-->
<!--Content to display-->
</c:forEach>
</div>
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中的每个类组合起来,等等)
使用过滤功能。它允许任意复杂性,并且可能是所有非平凡案例的正确选择。
最重要的是,使用选择器没有性能优势(如果将选择器直接馈入querySelector
或jQuery调用,您可能会期望这样做)。 Isotope遍历每个项目并将选择器应用为函数,无论如何:
return function( item ) {
return matchesSelector( item.element, filter );
};
因此,您可以将过滤逻辑放入函数中,而不是尝试生成选择器字符串。