您当前的方法不是很动态,选择器和数组都是硬编码的,因此每次添加新的过滤器选项时,您都必须添加代码来处理它。
相反,只需将更改处理程序绑定到所有过滤器复选框,您就可以收集它们的值,并按各自的名称对它们进行分组,例如:
var $filterCheckboxes = $( '.filter-checkboxes' );
$filterCheckboxes.on( 'change', function() {
var selectedFilters = {};
$filterCheckboxes.filter( ':checked' ).each( function() {
if ( ! selectedFilters.hasOwnProperty( this.name ) ) {
selectedFilters[ this.name ] = [];
}
selectedFilters[ this.name ].push( this.value );
} );
} );
这将创建一个包含以下内容的对象input-name -> value array
对,例如:
selectedFilters = {
'fl-colour': [ 'red', 'green' ],
'fl-size': [ 'tiny' ]
};
然后你可以循环每个selectedFilters
,并过滤你的.flower
元素。的一个.flower
元素与每个命名集中的值匹配,我们返回 true,以便该元素包含在$filteredResults
收藏:
// create a collection containing all of the filterable elements
var $filteredResults = $( '.flower' );
// loop over the selected filter name -> (array) values pairs
$.each( selectedFilters, function( name, filterValues ) {
// filter each .flower element
$filteredResults = $filteredResults.filter( function() {
var matched = false,
currentFilterValues = $( this ).data( 'category' ).split( ' ' );
// loop over each category value in the current .flower's data-category
$.each( currentFilterValues, function( _, currentFilterValue ) {
// if the current category exists in the selected filters array
// set matched to true, and stop looping. as we're ORing in each
// set of filters, we only need to match once
if ( $.inArray( currentFilterValue, filterValues) != -1 ) {
matched = true;
return false;
}
} );
// if matched is true the current .flower element is returned
return matched;
} );
} );
然后简单地隐藏所有.flower
元素,并显示$filteredResults
, eg:
$( '.flower' ).hide().filter( $filteredResults ).show();
这是一个小提琴示例