Javascript 如何使用jQuery根据多个数据属性筛选列表项?

Javascript 如何使用jQuery根据多个数据属性筛选列表项?,javascript,jquery,html,Javascript,Jquery,Html,以下是我的HTML以及我的所有过滤器: <div class="search-filters"> <div class="filter-block"> <label for="employee_type">Employee Type</label> <select id="employee_type" class="category"> <option value="0">

以下是我的HTML以及我的所有过滤器:

  <div class="search-filters">
    <div class="filter-block">
      <label for="employee_type">Employee Type</label>
      <select id="employee_type" class="category">
        <option value="0">All</option>
        <option value="designer">Designer</option>
        <option value="manager">Manager</option>
        <option value="developer">Developer</option>
        <option value="quality-assurance">Quality Assurance</option>
      </select>
    </div>
    <div class="filter-block">
      <label for="years_xp">Years Experience</label>
      <select id="years_xp" class="category">
        <option value="0">Select years Experience</option>
        <option value="1">1 year</option>
        <option value="2">2 years</option>
        <option value="3">3 years</option>
      </select>
    </div>

  </div>

你知道我做错了什么吗?我已经在这个问题上纠缠了将近6个小时,并且已经看了其他示例,但它们似乎不适用于我的案例。

得到这个结果的原因是
返回true。将此视为中断语句-一旦在
.filter
函数中达到这一点,它就会认为它的工作已经完成,并且可以停止处理。要克服此问题,请使用一些局部布尔值,然后在函数末尾对它们进行求值,以决定是否返回true:

var etMatch = false, xpMatch = false;

if (employee_type != "") {
    if ($(this).attr('data-employee-type') == employee_type) {
        etMatch = true;
    }
}

if (years_xp != "") {
    if ($(this).attr('data-xp') == years_xp) {
        xpMatch = true;
    }
}

if (etMatch && xpMatch) { return true; }

好的,您希望同时应用两个过滤器,而不是在单个过滤器匹配时立即显示一个项目。在筛选函数中,一旦找到匹配项,就会返回true,这就是问题所在

我继续更新了您的代码:

$('.category').on('change', function() {
  var category_filters = [];

  $('.search-filters select').each(function() {
    if ($(this).val() != 0) {
      category_filters[$(this).attr('id')] = $(this).val();
    }
  });

  $(".result-set .result").hide().filter(function() { 
    var show = true;
    for (var category in category_filters) {
       show = show && $(this).data(category) == category_filters[category];
    }

    return show;
  }).show();

});
还有一个演示:

你会注意到,我也做了一些重构。此代码假定筛选器的
id
与要应用筛选器的数据属性的名称完全匹配,因此请确保检查更新的HTML

javascript的重复性要小得多,您可以根据需要添加任意多的附加过滤器和匹配的数据属性,这些过滤器和属性无需更改javascript即可工作

至于filter函数,让我添加一些注释来解释

// assume we'll want to show the item
var show = true;
// go over each active filter
for (var category in category_filters) {
   // check if the filter value matches the data attribute value, and any
   // previous filters did not exclude this item yet (show &&)
   show = show && $(this).data(category) == category_filters[category];
}

return show;

对于每个过滤器,应使用其功能进行比较:

var compare = {
  "employee-type": function(a,b) { return a===b},
  "years-xp": function(a,b) { return (1*a)<=(1*b) }
}

$(".result-set .result").show().filter(function() {

  var self = this;

  return 
    !Object
     .keys(category_filters)
     .reduce( function(result, i) {

       var filterValue = category_filters[i];
       var itemValue = $(self).attr('data-'+i);

       return result && compare[ i ]( filterValue, itemValue)

     }, true)

}).hide();
var比较={
“员工类型”:函数(a,b){返回a==b},

“years xp”:函数(a,b){return(1*a)
if('employee\u type'在category\u filters中)
这并不像你想象的那样。例如:
在[]
返回trues似乎工作正常,无论是过滤器与
条件相结合。您希望它是
?@StephenBugsKamenar当我执行控制台时。登录if语句中的'employee_type'变量,我从下拉列表中获取当前返回值,并分配正确的键值对在数组“category_filters”中。因此该部分应该可以工作。@Pevara是的,我希望它是一个AND。非常感谢,这对数据属性和select id的不匹配有很大帮助。我完全忽略了这一点。
// assume we'll want to show the item
var show = true;
// go over each active filter
for (var category in category_filters) {
   // check if the filter value matches the data attribute value, and any
   // previous filters did not exclude this item yet (show &&)
   show = show && $(this).data(category) == category_filters[category];
}

return show;
var compare = {
  "employee-type": function(a,b) { return a===b},
  "years-xp": function(a,b) { return (1*a)<=(1*b) }
}

$(".result-set .result").show().filter(function() {

  var self = this;

  return 
    !Object
     .keys(category_filters)
     .reduce( function(result, i) {

       var filterValue = category_filters[i];
       var itemValue = $(self).attr('data-'+i);

       return result && compare[ i ]( filterValue, itemValue)

     }, true)

}).hide();